mirror of https://github.com/grafana/grafana.git
735 lines
22 KiB
TypeScript
735 lines
22 KiB
TypeScript
import { firstValueFrom } from 'rxjs';
|
|
|
|
import { PluginLoadingStrategy } from '@grafana/data';
|
|
import { config } from '@grafana/runtime';
|
|
|
|
import { isGrafanaDevMode } from '../utils';
|
|
|
|
import { AddedLinksRegistry } from './AddedLinksRegistry';
|
|
import { MSG_CANNOT_REGISTER_READ_ONLY } from './Registry';
|
|
|
|
jest.mock('../utils', () => ({
|
|
...jest.requireActual('../utils'),
|
|
|
|
// Manually set the dev mode to false
|
|
// (to make sure that by default we are testing a production scneario)
|
|
isGrafanaDevMode: jest.fn().mockReturnValue(false),
|
|
}));
|
|
|
|
describe('AddedLinksRegistry', () => {
|
|
const originalApps = config.apps;
|
|
const consoleWarn = jest.fn();
|
|
const pluginId = 'grafana-basic-app';
|
|
const appPluginConfig = {
|
|
id: pluginId,
|
|
path: '',
|
|
version: '',
|
|
preload: false,
|
|
angular: {
|
|
detected: false,
|
|
hideDeprecation: false,
|
|
},
|
|
loadingStrategy: PluginLoadingStrategy.fetch,
|
|
dependencies: {
|
|
grafanaVersion: '8.0.0',
|
|
plugins: [],
|
|
extensions: {
|
|
exposedComponents: [],
|
|
},
|
|
},
|
|
extensions: {
|
|
addedLinks: [],
|
|
addedComponents: [],
|
|
exposedComponents: [],
|
|
extensionPoints: [],
|
|
},
|
|
};
|
|
|
|
beforeEach(() => {
|
|
global.console.warn = consoleWarn;
|
|
consoleWarn.mockReset();
|
|
jest.mocked(isGrafanaDevMode).mockReturnValue(false);
|
|
config.apps = {
|
|
[pluginId]: appPluginConfig,
|
|
};
|
|
});
|
|
|
|
afterEach(() => {
|
|
config.apps = originalApps;
|
|
});
|
|
|
|
it('should return empty registry when no extensions registered', async () => {
|
|
const addedLinksRegistry = new AddedLinksRegistry();
|
|
const observable = addedLinksRegistry.asObservable();
|
|
const registry = await firstValueFrom(observable);
|
|
expect(registry).toEqual({});
|
|
});
|
|
|
|
it('should be possible to register link extensions in the registry', async () => {
|
|
const addedLinksRegistry = new AddedLinksRegistry();
|
|
|
|
addedLinksRegistry.register({
|
|
pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'plugins/myorg-basic-app/start',
|
|
configure: jest.fn().mockImplementation((context) => ({ title: context?.title })),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry = await addedLinksRegistry.getState();
|
|
|
|
expect(registry).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId,
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
'plugins/myorg-basic-app/start': [
|
|
{
|
|
pluginId: pluginId,
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
extensionPointId: 'plugins/myorg-basic-app/start',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
it('should be possible to asynchronously register link extensions for the same placement (different plugins)', async () => {
|
|
const pluginId1 = 'grafana-basic-app';
|
|
const pluginId2 = 'grafana-basic-app2';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
|
|
// Register extensions for the first plugin
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId1,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId1}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry1 = await reactiveRegistry.getState();
|
|
|
|
expect(registry1).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId1,
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId1}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
|
|
// Register extensions for the second plugin to a different placement
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId2,
|
|
configs: [
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId2}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry2 = await reactiveRegistry.getState();
|
|
|
|
expect(registry2).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId1,
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId1}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
{
|
|
pluginId: pluginId2,
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId2}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('should be possible to asynchronously register link extensions for a different placement (different plugin)', async () => {
|
|
const pluginId1 = 'grafana-basic-app';
|
|
const pluginId2 = 'grafana-basic-app2';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
|
|
// Register extensions for the first plugin
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId1,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId1}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry1 = await reactiveRegistry.getState();
|
|
|
|
expect(registry1).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId1,
|
|
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId1}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
|
|
// Register extensions for the second plugin to a different placement
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId2,
|
|
configs: [
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId2}/declare-incident`,
|
|
targets: 'plugins/myorg-basic-app/start',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry2 = await reactiveRegistry.getState();
|
|
|
|
expect(registry2).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId1,
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId1}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
'plugins/myorg-basic-app/start': [
|
|
{
|
|
pluginId: pluginId2,
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId2}/declare-incident`,
|
|
extensionPointId: 'plugins/myorg-basic-app/start',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('should be possible to asynchronously register link extensions for the same placement (same plugin)', async () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
|
|
// Register extensions for the first extension point
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident-1`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
// Register extensions to a different extension point
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident-2`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry2 = await reactiveRegistry.getState();
|
|
|
|
expect(registry2).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId,
|
|
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident-1`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
{
|
|
pluginId: pluginId,
|
|
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident-2`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('should be possible to asynchronously register link extensions for a different placement (same plugin)', async () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
|
|
// Register extensions for the first extension point
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
// Register extensions to a different extension point
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'plugins/myorg-basic-app/start',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
const registry2 = await reactiveRegistry.getState();
|
|
|
|
expect(registry2).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId,
|
|
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
'plugins/myorg-basic-app/start': [
|
|
{
|
|
pluginId: pluginId,
|
|
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
extensionPointId: 'plugins/myorg-basic-app/start',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('should notify subscribers when the registry changes', async () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
const observable = reactiveRegistry.asObservable();
|
|
const subscribeCallback = jest.fn();
|
|
|
|
observable.subscribe(subscribeCallback);
|
|
|
|
// Register extensions for the first plugin
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(2);
|
|
|
|
// Register extensions for the first plugin
|
|
reactiveRegistry.register({
|
|
pluginId: 'another-plugin',
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/another-plugin/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(3);
|
|
|
|
const registry = subscribeCallback.mock.calls[2][0];
|
|
|
|
expect(registry).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId,
|
|
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
{
|
|
pluginId: 'another-plugin',
|
|
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/another-plugin/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('should give the last version of the registry for new subscribers', async () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
const observable = reactiveRegistry.asObservable();
|
|
const subscribeCallback = jest.fn();
|
|
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
observable.subscribe(subscribeCallback);
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(1);
|
|
|
|
const registry = subscribeCallback.mock.calls[0][0];
|
|
|
|
expect(registry).toEqual({
|
|
'grafana/dashboard/panel/menu': [
|
|
{
|
|
pluginId: pluginId,
|
|
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
extensionPointId: 'grafana/dashboard/panel/menu',
|
|
configure: expect.any(Function),
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
it('should not register a link extension if it has an invalid configure() function', () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
const observable = reactiveRegistry.asObservable();
|
|
const subscribeCallback = jest.fn();
|
|
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
//@ts-ignore
|
|
configure: '...',
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(consoleWarn).toHaveBeenCalled();
|
|
|
|
observable.subscribe(subscribeCallback);
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(1);
|
|
|
|
const registry = subscribeCallback.mock.calls[0][0];
|
|
expect(registry).toEqual({});
|
|
});
|
|
|
|
it('should not register a link extension if it has invalid properties (empty title / description)', () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
const observable = reactiveRegistry.asObservable();
|
|
const subscribeCallback = jest.fn();
|
|
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: '',
|
|
description: '',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(consoleWarn).toHaveBeenCalled();
|
|
|
|
observable.subscribe(subscribeCallback);
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(1);
|
|
|
|
const registry = subscribeCallback.mock.calls[0][0];
|
|
expect(registry).toEqual({});
|
|
});
|
|
|
|
it('should not register link extensions with invalid path configured', () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const reactiveRegistry = new AddedLinksRegistry();
|
|
const observable = reactiveRegistry.asObservable();
|
|
const subscribeCallback = jest.fn();
|
|
|
|
reactiveRegistry.register({
|
|
pluginId: pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Title 1',
|
|
description: 'Description 1',
|
|
path: `/a/another-plugin/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(consoleWarn).toHaveBeenCalled();
|
|
|
|
observable.subscribe(subscribeCallback);
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(1);
|
|
|
|
const registry = subscribeCallback.mock.calls[0][0];
|
|
expect(registry).toEqual({});
|
|
});
|
|
|
|
it('should not be possible to register a link on a read-only registry', async () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const registry = new AddedLinksRegistry();
|
|
const readOnlyRegistry = registry.readOnly();
|
|
|
|
expect(() => {
|
|
readOnlyRegistry.register({
|
|
pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'plugins/myorg-basic-app/start',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
}).toThrow(MSG_CANNOT_REGISTER_READ_ONLY);
|
|
|
|
const currentState = await readOnlyRegistry.getState();
|
|
expect(Object.keys(currentState)).toHaveLength(0);
|
|
});
|
|
|
|
it('should pass down fresh registrations to the read-only version of the registry', async () => {
|
|
const pluginId = 'grafana-basic-app';
|
|
const registry = new AddedLinksRegistry();
|
|
const readOnlyRegistry = registry.readOnly();
|
|
const subscribeCallback = jest.fn();
|
|
let readOnlyState;
|
|
|
|
// Should have no extensions registered in the beginning
|
|
readOnlyState = await readOnlyRegistry.getState();
|
|
expect(Object.keys(readOnlyState)).toHaveLength(0);
|
|
|
|
readOnlyRegistry.asObservable().subscribe(subscribeCallback);
|
|
|
|
// Register an extension to the original (writable) registry
|
|
registry.register({
|
|
pluginId,
|
|
configs: [
|
|
{
|
|
title: 'Link 2',
|
|
description: 'Link 2 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'plugins/myorg-basic-app/start',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
},
|
|
],
|
|
});
|
|
|
|
// The read-only registry should have received the new extension
|
|
readOnlyState = await readOnlyRegistry.getState();
|
|
expect(Object.keys(readOnlyState)).toHaveLength(1);
|
|
|
|
expect(subscribeCallback).toHaveBeenCalledTimes(2);
|
|
expect(Object.keys(subscribeCallback.mock.calls[1][0])).toEqual(['plugins/myorg-basic-app/start']);
|
|
});
|
|
|
|
it('should not register a link added by a plugin in dev-mode if the meta-info is missing from the plugin.json', async () => {
|
|
// Enabling dev mode
|
|
jest.mocked(isGrafanaDevMode).mockReturnValue(true);
|
|
|
|
const registry = new AddedLinksRegistry();
|
|
const linkConfig = {
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
};
|
|
|
|
// Make sure that the meta-info is empty
|
|
config.apps[pluginId].extensions.addedLinks = [];
|
|
|
|
registry.register({
|
|
pluginId,
|
|
configs: [linkConfig],
|
|
});
|
|
|
|
const currentState = await registry.getState();
|
|
|
|
expect(Object.keys(currentState)).toHaveLength(0);
|
|
expect(consoleWarn).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should register a link added by core Grafana in dev-mode even if the meta-info is missing', async () => {
|
|
// Enabling dev mode
|
|
jest.mocked(isGrafanaDevMode).mockReturnValue(true);
|
|
|
|
const registry = new AddedLinksRegistry();
|
|
const linkConfig = {
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/grafana/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
};
|
|
|
|
registry.register({
|
|
pluginId: 'grafana',
|
|
configs: [linkConfig],
|
|
});
|
|
|
|
const currentState = await registry.getState();
|
|
|
|
expect(Object.keys(currentState)).toHaveLength(1);
|
|
expect(consoleWarn).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should register a link added by a plugin in production mode even if the meta-info is missing', async () => {
|
|
// Production mode
|
|
jest.mocked(isGrafanaDevMode).mockReturnValue(false);
|
|
|
|
const registry = new AddedLinksRegistry();
|
|
const linkConfig = {
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: 'grafana/dashboard/panel/menu',
|
|
configure: jest.fn().mockReturnValue({}),
|
|
};
|
|
|
|
// Make sure that the meta-info is empty
|
|
config.apps[pluginId].extensions.addedLinks = [];
|
|
|
|
registry.register({
|
|
pluginId,
|
|
configs: [linkConfig],
|
|
});
|
|
|
|
const currentState = await registry.getState();
|
|
|
|
expect(Object.keys(currentState)).toHaveLength(1);
|
|
expect(consoleWarn).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should register a link added by a plugin in dev-mode if the meta-info is present', async () => {
|
|
// Enabling dev mode
|
|
jest.mocked(isGrafanaDevMode).mockReturnValue(true);
|
|
|
|
const registry = new AddedLinksRegistry();
|
|
const linkConfig = {
|
|
title: 'Link 1',
|
|
description: 'Link 1 description',
|
|
path: `/a/${pluginId}/declare-incident`,
|
|
targets: ['grafana/dashboard/panel/menu'],
|
|
configure: jest.fn().mockReturnValue({}),
|
|
};
|
|
|
|
// Make sure that the meta-info is empty
|
|
config.apps[pluginId].extensions.addedLinks = [linkConfig];
|
|
|
|
registry.register({
|
|
pluginId,
|
|
configs: [linkConfig],
|
|
});
|
|
|
|
const currentState = await registry.getState();
|
|
|
|
expect(Object.keys(currentState)).toHaveLength(1);
|
|
expect(consoleWarn).not.toHaveBeenCalled();
|
|
});
|
|
});
|