Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track detail provider #6

Merged
merged 2 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions app/containers/TrackDetailContainer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ 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';
import { selectTracksData } from '../TrackContainer/selectors';

// Custom Styling
const CustomCard = styled(Card)`
Expand All @@ -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 = () => {
Expand Down Expand Up @@ -102,13 +114,18 @@ export const TrackDetailContainer = ({
};

TrackDetailContainer.propTypes = {
tracksData: PropTypes.shape({
resultCount: PropTypes.number,
results: PropTypes.array
}),
trackDetailData: PropTypes.shape({
resultCount: PropTypes.number,
results: PropTypes.array
}),
trackError: PropTypes.string,
trackDetailLoading: PropTypes.bool,
dispatchTrackDetail: PropTypes.func,
dispatchTrackDetailData: PropTypes.func,
padding: PropTypes.number
};

Expand All @@ -119,15 +136,17 @@ TrackDetailContainer.defaultProps = {
};

const mapStateToProps = createStructuredSelector({
tracksData: selectTracksData(),
trackDetailData: selectTrackDetailData(),
trackError: selectTrackError(),
trackDetailLoading: selectTrackDetailLoading()
});

export function mapDispatchToProps(dispatch) {
const { requestGetTrackDetail } = trackDetailContainerCreators;
const { requestGetTrackDetail, successGetTrackDetail } = trackDetailCreators;
return {
dispatchTrackDetail: (trackId) => dispatch(requestGetTrackDetail(trackId))
dispatchTrackDetail: (trackId) => dispatch(requestGetTrackDetail(trackId)),
dispatchTrackDetailData: (data) => dispatch(successGetTrackDetail(data))
};
}

Expand All @@ -136,7 +155,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);
4 changes: 2 additions & 2 deletions app/containers/TrackDetailContainer/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<TrackDetailContainer /> tests', () => {
let submitSpy;
Expand All @@ -25,7 +25,7 @@ describe('<TrackDetailContainer /> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ 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']
});
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;
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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'));
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -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
})
);
Expand All @@ -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
})
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
selectTrackDetailContainerDomain,
selectTrackDetailDomain,
selectTrackDetailData,
selectTrackError,
selectTrackDetailLoading
Expand Down Expand Up @@ -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);
});
});
4 changes: 2 additions & 2 deletions app/createRootReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,6 +17,6 @@ export default function createRootReducer(injectedReducer = {}) {
language: languageProviderReducer,
homeContainer: homeContainerReducer,
trackContainer: trackContainerReducer,
trackDetailContainer: trackDetailContainerReducer
trackDetailContainer: trackDetailReducer
});
}
6 changes: 5 additions & 1 deletion internals/webpack/webpack.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
Loading