mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #14958 from aocenas/refresh-playlist-counter
Add loop counter for full refresh in playlist
This commit is contained in:
commit
3dca65c6b8
@ -4,12 +4,13 @@ import appEvents from 'app/core/app_events';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { toUrlParams } from 'app/core/utils/url';
|
import { toUrlParams } from 'app/core/utils/url';
|
||||||
|
|
||||||
class PlaylistSrv {
|
export class PlaylistSrv {
|
||||||
private cancelPromise: any;
|
private cancelPromise: any;
|
||||||
private dashboards: any;
|
private dashboards: Array<{ uri: string }>;
|
||||||
private index: number;
|
private index: number;
|
||||||
private interval: any;
|
private interval: number;
|
||||||
private startUrl: string;
|
private startUrl: string;
|
||||||
|
private numberOfLoops = 0;
|
||||||
isPlaying: boolean;
|
isPlaying: boolean;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
@ -20,8 +21,15 @@ class PlaylistSrv {
|
|||||||
|
|
||||||
const playedAllDashboards = this.index > this.dashboards.length - 1;
|
const playedAllDashboards = this.index > this.dashboards.length - 1;
|
||||||
if (playedAllDashboards) {
|
if (playedAllDashboards) {
|
||||||
window.location.href = this.startUrl;
|
this.numberOfLoops++;
|
||||||
return;
|
|
||||||
|
// This does full reload of the playlist to keep memory in check due to existing leaks but at the same time
|
||||||
|
// we do not want page to flicker after each full loop.
|
||||||
|
if (this.numberOfLoops >= 3) {
|
||||||
|
window.location.href = this.startUrl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dash = this.dashboards[this.index];
|
const dash = this.dashboards[this.index];
|
||||||
@ -46,8 +54,8 @@ class PlaylistSrv {
|
|||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.isPlaying = true;
|
this.isPlaying = true;
|
||||||
|
|
||||||
this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
|
return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
|
||||||
this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
|
return this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
|
||||||
this.dashboards = dashboards;
|
this.dashboards = dashboards;
|
||||||
this.interval = kbn.interval_to_ms(playlist.interval);
|
this.interval = kbn.interval_to_ms(playlist.interval);
|
||||||
this.next();
|
this.next();
|
||||||
|
103
public/app/features/playlist/specs/playlist_srv.test.ts
Normal file
103
public/app/features/playlist/specs/playlist_srv.test.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { PlaylistSrv } from '../playlist_srv';
|
||||||
|
|
||||||
|
const dashboards = [{ uri: 'dash1' }, { uri: 'dash2' }];
|
||||||
|
|
||||||
|
const createPlaylistSrv = (): [PlaylistSrv, { url: jest.MockInstance<any> }] => {
|
||||||
|
const mockBackendSrv = {
|
||||||
|
get: jest.fn(url => {
|
||||||
|
switch (url) {
|
||||||
|
case '/api/playlists/1':
|
||||||
|
return Promise.resolve({ interval: '1s' });
|
||||||
|
case '/api/playlists/1/dashboards':
|
||||||
|
return Promise.resolve(dashboards);
|
||||||
|
default:
|
||||||
|
throw new Error(`Unexpected url=${url}`);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockLocation = {
|
||||||
|
url: jest.fn(),
|
||||||
|
search: () => ({}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockTimeout = jest.fn();
|
||||||
|
(mockTimeout as any).cancel = jest.fn();
|
||||||
|
|
||||||
|
return [new PlaylistSrv(mockLocation, mockTimeout, mockBackendSrv), mockLocation];
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockWindowLocation = (): [jest.MockInstance<any>, () => void] => {
|
||||||
|
const oldLocation = window.location;
|
||||||
|
const hrefMock = jest.fn();
|
||||||
|
|
||||||
|
// JSDom defines window in a way that you cannot tamper with location so this seems to be the only way to change it.
|
||||||
|
// https://github.com/facebook/jest/issues/5124#issuecomment-446659510
|
||||||
|
delete window.location;
|
||||||
|
window.location = {} as any;
|
||||||
|
|
||||||
|
// Only mocking href as that is all this test needs, but otherwise there is lots of things missing, so keep that
|
||||||
|
// in mind if this is reused.
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
set: hrefMock,
|
||||||
|
get: hrefMock,
|
||||||
|
});
|
||||||
|
const unmock = () => {
|
||||||
|
window.location = oldLocation;
|
||||||
|
};
|
||||||
|
return [hrefMock, unmock];
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('PlaylistSrv', () => {
|
||||||
|
let srv: PlaylistSrv;
|
||||||
|
let mockLocationService: { url: jest.MockInstance<any> };
|
||||||
|
let hrefMock: jest.MockInstance<any>;
|
||||||
|
let unmockLocation: () => void;
|
||||||
|
const initialUrl = 'http://localhost/playlist';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
[srv, mockLocationService] = createPlaylistSrv();
|
||||||
|
[hrefMock, unmockLocation] = mockWindowLocation();
|
||||||
|
|
||||||
|
// This will be cached in the srv when start() is called
|
||||||
|
hrefMock.mockReturnValue(initialUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
unmockLocation();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('runs all dashboards in cycle and reloads page after 3 cycles', async () => {
|
||||||
|
await srv.start(1);
|
||||||
|
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
expect(mockLocationService.url).toHaveBeenLastCalledWith(`dashboard/${dashboards[i % 2].uri}?`);
|
||||||
|
srv.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(hrefMock).toHaveBeenCalledTimes(2);
|
||||||
|
expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps the refresh counter value after restarting', async () => {
|
||||||
|
await srv.start(1);
|
||||||
|
|
||||||
|
// 1 complete loop
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
expect(mockLocationService.url).toHaveBeenLastCalledWith(`dashboard/${dashboards[i % 2].uri}?`);
|
||||||
|
srv.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
srv.stop();
|
||||||
|
await srv.start(1);
|
||||||
|
|
||||||
|
// Another 2 loops
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
expect(mockLocationService.url).toHaveBeenLastCalledWith(`dashboard/${dashboards[i % 2].uri}?`);
|
||||||
|
srv.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(hrefMock).toHaveBeenCalledTimes(3);
|
||||||
|
expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user