Merge pull request #14958 from aocenas/refresh-playlist-counter

Add loop counter for full refresh in playlist
This commit is contained in:
Torkel Ödegaard 2019-01-23 15:34:49 +01:00 committed by GitHub
commit 3dca65c6b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 7 deletions

View File

@ -4,12 +4,13 @@ import appEvents from 'app/core/app_events';
import _ from 'lodash';
import { toUrlParams } from 'app/core/utils/url';
class PlaylistSrv {
export class PlaylistSrv {
private cancelPromise: any;
private dashboards: any;
private dashboards: Array<{ uri: string }>;
private index: number;
private interval: any;
private interval: number;
private startUrl: string;
private numberOfLoops = 0;
isPlaying: boolean;
/** @ngInject */
@ -20,8 +21,15 @@ class PlaylistSrv {
const playedAllDashboards = this.index > this.dashboards.length - 1;
if (playedAllDashboards) {
window.location.href = this.startUrl;
return;
this.numberOfLoops++;
// 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];
@ -46,8 +54,8 @@ class PlaylistSrv {
this.index = 0;
this.isPlaying = true;
this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
return this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
this.dashboards = dashboards;
this.interval = kbn.interval_to_ms(playlist.interval);
this.next();

View 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);
});
});