playlist_srv.test.ts 3.3 KB

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