Upgrading to hooks, simplifying unit test mocks
This commit is contained in:
@ -13,8 +13,8 @@ jest.mock('redux-persist', () => ({
|
||||
persistReducer: jest.fn().mockImplementation((config, reducers) => reducers),
|
||||
}));
|
||||
jest.mock('react-redux', () => ({
|
||||
useSelector: jest.fn(() => mockState),
|
||||
useDispatch: jest.fn(fn => fn()),
|
||||
useSelector: jest.fn().mockImplementation(func => func(mockState)),
|
||||
useDispatch: jest.fn(),
|
||||
connect: jest.fn(fn => fn()),
|
||||
}));
|
||||
jest.mock('react-router-dom', () => ({
|
||||
@ -30,7 +30,8 @@ jest.mock('react-router-dom', () => ({
|
||||
}));
|
||||
|
||||
describe('<Album />', () => {
|
||||
const album = state.core.items['local:album:md5:66fbea3593ba96a15a9d4188bebab50b'];
|
||||
|
||||
const album = mockState.core.items['local:album:md5:66fbea3593ba96a15a9d4188bebab50b'];
|
||||
|
||||
// Need to rebuild Album to functional component, at which point I'll copy previous
|
||||
// snapshot testing approach from other project
|
||||
|
||||
36
__tests__/views/__snapshots__/Album.test.js.snap
Normal file
36
__tests__/views/__snapshots__/Album.test.js.snap
Normal file
@ -0,0 +1,36 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Album /> should render accurately 1`] = `
|
||||
<div
|
||||
className="error-message error-message--not-found"
|
||||
data-qa-file="ErrorMessage"
|
||||
data-qa-node="div"
|
||||
>
|
||||
<i
|
||||
className="error-message__icon icon icon--material"
|
||||
data-qa-file="ErrorMessage"
|
||||
data-qa-node="i"
|
||||
>
|
||||
error
|
||||
</i>
|
||||
<h4
|
||||
className="error-message__title"
|
||||
data-qa-file="ErrorMessage"
|
||||
data-qa-node="h4"
|
||||
>
|
||||
Not found
|
||||
</h4>
|
||||
<div
|
||||
className="error-message__content"
|
||||
data-qa-file="ErrorMessage"
|
||||
data-qa-node="div"
|
||||
>
|
||||
<p
|
||||
data-qa-file="Album"
|
||||
data-qa-node="p"
|
||||
>
|
||||
Could not find anything with URI
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -1,33 +1,29 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import * as uiActions from '../../services/ui/actions';
|
||||
import * as spotifyActions from '../../services/spotify/actions';
|
||||
import { getFromUri } from '../../util/helpers';
|
||||
import { createNotification } from '../../services/ui/actions';
|
||||
import { following } from '../../services/spotify/actions';
|
||||
import { i18n } from '../../locale';
|
||||
import { Button } from '../Button';
|
||||
import { makeLoadingSelector } from '../../util/selectors';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const loadingSelector = makeLoadingSelector(['(.*)(follow)|(me\/albums)(.*)']);
|
||||
|
||||
const FollowButton = ({
|
||||
spotifyActions: {
|
||||
following,
|
||||
},
|
||||
uiActions: {
|
||||
createNotification,
|
||||
},
|
||||
uri,
|
||||
addText,
|
||||
removeText,
|
||||
spotify_authorized,
|
||||
is_following,
|
||||
loading,
|
||||
}) => {
|
||||
const remove = () => following(uri, 'DELETE');
|
||||
const add = () => following(uri, 'PUT');
|
||||
const unauthorized = () => createNotification({
|
||||
content: i18n('errors.authorization_required', { provider: i18n('services.spotify.title') }),
|
||||
level: 'warning',
|
||||
});
|
||||
const loading = useSelector(loadingSelector);
|
||||
const spotify_authorized = useSelector((state) => state.spotify.authorization);
|
||||
const remove = () => dispatch(following(uri, 'DELETE'));
|
||||
const add = () => dispatch(following(uri, 'PUT'));
|
||||
const unauthorized = () => dispatch(
|
||||
createNotification({
|
||||
content: i18n('errors.authorization_required', { provider: i18n('services.spotify.title') }),
|
||||
level: 'warning',
|
||||
}),
|
||||
);
|
||||
|
||||
if (!uri) return null;
|
||||
|
||||
@ -65,18 +61,4 @@ const FollowButton = ({
|
||||
);
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const loadingSelector = makeLoadingSelector(['(.*)(follow)|(me\/albums)(.*)']);
|
||||
|
||||
return {
|
||||
loading: loadingSelector(state),
|
||||
spotify_authorized: state.spotify.authorization,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
uiActions: bindActionCreators(uiActions, dispatch),
|
||||
spotifyActions: bindActionCreators(spotifyActions, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(FollowButton);
|
||||
export default FollowButton;
|
||||
|
||||
@ -1,33 +1,26 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { range, uniqBy } from 'lodash';
|
||||
import Track from './Track';
|
||||
import * as mopidyActions from '../services/mopidy/actions';
|
||||
import * as uiActions from '../services/ui/actions';
|
||||
import { playURIs, changeTrack } from '../services/mopidy/actions';
|
||||
import { createNotification, showContextMenu } from '../services/ui/actions';
|
||||
import { isTouchDevice } from '../util/helpers';
|
||||
import { arrayOf } from '../util/arrays';
|
||||
import { SmartList } from './SmartList';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
const TrackList = ({
|
||||
context,
|
||||
className = '',
|
||||
show_source_icon,
|
||||
play_state,
|
||||
slim_mode,
|
||||
tracks,
|
||||
playTracks,
|
||||
removeTracks,
|
||||
reorderTracks,
|
||||
uiActions: {
|
||||
createNotification,
|
||||
showContextMenu,
|
||||
},
|
||||
mopidyActions: {
|
||||
playURIs,
|
||||
changeTrack,
|
||||
},
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const play_state = useSelector((state) => state.mopidy.play_state);
|
||||
const { slim_mode } = useSelector((state) => state.ui);
|
||||
const [selected, setSelected] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
@ -100,9 +93,9 @@ const TrackList = ({
|
||||
onDoubleClick: (item, index) => {
|
||||
setSelected([{ item, index }]);
|
||||
if (context?.type === 'queue') {
|
||||
changeTrack(item.tlid);
|
||||
dispatch(changeTrack(item.tlid));
|
||||
} else {
|
||||
playURIs({ uris: [item.uri], from: context });
|
||||
dispatch(playURIs({ uris: [item.uri], from: context }));
|
||||
}
|
||||
},
|
||||
onContextMenu: (item, index, e) => {
|
||||
@ -114,14 +107,14 @@ const TrackList = ({
|
||||
({ index, item }) => ({ index, ...item }),
|
||||
);
|
||||
|
||||
showContextMenu({
|
||||
dispatch(showContextMenu({
|
||||
e,
|
||||
context,
|
||||
...(items.length === 1
|
||||
? { type: 'track', item: items[0] }
|
||||
: { type: 'tracks', items }
|
||||
),
|
||||
});
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
@ -132,7 +125,7 @@ const TrackList = ({
|
||||
if (playTracks) {
|
||||
playTracks(selectedTracks);
|
||||
} else {
|
||||
playURIs({ uris: arrayOf('uri', selectedTracks), from: context });
|
||||
dispatch(playURIs({ uris: arrayOf('uri', selectedTracks), from: context }));
|
||||
}
|
||||
};
|
||||
|
||||
@ -140,10 +133,10 @@ const TrackList = ({
|
||||
if (!selected || !selected.length) return;
|
||||
|
||||
if (!removeTracks) {
|
||||
createNotification({
|
||||
dispatch(createNotification({
|
||||
content: `Cannot delete ${selected.length > 1 ? 'these tracks' : 'this track'}`,
|
||||
level: 'error',
|
||||
});
|
||||
}));
|
||||
return;
|
||||
}
|
||||
removeTracks(selected.map(({ index }) => index));
|
||||
@ -233,18 +226,4 @@ const TrackList = ({
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
play_state: state.mopidy.play_state,
|
||||
slim_mode: state.ui.slim_mode,
|
||||
selected_tracks: state.ui.selected_tracks,
|
||||
current_track: state.core.current_track,
|
||||
context_menu: state.ui.context_menu,
|
||||
stream_title: state.core.stream_title,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
mopidyActions: bindActionCreators(mopidyActions, dispatch),
|
||||
uiActions: bindActionCreators(uiActions, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TrackList);
|
||||
export default TrackList;
|
||||
|
||||
Reference in New Issue
Block a user