diff --git a/assets/manifest.json b/assets/manifest.json index e5bfc6b..9209201 100644 --- a/assets/manifest.json +++ b/assets/manifest.json @@ -2,7 +2,7 @@ { "manifest_version": 2, "name": "develinky", - "description": "This is web clipper for devlink website", + "description": "This is web clipper for devlinky website", "version": "1.0.0", "icons": { "128": "icon.png" diff --git a/jest.config.js b/jest.config.js index 2e20e43..4949d54 100644 --- a/jest.config.js +++ b/jest.config.js @@ -12,6 +12,6 @@ module.exports = { statements: 100, }, }, - modulePathIgnorePatterns: ['./src/services/api'], - coveragePathIgnorePatterns: ['./src/services/api'], + modulePathIgnorePatterns: ['./src/services/api', './src/services/chrome'], + coveragePathIgnorePatterns: ['./src/services/api', './src/services/chrome'], }; diff --git a/src/pages/MainPage.jsx b/src/pages/MainPage.jsx index 317c1df..46fe6fd 100644 --- a/src/pages/MainPage.jsx +++ b/src/pages/MainPage.jsx @@ -1,4 +1,3 @@ -/* global chrome */ import React from 'react'; import { @@ -9,7 +8,7 @@ import { useDispatch, useSelector } from 'react-redux'; import useCurrentUser from '../hooks/useCurrentUser'; -import { setUrl, fetchPreview } from '../redux/slice'; +import { setUrl, fetchPreview, loadUrl } from '../redux/slice'; import { isEmpty, get } from '../utils'; @@ -27,15 +26,7 @@ export default function MainPage() { const url = useSelector(get('url')); if (!url) { - if (process.env.NODE_ENV !== 'production') { - setTimeout(() => { // 테스트용 코드 - dispatch(setUrl('https://jeonghwan-kim.github.io/series/2019/12/10/frontend-dev-env-webpack-basic.html')); - }, 1000); - } else { - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - dispatch(setUrl(tabs[0].url)); - }); - } + dispatch(loadUrl()); } const preview = useSelector(get('preview')); @@ -49,7 +40,7 @@ export default function MainPage() { }; const handleClick = () => { - + dispatch(fetchPreview()); }; return ( @@ -80,7 +71,9 @@ export default function MainPage() { value={url || ''} onChange={handleChange} /> - + <>

preview

diff --git a/src/pages/MainPage.test.jsx b/src/pages/MainPage.test.jsx index 6564335..689b35f 100644 --- a/src/pages/MainPage.test.jsx +++ b/src/pages/MainPage.test.jsx @@ -226,4 +226,29 @@ describe('', () => { expect(dispatch).toBeCalledWith(setUrl(newUrl)); }); }); + + context('when search button is clicked', () => { + const dispatch = jest.fn(); + + beforeEach(() => { + useCurrentUser.mockImplementation(() => ({ + currentUser, + })); + + useDispatch.mockImplementation(() => dispatch); + + useSelector.mockImplementation((selector) => selector({ + url: devlink.url, + preview, + })); + }); + + it('change dispatch', () => { + const { getByLabelText } = render(); + + fireEvent.click(getByLabelText('search-url')); + + expect(dispatch).toBeCalledTimes(1); + }); + }); }); diff --git a/src/redux/asyncActions.test.js b/src/redux/asyncActions.test.js index 4e2ebc1..034c40c 100644 --- a/src/redux/asyncActions.test.js +++ b/src/redux/asyncActions.test.js @@ -2,15 +2,19 @@ import { getDefaultMiddleware } from '@reduxjs/toolkit'; import configureStore from 'redux-mock-store'; -import { fetchPreview, setPreview } from './slice'; +import { + fetchPreview, setPreview, loadUrl, setUrl, +} from './slice'; import { fetchUrlMetaData } from '../services/api'; +import { fetchUrl } from '../services/chrome'; import { preview } from '../../fixtures'; const mockStore = configureStore(getDefaultMiddleware()); jest.mock('../services/api'); +jest.mock('../services/chrome'); describe('actions', () => { let store; @@ -32,4 +36,22 @@ describe('actions', () => { expect(actions[0]).toEqual(setPreview(preview)); }); }); + + describe('loadUrl', () => { + beforeEach(() => { + store = mockStore({ + url: null, + }); + + fetchUrl.mockImplementation((callback) => callback(preview.url)); + }); + + it('runs setUrl', async () => { + await store.dispatch(loadUrl()); + + const actions = store.getActions(); + + expect(actions[0]).toStrictEqual(setUrl(preview.url)); + }); + }); }); diff --git a/src/redux/slice.js b/src/redux/slice.js index 680b6bc..0bdfd19 100644 --- a/src/redux/slice.js +++ b/src/redux/slice.js @@ -1,6 +1,7 @@ import { createSlice } from '@reduxjs/toolkit'; import { fetchUrlMetaData } from '../services/api'; +import { fetchUrl } from '../services/chrome'; const { actions, reducer } = createSlice({ name: 'devlinky#', @@ -37,6 +38,10 @@ export const { setPreview, } = actions; +export const loadUrl = () => (dispatch) => { + fetchUrl((data) => dispatch(setUrl(data))); +}; + export const fetchPreview = () => async (dispatch, getState) => { const { url } = getState(); diff --git a/src/services/chrome/__mocks__/chrome.js b/src/services/chrome/__mocks__/chrome.js new file mode 100644 index 0000000..819efb7 --- /dev/null +++ b/src/services/chrome/__mocks__/chrome.js @@ -0,0 +1,3 @@ +export const fetchUrl = jest.fn(); + +export const temp = jest.fn(); diff --git a/src/services/chrome/index.js b/src/services/chrome/index.js new file mode 100644 index 0000000..dc524db --- /dev/null +++ b/src/services/chrome/index.js @@ -0,0 +1,15 @@ +/* global chrome */ +export const fetchUrl = (callback) => { + if (process.env.NODE_ENV === 'production') { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + callback(tabs[0].url); + }); + } else { + const currentTabUrl = 'https://jeonghwan-kim.github.io/series/2019/12/10/frontend-dev-env-webpack-basic.html'; + setTimeout(() => { + callback(currentTabUrl); + }, 1000); + } +}; + +export const temp = () => {}; diff --git a/webpack.config.js b/webpack.config.js index af2a31c..0c9cd2f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -46,6 +46,7 @@ module.exports = (env, argv) => ({ { from: './assets/manifest.json', to: './manifest.json' }, { from: './assets/icon.png', to: './icon.png' }, { from: './assets/images/logo-small.png', to: './assets/images/logo-small.png' }, + { from: './assets/images/preview_default.png', to: './assets/images/preview_default.png' }, ], }), ],