The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/playlist/PlaylistSrv.test.ts

166 lines
4.5 KiB

import { Store } from 'redux';
import configureMockStore from 'redux-mock-store';
import { locationService } from '@grafana/runtime';
import { setStore } from 'app/store/store';
import { DashboardQueryResult } from '../search/service/types';
import { PlaylistSrv } from './PlaylistSrv';
import { Playlist, PlaylistItem } from './types';
jest.mock('./api', () => ({
getPlaylistAPI: () => ({
getPlaylist: jest.fn().mockReturnValue({
interval: '1s',
uid: 'xyz',
name: 'The display',
items: [
{ type: 'dashboard_by_uid', value: 'aaa' },
{ type: 'dashboard_by_uid', value: 'bbb' },
],
} as Playlist),
}),
loadDashboards: (items: PlaylistItem[]) => {
return Promise.resolve(
items.map((v) => ({
...v, // same item with dashboard URLs filled in
dashboards: [{ url: `/url/to/${v.value}` } as unknown as DashboardQueryResult],
}))
);
},
}));
const mockStore = configureMockStore();
setStore(
mockStore({
location: {},
}) as Store
);
function createPlaylistSrv(): PlaylistSrv {
locationService.push('/playlists/foo');
return new PlaylistSrv();
}
const mockWindowLocation = (): [jest.Mock, () => 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
//@ts-ignore
delete window.location;
window.location = {} as Location;
// 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 hrefMock: jest.Mock;
let unmockLocation: () => void;
const initialUrl = 'http://localhost/playlist';
beforeEach(() => {
jest.clearAllMocks();
srv = 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('foo');
for (let i = 0; i < 6; i++) {
srv.next();
}
expect(hrefMock).toHaveBeenCalledTimes(2);
expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
});
it('keeps the refresh counter value after restarting', async () => {
await srv.start('foo');
// 1 complete loop
for (let i = 0; i < 3; i++) {
srv.next();
}
srv.stop();
await srv.start('foo');
// Another 2 loops
for (let i = 0; i < 4; i++) {
srv.next();
}
expect(hrefMock).toHaveBeenCalledTimes(3);
expect(hrefMock).toHaveBeenLastCalledWith(initialUrl);
});
it('Should stop playlist when navigating away', async () => {
await srv.start('foo');
locationService.push('/datasources');
expect(srv.state.isPlaying).toBe(false);
});
it('storeUpdated should not stop playlist when navigating to next dashboard', async () => {
await srv.start('foo');
// eslint-disable-next-line
expect((srv as any).validPlaylistUrl).toBe('/url/to/aaa');
srv.next();
// eslint-disable-next-line
expect((srv as any).validPlaylistUrl).toBe('/url/to/bbb');
expect(srv.state.isPlaying).toBe(true);
});
it('should replace playlist start page in history when starting playlist', async () => {
// Start at playlists page
locationService.push('/playlists');
// Navigate to playlist start page
locationService.push('/playlists/play/foo');
// Start the playlist
await srv.start('foo');
// Get history entries
const history = locationService.getHistory();
const entries = (history as unknown as { entries: Location[] }).entries;
// The current entry should be the first dashboard
expect(entries[entries.length - 1].pathname).toBe('/url/to/aaa');
// The previous entry should be the playlists page, not the start page
expect(entries[entries.length - 2].pathname).toBe('/playlists');
// Verify the start page (/playlists/play/foo) is not in history
const hasStartPage = entries.some((entry: { pathname: string }) => entry.pathname === '/playlists/play/foo');
expect(hasStartPage).toBe(false);
});
});