PlaylistSrv.test.ts 3.4 KB

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