123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- import { act, render, screen } from '@testing-library/react';
- import React, { Component } from 'react';
- import { Route, Router } from 'react-router-dom';
- import { AppPlugin, PluginType, AppRootProps, NavModelItem } from '@grafana/data';
- import { locationService, setEchoSrv } from '@grafana/runtime';
- import { GrafanaRoute } from 'app/core/navigation/GrafanaRoute';
- import { Echo } from 'app/core/services/echo/Echo';
- import { getMockPlugin } from '../__mocks__/pluginMocks';
- import { getPluginSettings } from '../pluginSettings';
- import { importAppPlugin } from '../plugin_loader';
- import AppRootPage from './AppRootPage';
- jest.mock('../pluginSettings', () => ({
- getPluginSettings: jest.fn(),
- }));
- jest.mock('../plugin_loader', () => ({
- importAppPlugin: jest.fn(),
- }));
- const importAppPluginMock = importAppPlugin as jest.Mock<
- ReturnType<typeof importAppPlugin>,
- Parameters<typeof importAppPlugin>
- >;
- const getPluginSettingsMock = getPluginSettings as jest.Mock<
- ReturnType<typeof getPluginSettings>,
- Parameters<typeof getPluginSettings>
- >;
- class RootComponent extends Component<AppRootProps> {
- static timesMounted = 0;
- componentDidMount() {
- RootComponent.timesMounted += 1;
- const node: NavModelItem = {
- text: 'My Great plugin',
- children: [
- {
- text: 'A page',
- url: '/apage',
- id: 'a',
- },
- {
- text: 'Another page',
- url: '/anotherpage',
- id: 'b',
- },
- ],
- };
- this.props.onNavChanged({
- main: node,
- node,
- });
- }
- render() {
- return <p>my great plugin</p>;
- }
- }
- function renderUnderRouter() {
- const route = { component: AppRootPage };
- locationService.push('/a/my-awesome-plugin');
- render(
- <Router history={locationService.getHistory()}>
- <Route path="/a/:pluginId" exact render={(props) => <GrafanaRoute {...props} route={route as any} />} />
- </Router>
- );
- }
- describe('AppRootPage', () => {
- beforeEach(() => {
- jest.resetAllMocks();
- setEchoSrv(new Echo());
- });
- it('should not mount plugin twice if nav is changed', async () => {
- // reproduces https://github.com/grafana/grafana/pull/28105
- getPluginSettingsMock.mockResolvedValue(
- getMockPlugin({
- type: PluginType.app,
- enabled: true,
- })
- );
- const plugin = new AppPlugin();
- plugin.root = RootComponent;
- importAppPluginMock.mockResolvedValue(plugin);
- renderUnderRouter();
- // check that plugin and nav links were rendered, and plugin is mounted only once
- expect(await screen.findByText('my great plugin')).toBeVisible();
- expect(await screen.findByLabelText('Tab A page')).toBeVisible();
- expect(await screen.findByLabelText('Tab Another page')).toBeVisible();
- expect(RootComponent.timesMounted).toEqual(1);
- });
- it('should not render component if not at plugin path', async () => {
- getPluginSettingsMock.mockResolvedValue(
- getMockPlugin({
- type: PluginType.app,
- enabled: true,
- })
- );
- class RootComponent extends Component<AppRootProps> {
- static timesRendered = 0;
- render() {
- RootComponent.timesRendered += 1;
- return <p>my great component</p>;
- }
- }
- const plugin = new AppPlugin();
- plugin.root = RootComponent;
- importAppPluginMock.mockResolvedValue(plugin);
- renderUnderRouter();
- expect(await screen.findByText('my great component')).toBeVisible();
- // renders the first time
- expect(RootComponent.timesRendered).toEqual(1);
- await act(async () => {
- locationService.push('/foo');
- });
- expect(RootComponent.timesRendered).toEqual(1);
- await act(async () => {
- locationService.push('/a/my-awesome-plugin');
- });
- expect(RootComponent.timesRendered).toEqual(2);
- });
- });
|