From 58f24eb5a4b5c5cec621c6d4e81f256e1fac2d08 Mon Sep 17 00:00:00 2001 From: Anas WS Date: Wed, 6 Mar 2024 16:05:57 +0530 Subject: [PATCH 1/2] TrackDetailProvider added --- app/containers/TrackDetailContainer/index.js | 10 +++++----- .../TrackDetailContainer/tests/index.test.js | 4 ++-- .../reducer.js | 12 ++++++------ .../saga.js | 8 ++++---- .../selectors.js | 8 ++++---- .../tests/reducer.test.js | 16 ++++++++-------- .../tests/saga.test.js | 14 ++++++-------- .../tests/selectors.test.js | 4 ++-- app/createRootReducer.js | 4 ++-- 9 files changed, 39 insertions(+), 41 deletions(-) rename app/containers/{TrackDetailContainer => TrackDetailProvider}/reducer.js (66%) rename app/containers/{TrackDetailContainer => TrackDetailProvider}/saga.js (69%) rename app/containers/{TrackDetailContainer => TrackDetailProvider}/selectors.js (50%) rename app/containers/{TrackDetailContainer => TrackDetailProvider}/tests/reducer.test.js (70%) rename app/containers/{TrackDetailContainer => TrackDetailProvider}/tests/saga.test.js (77%) rename app/containers/{TrackDetailContainer => TrackDetailProvider}/tests/selectors.test.js (92%) diff --git a/app/containers/TrackDetailContainer/index.js b/app/containers/TrackDetailContainer/index.js index cf9273c..df33296 100644 --- a/app/containers/TrackDetailContainer/index.js +++ b/app/containers/TrackDetailContainer/index.js @@ -6,16 +6,16 @@ import { compose } from 'redux'; import { useParams } from 'react-router-dom'; import isEmpty from 'lodash/isEmpty'; import styled from '@emotion/styled'; -import { trackDetailContainerCreators } from './reducer'; import { injectSaga } from 'redux-injectors'; import { Card, CardHeader, Container, Divider, Skeleton } from '@mui/material'; import TrackCard from '@components/TrackCard'; import If from '@components/If'; import T from '@components/T'; import get from 'lodash/get'; -import trackDetailContainerSaga from './saga'; -import { selectTrackDetailData, selectTrackError, selectTrackDetailLoading } from './selectors'; import { translate } from '@app/utils/index'; +import trackDetailSaga from '../TrackDetailProvider/saga'; +import { selectTrackDetailData, selectTrackError, selectTrackDetailLoading } from '../TrackDetailProvider/selectors'; +import { trackDetailCreators } from '../TrackDetailProvider/reducer'; // Custom Styling const CustomCard = styled(Card)` @@ -125,7 +125,7 @@ const mapStateToProps = createStructuredSelector({ }); export function mapDispatchToProps(dispatch) { - const { requestGetTrackDetail } = trackDetailContainerCreators; + const { requestGetTrackDetail } = trackDetailCreators; return { dispatchTrackDetail: (trackId) => dispatch(requestGetTrackDetail(trackId)) }; @@ -136,7 +136,7 @@ const withConnect = connect(mapStateToProps, mapDispatchToProps); export default compose( withConnect, memo, - injectSaga({ key: 'trackDetailContainer', saga: trackDetailContainerSaga }) + injectSaga({ key: 'trackDetailContainer', saga: trackDetailSaga }) )(TrackDetailContainer); export const TrackDetailContainerTest = compose()(TrackDetailContainer); diff --git a/app/containers/TrackDetailContainer/tests/index.test.js b/app/containers/TrackDetailContainer/tests/index.test.js index 4349e8f..2849760 100644 --- a/app/containers/TrackDetailContainer/tests/index.test.js +++ b/app/containers/TrackDetailContainer/tests/index.test.js @@ -7,8 +7,8 @@ import React from 'react'; import { renderProvider } from '@utils/testUtils'; import { TrackDetailContainerTest as TrackDetailContainer, mapDispatchToProps } from '../index'; -import { trackDetailContainerTypes } from '../reducer'; import { translate } from '@app/utils/index'; +import { trackDetailTypes } from '@app/containers/TrackDetailProvider/reducer'; describe(' tests', () => { let submitSpy; @@ -25,7 +25,7 @@ describe(' tests', () => { const dispatchTracksSearchSpy = jest.fn(); const trackId = 12323; const actions = { - dispatchTrackDetail: { trackId, type: trackDetailContainerTypes.REQUEST_GET_TRACK_DETAIL } + dispatchTrackDetail: { trackId, type: trackDetailTypes.REQUEST_GET_TRACK_DETAIL } }; const props = mapDispatchToProps(dispatchTracksSearchSpy); diff --git a/app/containers/TrackDetailContainer/reducer.js b/app/containers/TrackDetailProvider/reducer.js similarity index 66% rename from app/containers/TrackDetailContainer/reducer.js rename to app/containers/TrackDetailProvider/reducer.js index 4de26ce..a84edcf 100644 --- a/app/containers/TrackDetailContainer/reducer.js +++ b/app/containers/TrackDetailProvider/reducer.js @@ -7,7 +7,7 @@ import produce from 'immer'; import { createActions } from 'reduxsauce'; import get from 'lodash/get'; -export const { Types: trackDetailContainerTypes, Creators: trackDetailContainerCreators } = createActions({ +export const { Types: trackDetailTypes, Creators: trackDetailCreators } = createActions({ requestGetTrackDetail: ['trackId'], successGetTrackDetail: ['data'], failureGetTrackDetail: ['error'] @@ -15,22 +15,22 @@ export const { Types: trackDetailContainerTypes, Creators: trackDetailContainerC export const initialState = { trackId: null, trackDetailData: {}, trackError: null, trackDetailLoading: false }; /* eslint-disable default-case, no-param-reassign */ -export const trackDetailContainerReducer = (state = initialState, action) => +export const trackDetailReducer = (state = initialState, action) => produce(state, (draft) => { switch (action.type) { - case trackDetailContainerTypes.REQUEST_GET_TRACK_DETAIL: + case trackDetailTypes.REQUEST_GET_TRACK_DETAIL: draft.trackId = action.trackId; draft.trackDetailLoading = true; break; - case trackDetailContainerTypes.SUCCESS_GET_TRACK_DETAIL: + case trackDetailTypes.SUCCESS_GET_TRACK_DETAIL: draft.trackDetailData = action.data; draft.trackDetailLoading = false; break; - case trackDetailContainerTypes.FAILURE_GET_TRACK_DETAIL: + case trackDetailTypes.FAILURE_GET_TRACK_DETAIL: draft.trackError = get(action.error, 'message', 'something_went_wrong'); draft.trackDetailLoading = false; break; } }); -export default trackDetailContainerReducer; +export default trackDetailReducer; diff --git a/app/containers/TrackDetailContainer/saga.js b/app/containers/TrackDetailProvider/saga.js similarity index 69% rename from app/containers/TrackDetailContainer/saga.js rename to app/containers/TrackDetailProvider/saga.js index 9eb254c..2f6b3f1 100644 --- a/app/containers/TrackDetailContainer/saga.js +++ b/app/containers/TrackDetailProvider/saga.js @@ -1,9 +1,9 @@ import { put, call, takeLatest } from 'redux-saga/effects'; import { getTrack } from '@services/trackApi'; -import { trackDetailContainerTypes, trackDetailContainerCreators } from './reducer'; +import { trackDetailTypes, trackDetailCreators } from './reducer'; -const { REQUEST_GET_TRACK_DETAIL } = trackDetailContainerTypes; -const { successGetTrackDetail, failureGetTrackDetail } = trackDetailContainerCreators; +const { REQUEST_GET_TRACK_DETAIL } = trackDetailTypes; +const { successGetTrackDetail, failureGetTrackDetail } = trackDetailCreators; export function* getTrackDetail(action) { const response = yield call(getTrack, action.trackId); const { data, ok } = response; @@ -14,6 +14,6 @@ export function* getTrackDetail(action) { } } // Individual exports for testing -export default function* trackDetailContainerSaga() { +export default function* trackDetailSaga() { yield takeLatest(REQUEST_GET_TRACK_DETAIL, getTrackDetail); } diff --git a/app/containers/TrackDetailContainer/selectors.js b/app/containers/TrackDetailProvider/selectors.js similarity index 50% rename from app/containers/TrackDetailContainer/selectors.js rename to app/containers/TrackDetailProvider/selectors.js index 6df5551..fb3b404 100644 --- a/app/containers/TrackDetailContainer/selectors.js +++ b/app/containers/TrackDetailProvider/selectors.js @@ -6,7 +6,7 @@ import { initialState } from './reducer'; * Direct selector to the trackDetailContainer state domain */ -export const selectTrackDetailContainerDomain = (state) => state.trackDetailContainer || initialState; +export const selectTrackDetailDomain = (state) => state.trackDetailContainer || initialState; /** * Other specific selectors @@ -17,10 +17,10 @@ export const selectTrackDetailContainerDomain = (state) => state.trackDetailCont */ export const selectTrackDetailData = () => - createSelector(selectTrackDetailContainerDomain, (substate) => get(substate, 'trackDetailData')); + createSelector(selectTrackDetailDomain, (substate) => get(substate, 'trackDetailData')); export const selectTrackError = () => - createSelector(selectTrackDetailContainerDomain, (substate) => get(substate, 'trackError')); + createSelector(selectTrackDetailDomain, (substate) => get(substate, 'trackError')); export const selectTrackDetailLoading = () => - createSelector(selectTrackDetailContainerDomain, (substate) => get(substate, 'trackDetailLoading')); + createSelector(selectTrackDetailDomain, (substate) => get(substate, 'trackDetailLoading')); diff --git a/app/containers/TrackDetailContainer/tests/reducer.test.js b/app/containers/TrackDetailProvider/tests/reducer.test.js similarity index 70% rename from app/containers/TrackDetailContainer/tests/reducer.test.js rename to app/containers/TrackDetailProvider/tests/reducer.test.js index 56798ca..a6131b6 100644 --- a/app/containers/TrackDetailContainer/tests/reducer.test.js +++ b/app/containers/TrackDetailProvider/tests/reducer.test.js @@ -1,4 +1,4 @@ -import { trackDetailContainerReducer, initialState, trackDetailContainerTypes } from '../reducer'; +import { trackDetailReducer, initialState, trackDetailTypes } from '../reducer'; /* eslint-disable default-case, no-param-reassign */ describe('TrackDetailContainer reducer tests', () => { @@ -8,15 +8,15 @@ describe('TrackDetailContainer reducer tests', () => { }); it('should return the initial state', () => { - expect(trackDetailContainerReducer(undefined, {})).toEqual(state); + expect(trackDetailReducer(undefined, {})).toEqual(state); }); it('should return the initial state when an action of type REQUEST_GET_TRACK_DETAIL is dispatched', () => { const trackId = 'Sunflower'; const expectedResult = { ...state, trackId, trackDetailLoading: true }; expect( - trackDetailContainerReducer(state, { - type: trackDetailContainerTypes.REQUEST_GET_TRACK_DETAIL, + trackDetailReducer(state, { + type: trackDetailTypes.REQUEST_GET_TRACK_DETAIL, trackId }) ).toEqual(expectedResult); @@ -26,8 +26,8 @@ describe('TrackDetailContainer reducer tests', () => { const data = { artistName: 'Post Malone' }; const expectedResult = { ...state, trackDetailData: data, trackDetailLoading: false }; expect( - trackDetailContainerReducer(state, { - type: trackDetailContainerTypes.SUCCESS_GET_TRACK_DETAIL, + trackDetailReducer(state, { + type: trackDetailTypes.SUCCESS_GET_TRACK_DETAIL, data }) ).toEqual(expectedResult); @@ -37,8 +37,8 @@ describe('TrackDetailContainer reducer tests', () => { const error = 'something_went_wrong'; const expectedResult = { ...state, trackError: error, trackDetailLoading: false }; expect( - trackDetailContainerReducer(state, { - type: trackDetailContainerTypes.FAILURE_GET_TRACK_DETAIL, + trackDetailReducer(state, { + type: trackDetailTypes.FAILURE_GET_TRACK_DETAIL, error }) ).toEqual(expectedResult); diff --git a/app/containers/TrackDetailContainer/tests/saga.test.js b/app/containers/TrackDetailProvider/tests/saga.test.js similarity index 77% rename from app/containers/TrackDetailContainer/tests/saga.test.js rename to app/containers/TrackDetailProvider/tests/saga.test.js index 148f786..fcd3185 100644 --- a/app/containers/TrackDetailContainer/tests/saga.test.js +++ b/app/containers/TrackDetailProvider/tests/saga.test.js @@ -6,18 +6,16 @@ import { takeLatest, call, put } from 'redux-saga/effects'; import { getTrack } from '@services/trackApi'; import { apiResponseGenerator } from '@utils/testUtils'; -import trackDetailContainerSaga, { getTrackDetail } from '../saga'; -import { trackDetailContainerTypes } from '../reducer'; +import trackDetailSaga, { getTrackDetail } from '../saga'; +import { trackDetailTypes } from '../reducer'; describe('TrackDetailContainer saga tests', () => { - const generator = trackDetailContainerSaga(); + const generator = trackDetailSaga(); const trackId = 12323; let getTracksGenerator = getTrackDetail({ trackId }); it('should start task to watch for REQUEST_GET_TRACK_DETAIL action', () => { - expect(generator.next().value).toEqual( - takeLatest(trackDetailContainerTypes.REQUEST_GET_TRACK_DETAIL, getTrackDetail) - ); + expect(generator.next().value).toEqual(takeLatest(trackDetailTypes.REQUEST_GET_TRACK_DETAIL, getTrackDetail)); }); it('should ensure that the action FAILURE_GET_TRACK_DETAIL is dispatched when the api call fails', () => { @@ -28,7 +26,7 @@ describe('TrackDetailContainer saga tests', () => { }; expect(getTracksGenerator.next(apiResponseGenerator(false, errorResponse)).value).toEqual( put({ - type: trackDetailContainerTypes.FAILURE_GET_TRACK_DETAIL, + type: trackDetailTypes.FAILURE_GET_TRACK_DETAIL, error: errorResponse }) ); @@ -44,7 +42,7 @@ describe('TrackDetailContainer saga tests', () => { }; expect(getTracksGenerator.next(apiResponseGenerator(true, tracksResponse)).value).toEqual( put({ - type: trackDetailContainerTypes.SUCCESS_GET_TRACK_DETAIL, + type: trackDetailTypes.SUCCESS_GET_TRACK_DETAIL, data: tracksResponse }) ); diff --git a/app/containers/TrackDetailContainer/tests/selectors.test.js b/app/containers/TrackDetailProvider/tests/selectors.test.js similarity index 92% rename from app/containers/TrackDetailContainer/tests/selectors.test.js rename to app/containers/TrackDetailProvider/tests/selectors.test.js index 1457abb..c45f5ef 100644 --- a/app/containers/TrackDetailContainer/tests/selectors.test.js +++ b/app/containers/TrackDetailProvider/tests/selectors.test.js @@ -1,5 +1,5 @@ import { - selectTrackDetailContainerDomain, + selectTrackDetailDomain, selectTrackDetailData, selectTrackError, selectTrackDetailLoading @@ -41,7 +41,7 @@ describe('TrackDetailContainer selector tests', () => { }); it('should select the global state', () => { - const selector = selectTrackDetailContainerDomain(initialState); + const selector = selectTrackDetailDomain(initialState); expect(selector).toEqual(initialState); }); }); diff --git a/app/createRootReducer.js b/app/createRootReducer.js index 76f02fc..8066159 100644 --- a/app/createRootReducer.js +++ b/app/createRootReducer.js @@ -6,7 +6,7 @@ import { combineReducers } from 'redux'; import languageProviderReducer from 'containers/LanguageProvider/reducer'; import homeContainerReducer from 'containers/HomeContainer/reducer'; import trackContainerReducer from './containers/TrackContainer/reducer'; -import trackDetailContainerReducer from './containers/TrackDetailContainer/reducer'; +import trackDetailReducer from './containers/TrackDetailProvider/reducer'; /** * Merges the main reducer with the router state and dynamically injected reducers @@ -17,6 +17,6 @@ export default function createRootReducer(injectedReducer = {}) { language: languageProviderReducer, homeContainer: homeContainerReducer, trackContainer: trackContainerReducer, - trackDetailContainer: trackDetailContainerReducer + trackDetailContainer: trackDetailReducer }); } From aa7f8f529045795caa5b5e878af9642e81408408 Mon Sep 17 00:00:00 2001 From: Anas WS Date: Wed, 6 Mar 2024 19:01:57 +0530 Subject: [PATCH 2/2] Last task done --- app/containers/TrackDetailContainer/index.js | 25 +++++++++++++++++--- internals/webpack/webpack.config.base.js | 6 ++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/containers/TrackDetailContainer/index.js b/app/containers/TrackDetailContainer/index.js index df33296..3d60c9c 100644 --- a/app/containers/TrackDetailContainer/index.js +++ b/app/containers/TrackDetailContainer/index.js @@ -16,6 +16,7 @@ import { translate } from '@app/utils/index'; import trackDetailSaga from '../TrackDetailProvider/saga'; import { selectTrackDetailData, selectTrackError, selectTrackDetailLoading } from '../TrackDetailProvider/selectors'; import { trackDetailCreators } from '../TrackDetailProvider/reducer'; +import { selectTracksData } from '../TrackContainer/selectors'; // Custom Styling const CustomCard = styled(Card)` @@ -34,16 +35,27 @@ const CustomCardHeader = styled(CardHeader)` `; export const TrackDetailContainer = ({ + tracksData, trackDetailData, trackError, trackDetailLoading, dispatchTrackDetail, + dispatchTrackDetailData, padding }) => { const { trackId } = useParams(); useEffect(() => { - dispatchTrackDetail(trackId); + const trackDataResults = get(tracksData, 'results', []); + const data = trackDataResults.find((track) => { + return track.collectionId == trackId; + }); + if (isEmpty(data)) { + dispatchTrackDetail(trackId); + } else { + dispatchTrackDetailData({ results: [data] }); + } + // dispatchTrackDetail(trackId); }, []); const renderSkeleton = () => { @@ -102,6 +114,10 @@ export const TrackDetailContainer = ({ }; TrackDetailContainer.propTypes = { + tracksData: PropTypes.shape({ + resultCount: PropTypes.number, + results: PropTypes.array + }), trackDetailData: PropTypes.shape({ resultCount: PropTypes.number, results: PropTypes.array @@ -109,6 +125,7 @@ TrackDetailContainer.propTypes = { trackError: PropTypes.string, trackDetailLoading: PropTypes.bool, dispatchTrackDetail: PropTypes.func, + dispatchTrackDetailData: PropTypes.func, padding: PropTypes.number }; @@ -119,15 +136,17 @@ TrackDetailContainer.defaultProps = { }; const mapStateToProps = createStructuredSelector({ + tracksData: selectTracksData(), trackDetailData: selectTrackDetailData(), trackError: selectTrackError(), trackDetailLoading: selectTrackDetailLoading() }); export function mapDispatchToProps(dispatch) { - const { requestGetTrackDetail } = trackDetailCreators; + const { requestGetTrackDetail, successGetTrackDetail } = trackDetailCreators; return { - dispatchTrackDetail: (trackId) => dispatch(requestGetTrackDetail(trackId)) + dispatchTrackDetail: (trackId) => dispatch(requestGetTrackDetail(trackId)), + dispatchTrackDetailData: (data) => dispatch(successGetTrackDetail(data)) }; } diff --git a/internals/webpack/webpack.config.base.js b/internals/webpack/webpack.config.base.js index d1bd008..77edac2 100644 --- a/internals/webpack/webpack.config.base.js +++ b/internals/webpack/webpack.config.base.js @@ -135,7 +135,11 @@ module.exports = (options) => ({ interlaced: false }, optipng: { - optimizationLevel: 7 + enabled: false + // NOTE: optipng is disabled as it causes errors in some Mac M1 & M2 environments + // Try enabling it in your environment by switching the config to: + // enabled: true, + // optimizationLevel: 7 }, pngquant: { quality: [0.65, 0.9],