From e623f0694985c429cc47a161228b1bd1e9e0a7eb Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Fri, 12 Apr 2024 03:27:53 +0530 Subject: [PATCH 1/5] code refator --- App.js | 4 +- .../molecules/CharacterWithQuote/index.js | 4 +- app/components/molecules/If/index.js | 23 ++++++----- .../molecules/If/tests/index.test.js | 4 +- .../organisms/SimpsonsLoveWednesday/index.js | 4 +- .../SimpsonsLoveWednesday/tests/index.test.js | 4 +- app/i18n.js | 16 +++++--- app/utils/apiUtils.js | 40 +++++++++++++------ app/utils/createStore.js | 10 ++--- app/utils/testUtils.js | 3 +- babel.config.js | 2 +- setupTests.js | 4 +- 12 files changed, 68 insertions(+), 50 deletions(-) diff --git a/App.js b/App.js index 426ce63..fc85faa 100644 --- a/App.js +++ b/App.js @@ -12,9 +12,7 @@ if (!window.Intl) { }) .then(() => Promise.all([import('intl/locale-data/jsonp/en.js')])) .then(() => AppRegistry.registerComponent(appName, () => App)) - .catch(err => { - throw err; - }); + .catch(alert); } else { AppRegistry.registerComponent(appName, () => App); } diff --git a/app/components/molecules/CharacterWithQuote/index.js b/app/components/molecules/CharacterWithQuote/index.js index 3ccb5a7..c5c6ed6 100644 --- a/app/components/molecules/CharacterWithQuote/index.js +++ b/app/components/molecules/CharacterWithQuote/index.js @@ -1,6 +1,6 @@ import React from 'react'; import styled from 'styled-components/native'; -import { get } from 'lodash'; +import get from 'lodash/get'; import PropTypes from 'prop-types'; import { fonts } from '@themes'; import T from '@atoms/T'; @@ -23,7 +23,7 @@ function CharacterWithQuote({ user }) { diff --git a/app/components/molecules/If/index.js b/app/components/molecules/If/index.js index eb4c77b..0d2cab4 100644 --- a/app/components/molecules/If/index.js +++ b/app/components/molecules/If/index.js @@ -4,21 +4,24 @@ * */ // eslint-disable-next-line -import React from 'react' -import Proptypes from 'prop-types'; +import PropTypes from 'prop-types'; + const If = props => (props.condition ? props.children : props.otherwise); -If.propsTypes = { - condition: Proptypes.bool, - otherwise: Proptypes.oneOfType([ - Proptypes.arrayOf(Proptypes.node), - Proptypes.node + +If.propTypes = { + condition: PropTypes.bool, + otherwise: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node ]), - children: Proptypes.oneOfType([ - Proptypes.arrayOf(Proptypes.node), - Proptypes.node + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node ]) }; + If.defaultProps = { otherwise: null }; + export default If; diff --git a/app/components/molecules/If/tests/index.test.js b/app/components/molecules/If/tests/index.test.js index 52e0090..983d5c5 100644 --- a/app/components/molecules/If/tests/index.test.js +++ b/app/components/molecules/If/tests/index.test.js @@ -9,7 +9,7 @@ import React from 'react'; import { Text } from 'react-native'; import { render } from '@testing-library/react-native'; - +import set from 'lodash/set'; import If from '../index'; describe('', () => { @@ -32,7 +32,7 @@ describe('', () => { ); expect(getByText(conditionTrueText)).toBeTruthy(); - props.condition = false; + set(props, 'condition', false); const { getByText: textQueryOnReRender } = render( diff --git a/app/components/organisms/SimpsonsLoveWednesday/index.js b/app/components/organisms/SimpsonsLoveWednesday/index.js index ffb6c5a..aa4fbcc 100644 --- a/app/components/organisms/SimpsonsLoveWednesday/index.js +++ b/app/components/organisms/SimpsonsLoveWednesday/index.js @@ -6,7 +6,7 @@ import If from '@molecules/If'; import CharacterWithQuote from '@molecules/CharacterWithQuote'; import LogoWithInstructions from '@molecules/LogoWithInstructions'; -const Error = styled.Text` +const Err = styled.Text` ${fonts.style.standard()}; text-align: center; margin-bottom: 5px; @@ -25,7 +25,7 @@ function SimpsonsLoveWednesday({ instructions, user, userErrorMessage }) { {userErrorMessage}} + otherwise={{userErrorMessage}} > diff --git a/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js b/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js index 9978c9c..7142fb0 100644 --- a/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js +++ b/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js @@ -9,8 +9,8 @@ import React from 'react'; import { renderWithIntl } from '@utils/testUtils'; import { rerender } from '@testing-library/react-native'; +import set from 'lodash/set'; import SimpsonsLoveWednesday from '../index'; - describe('', () => { it('Should render and match the snapshot', () => { const baseElement = renderWithIntl(); @@ -29,7 +29,7 @@ describe('', () => { }; const { getByText } = renderWithIntl(); expect(getByText(props.userErrorMessage)).toBeTruthy(); - props.userErrorMessage = null; + set(props, 'userErrorMessage', null); const { getByText: textQueryOnReRender } = renderWithIntl( , rerender diff --git a/app/i18n.js b/app/i18n.js index 87c780f..6e375c1 100644 --- a/app/i18n.js +++ b/app/i18n.js @@ -7,12 +7,12 @@ * script `extract-intl`, and must use CommonJS module syntax * You CANNOT use import/export in this file. */ +import get from 'lodash/get'; const addLocaleData = require('react-intl').addLocaleData; //eslint-disable-line const enLocaleData = require('react-intl/locale-data/en'); const enTranslationMessages = require('./translations/en.json'); - addLocaleData(enLocaleData); export const DEFAULT_LOCALE = 'en'; @@ -28,11 +28,15 @@ export const formatTranslationMessages = (locale, messages) => { ? formatTranslationMessages(DEFAULT_LOCALE, enTranslationMessages) : {}; const flattenFormattedMessages = (formattedMessages, key) => { - const formattedMessage = - !messages[key] && locale !== DEFAULT_LOCALE - ? defaultFormattedMessages[key] - : messages[key]; - return Object.assign(formattedMessages, { [key]: formattedMessage }); + const formattedMessageOptions = { + true: get(defaultFormattedMessages, key), + false: get(messages, key) + }; + const formattedCondition = !get(messages, key) && locale !== DEFAULT_LOCALE; + return { + ...formattedMessages, + [key]: get(formattedMessageOptions, formattedCondition) + }; }; return Object.keys(messages).reduce(flattenFormattedMessages, {}); }; diff --git a/app/utils/apiUtils.js b/app/utils/apiUtils.js index 433a357..b958ae3 100644 --- a/app/utils/apiUtils.js +++ b/app/utils/apiUtils.js @@ -1,22 +1,28 @@ import { create } from 'apisauce'; import mapKeysDeep from 'map-keys-deep'; -import { camelCase, snakeCase } from 'lodash'; +import camelCase from 'lodash/camelCase'; +import snakeCase from 'lodash/snakeCase'; +import set from 'lodash/set'; +import get from 'lodash/get'; import { Config } from '@app/config/index'; - export const apiClients = { configApi: null, default: null }; -export const getApiClient = (type = 'configApi') => apiClients[type]; +export const getApiClient = (type = 'configApi') => get(apiClients, type); export const generateApiClient = (type = 'configApi') => { - switch (type) { - case 'configApi': - apiClients[type] = createApiClientWithTransForm(Config.API_URL); - return apiClients[type]; - default: - apiClients.default = createApiClientWithTransForm(Config.API_URL); + const apiClientOption = { + configApi: () => { + set(apiClients, type, createApiClientWithTransForm(Config.API_URL)); + return get(apiClients, type); + }, + default: () => { + set(apiClients, 'default', createApiClientWithTransForm(Config.API_URL)); return apiClients.default; - } + } + }; + const clientGenerator = get(apiClientOption, type, apiClientOption.default); + return clientGenerator(); }; export const createApiClientWithTransForm = baseURL => { @@ -24,10 +30,16 @@ export const createApiClientWithTransForm = baseURL => { baseURL, headers: { 'Content-Type': 'application/json' } }); + + // eslint-disable-next-line complexity api.addResponseTransform(response => { const { ok, data } = response; if (ok && data) { - response.data = mapKeysDeep(data, keys => camelCase(keys)); + set( + response, + 'data', + mapKeysDeep(data, keys => camelCase(keys)) + ); } return response; }); @@ -35,7 +47,11 @@ export const createApiClientWithTransForm = baseURL => { api.addRequestTransform(request => { const { data } = request; if (data) { - request.data = mapKeysDeep(data, keys => snakeCase(keys)); + set( + request, + 'data', + mapKeysDeep(data, keys => snakeCase(keys)) + ); } return request; }); diff --git a/app/utils/createStore.js b/app/utils/createStore.js index ce230ca..fd5287a 100644 --- a/app/utils/createStore.js +++ b/app/utils/createStore.js @@ -26,14 +26,10 @@ const persistConfig = { }; export default (rootReducer, rootSaga) => { - const middleware = []; - const enhancers = []; - - // Connect the sagas to the redux store + // connect sagas to redux store const sagaMiddleware = createSagaMiddleware(); - middleware.push(sagaMiddleware); - - enhancers.push(applyMiddleware(...middleware)); + const middleware = [sagaMiddleware]; + const enhancers = [applyMiddleware(...middleware)]; // Redux persist const persistedReducer = persistReducer(persistConfig, rootReducer); diff --git a/app/utils/testUtils.js b/app/utils/testUtils.js index 86a7656..bad8004 100644 --- a/app/utils/testUtils.js +++ b/app/utils/testUtils.js @@ -3,6 +3,7 @@ import { IntlProvider } from 'react-intl'; import { render } from '@testing-library/react-native'; import { Provider } from 'react-redux'; import createStore from 'app/rootReducer'; +import get from 'lodash/get'; import { DEFAULT_LOCALE, translationMessages } from '@app/i18n'; import ConnectedLanguageProvider from '@atoms/LanguageProvider'; @@ -14,7 +15,7 @@ export const renderWithIntl = (children, renderFunction = render) => renderFunction( {children} diff --git a/babel.config.js b/babel.config.js index 88d868c..f4146e1 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,4 +1,4 @@ -module.exports = function(api = { cache: () => {} }) { +module.exports = (api = { cache: () => {} }) => { api.cache(true); return { presets: ['babel-preset-expo'], diff --git a/setupTests.js b/setupTests.js index 58d906e..34d761d 100644 --- a/setupTests.js +++ b/setupTests.js @@ -1,4 +1,4 @@ import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock'; - +import { LogBox } from 'react-native'; jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage); -console.disableYellowBox = true; +LogBox.ignoreAllLogs(); From 78270e4748a61240ef99647b52e9a205dea81617 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Fri, 12 Apr 2024 11:38:23 +0530 Subject: [PATCH 2/5] removed eslint disbalee comment --- app/components/molecules/If/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/components/molecules/If/index.js b/app/components/molecules/If/index.js index 0d2cab4..551e325 100644 --- a/app/components/molecules/If/index.js +++ b/app/components/molecules/If/index.js @@ -3,7 +3,6 @@ * If * */ -// eslint-disable-next-line import PropTypes from 'prop-types'; const If = props => (props.condition ? props.children : props.otherwise); From 11be2544b29aaa8ff826b2d92bd8eb9208e803db Mon Sep 17 00:00:00 2001 From: Mac Date: Fri, 12 Apr 2024 16:38:48 +0530 Subject: [PATCH 3/5] fix: split if tests into 2 --- .../{molecules => atoms}/If/index.js | 0 .../If/tests/__snapshots__/index.test.js.snap | 0 .../If/tests/index.test.js | 27 ++++++++++++++----- .../organisms/SimpsonsLoveWednesday/index.js | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) rename app/components/{molecules => atoms}/If/index.js (100%) rename app/components/{molecules => atoms}/If/tests/__snapshots__/index.test.js.snap (100%) rename app/components/{molecules => atoms}/If/tests/index.test.js (51%) diff --git a/app/components/molecules/If/index.js b/app/components/atoms/If/index.js similarity index 100% rename from app/components/molecules/If/index.js rename to app/components/atoms/If/index.js diff --git a/app/components/molecules/If/tests/__snapshots__/index.test.js.snap b/app/components/atoms/If/tests/__snapshots__/index.test.js.snap similarity index 100% rename from app/components/molecules/If/tests/__snapshots__/index.test.js.snap rename to app/components/atoms/If/tests/__snapshots__/index.test.js.snap diff --git a/app/components/molecules/If/tests/index.test.js b/app/components/atoms/If/tests/index.test.js similarity index 51% rename from app/components/molecules/If/tests/index.test.js rename to app/components/atoms/If/tests/index.test.js index 983d5c5..387c410 100644 --- a/app/components/molecules/If/tests/index.test.js +++ b/app/components/atoms/If/tests/index.test.js @@ -9,7 +9,6 @@ import React from 'react'; import { Text } from 'react-native'; import { render } from '@testing-library/react-native'; -import set from 'lodash/set'; import If from '../index'; describe('', () => { @@ -17,8 +16,9 @@ describe('', () => { const baseElement = render(); expect(baseElement).toMatchSnapshot(); }); - it('Should render the correct prop component based on the condition', () => { - const conditionTrueText = 'Shoudld render when condition is true'; + + it('If should render the child component when props.condition = true', () => { + const conditionTrueText = 'Should render when condition is true'; const conditionFalseText = 'Should render condition is false'; const OtherwiseComponent = () => {conditionFalseText}; const TrueConditionComponent = () => {conditionTrueText}; @@ -26,18 +26,31 @@ describe('', () => { otherwise: , condition: true }; - const { getByText } = render( + const { queryByText, getByText } = render( ); expect(getByText(conditionTrueText)).toBeTruthy(); - set(props, 'condition', false); - const { getByText: textQueryOnReRender } = render( + expect(queryByText(conditionFalseText)).not.toBeTruthy(); + }); + + it('If should render the component passed on otherwise when props.condition = false', () => { + const conditionFalseText = 'Should render condition is false'; + const conditionTrueText = 'Should render when condition is true'; + const TrueConditionComponent = () => {conditionTrueText}; + const OtherwiseComponent = () => {conditionFalseText}; + const props = { + otherwise: , + condition: false + }; + + const { queryByText, getByText } = render( ); - expect(textQueryOnReRender(conditionFalseText)).toBeTruthy(); + expect(getByText(conditionFalseText)).toBeTruthy(); + expect(queryByText(conditionTrueText)).not.toBeTruthy(); }); }); diff --git a/app/components/organisms/SimpsonsLoveWednesday/index.js b/app/components/organisms/SimpsonsLoveWednesday/index.js index aa4fbcc..1affdb3 100644 --- a/app/components/organisms/SimpsonsLoveWednesday/index.js +++ b/app/components/organisms/SimpsonsLoveWednesday/index.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components/native'; import { fonts } from '@themes'; -import If from '@molecules/If'; +import If from '@app/components/atoms/If'; import CharacterWithQuote from '@molecules/CharacterWithQuote'; import LogoWithInstructions from '@molecules/LogoWithInstructions'; From 6ab05e02bbe7beace086a686b406661d18640b31 Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 15 Apr 2024 12:36:15 +0530 Subject: [PATCH 4/5] feat: Code Refactor --- .../SimpsonsLoveWednesday/tests/index.test.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js b/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js index 7142fb0..0be176e 100644 --- a/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js +++ b/app/components/organisms/SimpsonsLoveWednesday/tests/index.test.js @@ -9,7 +9,6 @@ import React from 'react'; import { renderWithIntl } from '@utils/testUtils'; import { rerender } from '@testing-library/react-native'; -import set from 'lodash/set'; import SimpsonsLoveWednesday from '../index'; describe('', () => { it('Should render and match the snapshot', () => { @@ -29,7 +28,18 @@ describe('', () => { }; const { getByText } = renderWithIntl(); expect(getByText(props.userErrorMessage)).toBeTruthy(); - set(props, 'userErrorMessage', null); + }); + it('Should render the component if userErrorMessage is empty', () => { + const props = { + userErrorMessage: null, + instructions: 'PRESS CMD + D for iOS', + user: { + character: 'Homer', + image: + 'https://www.onthisday.com/images/people/homer-simpson-medium.jpg', + quote: "D'Oh!" + } + }; const { getByText: textQueryOnReRender } = renderWithIntl( , rerender From 46ca7223b8c2eb3f1f695b26ba8a592d088d586d Mon Sep 17 00:00:00 2001 From: HIMANSHU Date: Mon, 15 Apr 2024 13:57:33 +0530 Subject: [PATCH 5/5] feat: code refactor --- app/utils/apiUtils.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/app/utils/apiUtils.js b/app/utils/apiUtils.js index b958ae3..713aef2 100644 --- a/app/utils/apiUtils.js +++ b/app/utils/apiUtils.js @@ -5,24 +5,21 @@ import snakeCase from 'lodash/snakeCase'; import set from 'lodash/set'; import get from 'lodash/get'; import { Config } from '@app/config/index'; + export const apiClients = { configApi: null, default: null }; -export const getApiClient = (type = 'configApi') => get(apiClients, type); +export const getApiClient = (type = 'configApi') => apiClients[type]; export const generateApiClient = (type = 'configApi') => { - const apiClientOption = { - configApi: () => { + switch (type) { + case 'configApi': set(apiClients, type, createApiClientWithTransForm(Config.API_URL)); return get(apiClients, type); - }, - default: () => { + default: set(apiClients, 'default', createApiClientWithTransForm(Config.API_URL)); return apiClients.default; - } - }; - const clientGenerator = get(apiClientOption, type, apiClientOption.default); - return clientGenerator(); + } }; export const createApiClientWithTransForm = baseURL => { @@ -30,8 +27,6 @@ export const createApiClientWithTransForm = baseURL => { baseURL, headers: { 'Content-Type': 'application/json' } }); - - // eslint-disable-next-line complexity api.addResponseTransform(response => { const { ok, data } = response; if (ok && data) {