status.spec.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { render, RenderResult, waitFor } from '@testing-library/react';
  2. import nock from 'nock';
  3. import React from 'react';
  4. import { songInfoFetched } from '../actions';
  5. import { DispatchContext, StateContext } from '../context/state';
  6. import { GlobalState, initialState } from '../reducer';
  7. import { Song } from '../types';
  8. import { useCurrentlyPlayingSongInfo } from './status';
  9. describe(useCurrentlyPlayingSongInfo.name, () => {
  10. const TestComponent: React.FC = () => {
  11. useCurrentlyPlayingSongInfo();
  12. return null;
  13. };
  14. const dispatch = jest.fn();
  15. const setup = (state: GlobalState): RenderResult =>
  16. render(
  17. <StateContext.Provider value={state}>
  18. <DispatchContext.Provider value={dispatch}>
  19. <TestComponent />
  20. </DispatchContext.Provider>
  21. </StateContext.Provider>,
  22. );
  23. const testSong: Song = {
  24. id: 1765,
  25. track: 12,
  26. title: 'My song',
  27. artist: 'My artist',
  28. album: 'My album',
  29. time: 218,
  30. };
  31. describe('when there is no song ID', () => {
  32. const stateNoId: GlobalState = {
  33. ...initialState,
  34. player: {
  35. ...initialState.player,
  36. songId: null,
  37. },
  38. };
  39. describe('when there is no song info in state', () => {
  40. const stateNoIdNoInfo: GlobalState = {
  41. ...stateNoId,
  42. songInfo: null,
  43. };
  44. it('should not do anything', () => {
  45. expect.assertions(1);
  46. setup(stateNoIdNoInfo);
  47. expect(dispatch).not.toHaveBeenCalled();
  48. });
  49. });
  50. describe('when there is song info in state', () => {
  51. const stateNoIdWithInfo: GlobalState = {
  52. ...stateNoId,
  53. songInfo: testSong,
  54. };
  55. it('should dispatch an action to clear the current info', () => {
  56. expect.assertions(2);
  57. setup(stateNoIdWithInfo);
  58. expect(dispatch).toHaveBeenCalledTimes(1);
  59. expect(dispatch).toHaveBeenCalledWith(songInfoFetched(null));
  60. });
  61. });
  62. });
  63. describe('when there is a song ID in state', () => {
  64. const stateWithSongId: GlobalState = {
  65. ...initialState,
  66. player: {
  67. ...initialState.player,
  68. songId: testSong.id,
  69. },
  70. };
  71. describe('when the song info is already fetched for the playing song ID', () => {
  72. const stateFetched: GlobalState = {
  73. ...stateWithSongId,
  74. songInfo: testSong,
  75. };
  76. it('should not do anything', () => {
  77. expect.assertions(1);
  78. setup(stateFetched);
  79. expect(dispatch).not.toHaveBeenCalled();
  80. });
  81. });
  82. describe('when the song info is stale', () => {
  83. const stateStale: GlobalState = {
  84. ...stateWithSongId,
  85. songInfo: { ...testSong, id: testSong.id + 1 },
  86. };
  87. beforeEach(() => {
  88. nock('http://my-api.url:1234')
  89. .get('/song-info?id=1765')
  90. .reply(200, testSong, { 'Access-Control-Allow-Origin': '*' });
  91. });
  92. // eslint-disable-next-line jest/prefer-expect-assertions
  93. it('should fetch the info for the updated song ID, and update the state', async () => {
  94. setup(stateStale);
  95. await waitFor(() => {
  96. expect(dispatch).toHaveBeenCalledTimes(1);
  97. });
  98. expect(dispatch).toHaveBeenCalledWith(songInfoFetched(testSong));
  99. });
  100. });
  101. });
  102. });