playlist_srv.test.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // @ts-ignore
  2. import configureMockStore from 'redux-mock-store';
  3. import { PlaylistSrv } from '../playlist_srv';
  4. import { setStore } from 'app/store/store';
  5. const mockStore = configureMockStore();
  6. setStore(
  7. mockStore({
  8. location: {},
  9. })
  10. );
  11. const dashboards = [{ url: 'dash1' }, { url: 'dash2' }];
  12. const createPlaylistSrv = (): [PlaylistSrv, { url: jest.MockInstance<any, any> }] => {
  13. const mockBackendSrv = {
  14. get: jest.fn(url => {
  15. switch (url) {
  16. case '/api/playlists/1':
  17. return Promise.resolve({ interval: '1s' });
  18. case '/api/playlists/1/dashboards':
  19. return Promise.resolve(dashboards);
  20. default:
  21. throw new Error(`Unexpected url=${url}`);
  22. }
  23. }),
  24. };
  25. const mockLocation = {
  26. url: jest.fn(),
  27. search: () => ({}),
  28. path: () => '/playlists/1',
  29. };
  30. const mockTimeout = jest.fn();
  31. (mockTimeout as any).cancel = jest.fn();
  32. return [new PlaylistSrv(mockLocation, mockTimeout, mockBackendSrv), mockLocation];
  33. };
  34. const mockWindowLocation = (): [jest.MockInstance<any, any>, () => void] => {
  35. const oldLocation = window.location;
  36. const hrefMock = jest.fn();
  37. // JSDom defines window in a way that you cannot tamper with location so this seems to be the only way to change it.
  38. // https://github.com/facebook/jest/issues/5124#issuecomment-446659510
  39. delete window.location;
  40. window.location = {} as any;
  41. // Only mocking href as that is all this test needs, but otherwise there is lots of things missing, so keep that
  42. // in mind if this is reused.
  43. Object.defineProperty(window.location, 'href', {
  44. set: hrefMock,
  45. get: hrefMock,
  46. });
  47. const unmock = () => {
  48. window.location = oldLocation;
  49. };
  50. return [hrefMock, unmock];
  51. };
  52. describe('PlaylistSrv', () => {
  53. let srv: PlaylistSrv;
  54. let hrefMock: jest.MockInstance<any, any>;
  55. let unmockLocation: () => void;
  56. const initialUrl = 'http://localhost/playlist';
  57. beforeEach(() => {
  58. [srv] = createPlaylistSrv();
  59. [hrefMock, unmockLocation] = mockWindowLocation();
  60. // This will be cached in the srv when start() is called
  61. hrefMock.mockReturnValue(initialUrl);
  62. });
  63. afterEach(() => {
  64. unmockLocation();
  65. });
  66. it('runs all dashboards in cycle and reloads page after 3 cycles', async () => {
  67. await srv.start(1);
  68. for (let i = 0; i < 6; i++) {
  69. srv.next();
  70. }
  71. expect(hrefMock).toHaveBeenCalledTimes(2);
  72. expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
  73. });
  74. it('keeps the refresh counter value after restarting', async () => {
  75. await srv.start(1);
  76. // 1 complete loop
  77. for (let i = 0; i < 3; i++) {
  78. srv.next();
  79. }
  80. srv.stop();
  81. await srv.start(1);
  82. // Another 2 loops
  83. for (let i = 0; i < 4; i++) {
  84. srv.next();
  85. }
  86. expect(hrefMock).toHaveBeenCalledTimes(3);
  87. expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
  88. });
  89. it('storeUpdated should stop playlist when navigating away', async () => {
  90. await srv.start(1);
  91. srv.storeUpdated();
  92. expect(srv.isPlaying).toBe(false);
  93. });
  94. it('storeUpdated should not stop playlist when navigating to next dashboard', async () => {
  95. await srv.start(1);
  96. srv.next();
  97. setStore(
  98. mockStore({
  99. location: {
  100. path: 'dash2',
  101. },
  102. })
  103. );
  104. expect((srv as any).validPlaylistUrl).toBe('dash2');
  105. srv.storeUpdated();
  106. expect(srv.isPlaying).toBe(true);
  107. });
  108. });