grafana/public/app/features/dashboard/containers/PublicDashboardPage.test.tsx
Dominik Prokop 83199c4bf5
Dashboard schema: Review and mature timezone property (#62090)
* Review and mature timezone property of Dashboard kind

* Update timezone type
2023-01-27 07:13:33 -08:00

244 lines
7.4 KiB
TypeScript

import { render, RenderResult, screen } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import { useEffectOnce } from 'react-use';
import { AutoSizerProps } from 'react-virtualized-auto-sizer';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
import { locationService } from '@grafana/runtime';
import { Dashboard, DashboardCursorSync } from '@grafana/schema/src';
import { GrafanaContext } from 'app/core/context/GrafanaContext';
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
import { DashboardInitPhase, DashboardMeta, DashboardRoutes } from 'app/types';
import * as appTypes from 'app/types';
import { SafeDynamicImport } from '../../../core/components/DynamicImports/SafeDynamicImport';
import { configureStore } from '../../../store/configureStore';
import { Props as LazyLoaderProps } from '../dashgrid/LazyLoader';
import { DashboardModel } from '../state';
import { initDashboard } from '../state/initDashboard';
import PublicDashboardPage, { Props } from './PublicDashboardPage';
jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => {
const LazyLoader = ({ children, onLoad }: Pick<LazyLoaderProps, 'children' | 'onLoad'>) => {
useEffectOnce(() => {
onLoad?.();
});
return <>{typeof children === 'function' ? children({ isInView: true }) : children}</>;
};
return { LazyLoader };
});
jest.mock('react-virtualized-auto-sizer', () => {
// // // The size of the children need to be small enough to be outside the view.
// // // So it does not trigger the query to be run by the PanelQueryRunner.
return ({ children }: AutoSizerProps) => children({ height: 1, width: 1 });
});
jest.mock('app/features/dashboard/state/initDashboard', () => ({
...jest.requireActual('app/features/dashboard/state/initDashboard'),
initDashboard: jest.fn(),
}));
jest.mock('app/types', () => ({
...jest.requireActual('app/types'),
useDispatch: () => jest.fn(),
}));
interface ScenarioContext {
mount: () => void;
rerender: ({
propOverrides,
newState,
}: {
propOverrides?: Partial<Props>;
newState?: Partial<appTypes.StoreState>;
}) => void;
setup: (fn: () => void) => void;
}
const renderWithProvider = ({
props,
initialState,
}: {
props: Props;
initialState?: Partial<appTypes.StoreState>;
}): RenderResult => {
const context = getGrafanaContextMock();
const store = configureStore(initialState);
return render(
<GrafanaContext.Provider value={context}>
<Provider store={store}>
<Router history={locationService.getHistory()}>
<PublicDashboardPage {...props} />
</Router>
</Provider>
</GrafanaContext.Provider>
);
};
const selectors = e2eSelectors.components;
const getTestDashboard = (overrides?: Partial<Dashboard>, metaOverrides?: Partial<DashboardMeta>): DashboardModel => {
const data: Dashboard = Object.assign(
{
title: 'My dashboard',
revision: 1,
editable: false,
graphTooltip: DashboardCursorSync.Off,
schemaVersion: 1,
style: 'dark',
timepicker: { hidden: true },
timezone: '',
panels: [
{
id: 1,
type: 'timeseries',
title: 'My panel title',
gridPos: { x: 0, y: 0, w: 1, h: 1 },
},
],
},
overrides
);
return new DashboardModel(data, metaOverrides);
};
function dashboardPageScenario(description: string, scenarioFn: (ctx: ScenarioContext) => void) {
describe(description, () => {
let setupFn: () => void;
const ctx: ScenarioContext = {
setup: (fn) => {
setupFn = fn;
},
mount: () => {
const props: Props = {
...getRouteComponentProps({
match: { params: { accessToken: 'an-access-token' }, isExact: true, url: '', path: '' },
route: {
routeName: DashboardRoutes.Public,
path: '/public-dashboards/:accessToken',
component: SafeDynamicImport(
() =>
import(
/* webpackChunkName: "PublicDashboardPage"*/ 'app/features/dashboard/containers/PublicDashboardPage'
)
),
},
}),
};
const { rerender } = renderWithProvider({ props });
ctx.rerender = ({
propsOverride,
newState,
}: {
propsOverride?: Partial<Props>;
newState?: Partial<appTypes.StoreState>;
}) => {
Object.assign(props, propsOverride);
const context = getGrafanaContextMock();
const store = configureStore(newState);
rerender(
<GrafanaContext.Provider value={context}>
<Provider store={store}>
<Router history={locationService.getHistory()}>
<PublicDashboardPage {...props} />
</Router>
</Provider>
</GrafanaContext.Provider>
);
};
},
rerender: () => {},
};
beforeEach(() => {
setupFn();
});
scenarioFn(ctx);
});
}
describe('PublicDashboardPage', () => {
dashboardPageScenario('Given initial state', (ctx) => {
ctx.setup(() => {
ctx.mount();
});
it('Should call initDashboard on mount', () => {
expect(initDashboard).toBeCalledWith({
fixUrl: false,
accessToken: 'an-access-token',
routeName: 'public-dashboard',
keybindingSrv: expect.anything(),
});
});
});
dashboardPageScenario('Given a simple public dashboard', (ctx) => {
ctx.setup(() => {
ctx.mount();
ctx.rerender({
newState: {
dashboard: {
getModel: getTestDashboard,
initError: null,
initPhase: DashboardInitPhase.Completed,
permissions: [],
},
},
});
});
it('Should render panels', () => {
expect(screen.getByText('My panel title')).toBeInTheDocument();
});
it('Should update title', () => {
expect(document.title).toBe('My dashboard - Grafana');
});
it('Should not render neither time range nor refresh picker buttons', () => {
expect(screen.queryByTestId(selectors.TimePicker.openButton)).not.toBeInTheDocument();
expect(screen.queryByTestId(selectors.RefreshPicker.runButtonV2)).not.toBeInTheDocument();
expect(screen.queryByTestId(selectors.RefreshPicker.intervalButtonV2)).not.toBeInTheDocument();
});
});
dashboardPageScenario('Given a public dashboard with time range enabled', (ctx) => {
ctx.setup(() => {
ctx.mount();
ctx.rerender({
newState: {
dashboard: {
getModel: () =>
getTestDashboard({
timepicker: { hidden: false, collapse: false, enable: true, refresh_intervals: [], time_options: [] },
}),
initError: null,
initPhase: DashboardInitPhase.Completed,
permissions: [],
},
},
});
});
it('Should render time range and refresh picker buttons', () => {
expect(screen.getByTestId(selectors.TimePicker.openButton)).toBeInTheDocument();
expect(screen.getByTestId(selectors.RefreshPicker.runButtonV2)).toBeInTheDocument();
expect(screen.getByTestId(selectors.RefreshPicker.intervalButtonV2)).toBeInTheDocument();
});
});
});