mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard: Fix navigation from one SoloPanelPage to another one (#28578)
* Add test for SoloPanelPage.tsx * Fix navigation from one SoloPanelPage to another one The panel did not update because it assumed that the dashboard was already fully loaded.
This commit is contained in:
parent
00508295d1
commit
645412f04b
142
public/app/features/dashboard/containers/SoloPanelPage.test.tsx
Normal file
142
public/app/features/dashboard/containers/SoloPanelPage.test.tsx
Normal file
@ -0,0 +1,142 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { SoloPanelPage, Props } from './SoloPanelPage';
|
||||
import { Props as DashboardPanelProps } from '../dashgrid/DashboardPanel';
|
||||
import { DashboardModel } from '../state';
|
||||
import { DashboardRouteInfo } from 'app/types';
|
||||
|
||||
jest.mock('app/features/dashboard/components/DashboardSettings/SettingsCtrl', () => ({}));
|
||||
jest.mock('app/features/dashboard/dashgrid/DashboardPanel', () => {
|
||||
class DashboardPanel extends React.Component<DashboardPanelProps> {
|
||||
render() {
|
||||
// In this test we only check whether a new panel has arrived in the props
|
||||
return <>{this.props.panel?.title}</>;
|
||||
}
|
||||
}
|
||||
|
||||
return { DashboardPanel };
|
||||
});
|
||||
|
||||
interface ScenarioContext {
|
||||
dashboard?: DashboardModel | null;
|
||||
secondaryDashboard?: DashboardModel | null;
|
||||
setDashboard: (overrides?: any, metaOverrides?: any) => void;
|
||||
setSecondaryDashboard: (overrides?: any, metaOverrides?: any) => void;
|
||||
mount: (propOverrides?: Partial<Props>) => void;
|
||||
rerender: (propOverrides?: Partial<Props>) => void;
|
||||
setup: (fn: () => void) => void;
|
||||
}
|
||||
|
||||
function getTestDashboard(overrides?: any, metaOverrides?: any): DashboardModel {
|
||||
const data = Object.assign(
|
||||
{
|
||||
title: 'My dashboard',
|
||||
panels: [
|
||||
{
|
||||
id: 1,
|
||||
type: 'graph',
|
||||
title: 'My graph',
|
||||
gridPos: { x: 0, y: 0, w: 1, h: 1 },
|
||||
},
|
||||
],
|
||||
},
|
||||
overrides
|
||||
);
|
||||
|
||||
const meta = Object.assign({ canSave: true, canEdit: true }, metaOverrides);
|
||||
return new DashboardModel(data, meta);
|
||||
}
|
||||
|
||||
function soloPanelPageScenario(description: string, scenarioFn: (ctx: ScenarioContext) => void) {
|
||||
describe(description, () => {
|
||||
let setupFn: () => void;
|
||||
|
||||
const ctx: ScenarioContext = {
|
||||
setup: fn => {
|
||||
setupFn = fn;
|
||||
},
|
||||
setDashboard: (overrides?: any, metaOverrides?: any) => {
|
||||
ctx.dashboard = getTestDashboard(overrides, metaOverrides);
|
||||
},
|
||||
setSecondaryDashboard: (overrides?: any, metaOverrides?: any) => {
|
||||
ctx.secondaryDashboard = getTestDashboard(overrides, metaOverrides);
|
||||
},
|
||||
mount: (propOverrides?: Partial<Props>) => {
|
||||
const props: Props = {
|
||||
urlSlug: 'my-dash',
|
||||
$scope: {},
|
||||
urlUid: '11',
|
||||
urlPanelId: '1',
|
||||
$injector: {},
|
||||
routeInfo: DashboardRouteInfo.Normal,
|
||||
initDashboard: jest.fn(),
|
||||
dashboard: null,
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
ctx.dashboard = props.dashboard;
|
||||
let { rerender } = render(<SoloPanelPage {...props} />);
|
||||
// prop updates will be submitted by rerendering the same component with different props
|
||||
ctx.rerender = (newProps: Partial<Props>) => {
|
||||
Object.assign(props, newProps);
|
||||
rerender(<SoloPanelPage {...props} />);
|
||||
};
|
||||
},
|
||||
rerender: () => {
|
||||
// will be replaced while mount() is called
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
setupFn();
|
||||
});
|
||||
|
||||
scenarioFn(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
describe('SoloPanelPage', () => {
|
||||
soloPanelPageScenario('Given initial state', ctx => {
|
||||
ctx.setup(() => {
|
||||
ctx.mount();
|
||||
});
|
||||
|
||||
it('Should render nothing', () => {
|
||||
expect(screen.queryByText(/Loading/)).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
soloPanelPageScenario('Dashboard init completed ', ctx => {
|
||||
ctx.setup(() => {
|
||||
ctx.mount();
|
||||
ctx.setDashboard();
|
||||
expect(ctx.dashboard).not.toBeNull();
|
||||
// the componentDidMount will change the dashboard prop to the new dashboard
|
||||
// emulate this by rerendering with new props
|
||||
ctx.rerender({ dashboard: ctx.dashboard });
|
||||
});
|
||||
|
||||
it('Should render dashboard grid', async () => {
|
||||
// check if the panel title has arrived in the DashboardPanel mock
|
||||
expect(screen.queryByText(/My graph/)).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
soloPanelPageScenario('When user navigates to other SoloPanelPage', ctx => {
|
||||
ctx.setup(() => {
|
||||
ctx.mount();
|
||||
ctx.setDashboard({ uid: 1, panels: [{ id: 1, type: 'graph', title: 'Panel 1' }] });
|
||||
ctx.setSecondaryDashboard({ uid: 2, panels: [{ id: 1, type: 'graph', title: 'Panel 2' }] });
|
||||
});
|
||||
|
||||
it('Should show other graph', () => {
|
||||
// check that the title in the DashboardPanel has changed
|
||||
ctx.rerender({ dashboard: ctx.dashboard });
|
||||
expect(screen.queryByText(/Panel 1/)).not.toBeNull();
|
||||
ctx.rerender({ dashboard: ctx.secondaryDashboard });
|
||||
expect(screen.queryByText(/Panel 1/)).toBeNull();
|
||||
expect(screen.queryByText(/Panel 2/)).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
@ -13,7 +13,7 @@ import { initDashboard } from '../state/initDashboard';
|
||||
import { StoreState, DashboardRouteInfo } from 'app/types';
|
||||
import { PanelModel, DashboardModel } from 'app/features/dashboard/state';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
urlPanelId: string;
|
||||
urlUid?: string;
|
||||
urlSlug?: string;
|
||||
@ -25,7 +25,7 @@ interface Props {
|
||||
dashboard: DashboardModel | null;
|
||||
}
|
||||
|
||||
interface State {
|
||||
export interface State {
|
||||
panel: PanelModel | null;
|
||||
notFound: boolean;
|
||||
}
|
||||
@ -57,8 +57,8 @@ export class SoloPanelPage extends Component<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
// we just got the dashboard!
|
||||
if (!prevProps.dashboard) {
|
||||
// we just got a new dashboard
|
||||
if (!prevProps.dashboard || prevProps.dashboard.uid !== dashboard.uid) {
|
||||
const panelId = parseInt(urlPanelId, 10);
|
||||
|
||||
// need to expand parent row if this panel is inside a row
|
||||
|
Loading…
Reference in New Issue
Block a user