Files
grafana/public/app/features/plugins/components/AppRootPage.test.tsx
Levente Balogh 35c2c95fdc Plugins: remove deprecated code (components) (#41686)
* refactor(plugins): use routes specific to the new plugins/admin

* refactor(plugins): remove unused pages (PluginList, PluginItem)

* refactor(plugins): remove PluginPage

* refactor(plugins): remove UpdatePluginModal

* refactor(plugins): move AppConfigWrapper under plugins/admin

* refactor(plugins): move PluginDashboards under plugins/admin

* refactor(plugins): rename the "specs" folder to "tests"

* refactor(plugins): move test files to /tests folder

* refactor(plugins): move AppRootPage into a /components folder

* refactor(plugins): move PluginsErrorsInfo into a /plugins folder

* refactor(plugins): move PluginSettingsCache into a /components folder

* refactor(plugins): move PluginStateInfo into a /plugins folder

* refactor(plugins): move AppRootPage.test.tsx next to the tested component

* refactor(plugins): remove old snapshot tests

* fix(plugins): fix tests

* refactor(plugins/admin): move & rename PluginSettingsCache

* fix(plugins): fix a few rebase issues

* Plugins: remove deprecated code (state handling) (#41739)

* refactor(plugins): use the plugins/admin reducer only

* refactor(plugins): remove tests for the deprecated plugins reducer

* refactor(plugins): remove tests for the deprecated plugins selectors

* refactor(plugins/state): add a short comment note to selectors

* feat(plugins/state): add a selector for selecting errors

* feat(plugins/state): add a hook for getting plugin errors

* refactor(plugins): udpate the PluginsErrorsInfo component to use the new state selectors

* refactor(plugins/state): remove the old (deprecated) selectors

* refactor(plugins/state): use the new actions under /admin

* refactor(plugins/state): remove old (deprecated) reducers and actions

* refactor(plugins): update component definition

* fix(plugins): remove unnecessary {children} prop for PluginsErrorsInfo

* Plugins: show / hide install controls based on the `pluginAdminEnabled` flag (#41749)

* docs(plugins): update documentation for the `plugin_admin_enabled` flag

* refactor(InstallControls): move the main component to a named module

* feat(plugins): use the `pluginAdminEnable` flag to hide / show install controls in the UI

* test(plugins): add tests for enabling/disabling install controls
2021-11-19 13:42:26 +01:00

142 lines
3.7 KiB
TypeScript

import { act, render, screen } from '@testing-library/react';
import React, { Component } from 'react';
import AppRootPage from './AppRootPage';
import { getPluginSettings } from '../pluginSettings';
import { importAppPlugin } from '../plugin_loader';
import { getMockPlugin } from '../__mocks__/pluginMocks';
import { AppPlugin, PluginType, AppRootProps, NavModelItem } from '@grafana/data';
import { Route, Router } from 'react-router-dom';
import { locationService, setEchoSrv } from '@grafana/runtime';
import { GrafanaRoute } from 'app/core/navigation/GrafanaRoute';
import { Echo } from 'app/core/services/echo/Echo';
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);
});
});