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/dashboard-scene/scene/NavToolbarActions.test.tsx

232 lines
9.5 KiB

import { screen, render, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TestProvider } from 'test/helpers/TestProvider';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
import { selectors } from '@grafana/e2e-selectors';
import { LocationServiceProvider, config, locationService } from '@grafana/runtime';
import { SceneQueryRunner, SceneTimeRange, UrlSyncContextProvider, VizPanel } from '@grafana/scenes';
import { playlistSrv } from 'app/features/playlist/PlaylistSrv';
import { DashboardMeta } from 'app/types';
import { buildPanelEditScene } from '../panel-edit/PanelEditor';
import { DashboardScene } from './DashboardScene';
import { ToolbarActions } from './NavToolbarActions';
import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager';
jest.mock('app/features/playlist/PlaylistSrv', () => ({
playlistSrv: {
useState: jest.fn().mockReturnValue({ isPlaying: false }),
setState: jest.fn(),
isPlaying: true,
start: jest.fn(),
next: jest.fn(),
prev: jest.fn(),
stop: jest.fn(),
},
}));
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getDataSourceSrv: () => ({
get: jest.fn(),
getInstanceSettings: jest.fn().mockReturnValue({
uid: 'datasource-uid',
name: 'datasource-name',
}),
}),
}));
describe('NavToolbarActions', () => {
describe('Given an already saved dashboard', () => {
it('Should show correct buttons when not in editing', async () => {
setup();
expect(screen.queryByText('Save dashboard')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Add')).not.toBeInTheDocument();
expect(await screen.findByText('Edit')).toBeInTheDocument();
expect(await screen.findByText('Share')).toBeInTheDocument();
});
it('Should show the correct buttons when playing a playlist', async () => {
jest.mocked(playlistSrv).useState.mockReturnValueOnce({ isPlaying: true });
setup();
expect(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.prev)).toBeInTheDocument();
expect(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.stop)).toBeInTheDocument();
expect(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.next)).toBeInTheDocument();
expect(screen.queryByText('Edit')).not.toBeInTheDocument();
expect(screen.queryByText('Share')).not.toBeInTheDocument();
});
it('Should call the playlist srv when using playlist controls', async () => {
jest.mocked(playlistSrv).useState.mockReturnValueOnce({ isPlaying: true });
setup();
// Previous dashboard
expect(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.prev)).toBeInTheDocument();
await userEvent.click(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.prev));
expect(playlistSrv.prev).toHaveBeenCalledTimes(1);
// Next dashboard
expect(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.next)).toBeInTheDocument();
await userEvent.click(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.next));
expect(playlistSrv.next).toHaveBeenCalledTimes(1);
// Stop playlist
expect(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.stop)).toBeInTheDocument();
await userEvent.click(await screen.findByTestId(selectors.pages.Dashboard.DashNav.playlistControls.stop));
expect(playlistSrv.stop).toHaveBeenCalledTimes(1);
});
it('Should hide the playlist controls when it is not playing', async () => {
setup();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.prev)).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.stop)).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.next)).not.toBeInTheDocument();
});
it('Should show correct buttons when editing', async () => {
setup();
await userEvent.click(await screen.findByText('Edit'));
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(await screen.findByText('Exit edit')).toBeInTheDocument();
expect(await screen.findByText('Add')).toBeInTheDocument();
expect(screen.queryByText('Edit')).not.toBeInTheDocument();
expect(screen.queryByText('Share')).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.prev)).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.stop)).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.next)).not.toBeInTheDocument();
});
it('Should show correct buttons when in settings menu', async () => {
setup();
await userEvent.click(await screen.findByText('Edit'));
await userEvent.click(await screen.findByText('Settings'));
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(await screen.findByText('Back to dashboard')).toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.prev)).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.stop)).not.toBeInTheDocument();
expect(screen.queryByText(selectors.pages.Dashboard.DashNav.playlistControls.next)).not.toBeInTheDocument();
});
it('Should show correct buttons when editing a new panel', async () => {
const { dashboard } = setup();
await act(() => {
dashboard.onEnterEditMode();
const panel = dashboard.state.body.getVizPanels()[0];
dashboard.setState({ editPanel: buildPanelEditScene(panel, true) });
});
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(await screen.findByText('Discard panel')).toBeInTheDocument();
expect(await screen.findByText('Back to dashboard')).toBeInTheDocument();
});
it('Should show correct buttons when editing an existing panel', async () => {
const { dashboard } = setup();
await act(() => {
dashboard.onEnterEditMode();
const panel = dashboard.state.body.getVizPanels()[0];
dashboard.setState({ editPanel: buildPanelEditScene(panel) });
});
expect(await screen.findByText('Save dashboard')).toBeInTheDocument();
expect(await screen.findByText('Discard panel changes')).toBeInTheDocument();
expect(await screen.findByText('Back to dashboard')).toBeInTheDocument();
});
});
describe('Given new sharing button', () => {
it('Should show old share button when newDashboardSharingComponent FF is disabled', async () => {
setup();
expect(await screen.findByText('Share')).toBeInTheDocument();
const newShareButton = screen.queryByTestId(selectors.pages.Dashboard.DashNav.newShareButton.container);
expect(newShareButton).not.toBeInTheDocument();
const newExportButton = screen.queryByTestId(selectors.pages.Dashboard.DashNav.NewExportButton.container);
expect(newExportButton).not.toBeInTheDocument();
});
it('Should show new share button when newDashboardSharingComponent FF is enabled', async () => {
config.featureToggles.newDashboardSharingComponent = true;
setup();
expect(await screen.queryByTestId(selectors.pages.Dashboard.DashNav.shareButton)).not.toBeInTheDocument();
const newShareButton = screen.getByTestId(selectors.pages.Dashboard.DashNav.newShareButton.container);
expect(newShareButton).toBeInTheDocument();
});
it('Should show new export button when newDashboardSharingComponent FF is enabled', async () => {
config.featureToggles.newDashboardSharingComponent = true;
setup();
const newExportButton = screen.getByTestId(selectors.pages.Dashboard.DashNav.NewExportButton.container);
expect(newExportButton).toBeInTheDocument();
});
});
describe('Snapshot', () => {
it('should show link button when is a snapshot', () => {
setup({
isSnapshot: true,
});
expect(screen.queryByTestId('button-snapshot')).toBeInTheDocument();
});
});
});
function setup(meta?: DashboardMeta) {
const dashboard = new DashboardScene({
$timeRange: new SceneTimeRange({ from: 'now-6h', to: 'now' }),
meta: {
canEdit: true,
isNew: false,
canMakeEditable: true,
canSave: true,
canShare: true,
canStar: true,
canAdmin: true,
canDelete: true,
...meta,
},
title: 'hello',
uid: 'dash-1',
body: DefaultGridLayoutManager.fromVizPanels([
new VizPanel({
title: 'Panel A',
key: 'panel-1',
pluginId: 'table',
$data: new SceneQueryRunner({ key: 'data-query-runner', queries: [{ refId: 'A' }] }),
}),
new VizPanel({
title: 'Panel B',
key: 'panel-2',
pluginId: 'table',
}),
]),
});
const context = getGrafanaContextMock();
locationService.push('/');
render(
<TestProvider grafanaContext={context}>
<LocationServiceProvider service={locationService}>
<UrlSyncContextProvider scene={dashboard}>
<ToolbarActions dashboard={dashboard} />
</UrlSyncContextProvider>
</LocationServiceProvider>
</TestProvider>
);
const actions = context.chrome.state.getValue().actions;
return { dashboard, actions };
}