Files
grafana/public/app/features/dashboard-scene/scene/ScopesScene.test.tsx
Carl Bergquist b214b07695 Scopes: Name relationship objects *binding (#84955)
Signed-off-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Bogdan Matei <bogdan.matei@grafana.com>
2024-03-26 15:52:12 +01:00

262 lines
7.0 KiB
TypeScript

import { waitFor } from '@testing-library/react';
import { config } from '@grafana/runtime';
import {
behaviors,
sceneGraph,
SceneGridItem,
SceneGridLayout,
SceneQueryRunner,
SceneTimeRange,
VizPanel,
} from '@grafana/scenes';
import { DashboardControls } from './DashboardControls';
import { DashboardScene } from './DashboardScene';
import { ScopesDashboardsScene } from './ScopesDashboardsScene';
import { ScopesFiltersScene } from './ScopesFiltersScene';
import { ScopesScene } from './ScopesScene';
const dashboardsMocks = {
dashboard1: {
uid: 'dashboard1',
title: 'Dashboard 1',
url: '/d/dashboard1',
},
dashboard2: {
uid: 'dashboard2',
title: 'Dashboard 2',
url: '/d/dashboard2',
},
dashboard3: {
uid: 'dashboard3',
title: 'Dashboard 3',
url: '/d/dashboard3',
},
};
const scopesMocks = {
scope1: {
uid: 'scope1',
title: 'Scope 1',
type: 'Type 1',
description: 'Description 1',
category: 'Category 1',
filters: [
{ key: 'a-key', operator: '=', value: 'a-value' },
{ key: 'b-key', operator: '!=', value: 'b-value' },
],
dashboards: [dashboardsMocks.dashboard1, dashboardsMocks.dashboard2, dashboardsMocks.dashboard3],
},
scope2: {
uid: 'scope2',
title: 'Scope 2',
type: 'Type 2',
description: 'Description 2',
category: 'Category 2',
filters: [{ key: 'c-key', operator: '!=', value: 'c-value' }],
dashboards: [dashboardsMocks.dashboard3],
},
scope3: {
uid: 'scope3',
title: 'Scope 3',
type: 'Type 1',
description: 'Description 3',
category: 'Category 1',
filters: [{ key: 'd-key', operator: '=', value: 'd-value' }],
dashboards: [dashboardsMocks.dashboard1, dashboardsMocks.dashboard2],
},
};
jest.mock('@grafana/runtime', () => ({
__esModule: true,
...jest.requireActual('@grafana/runtime'),
getBackendSrv: () => ({
get: jest.fn().mockImplementation((url: string) => {
if (url === '/apis/scope.grafana.app/v0alpha1/scopes') {
return {
items: Object.values(scopesMocks).map((scope) => ({
metadata: { uid: scope.uid },
spec: {
title: scope.title,
type: scope.type,
description: scope.description,
category: scope.category,
filters: scope.filters,
},
})),
};
}
if (url === '/apis/scope.grafana.app/v0alpha1/scopedashboards') {
return {
items: Object.values(scopesMocks).map((scope) => ({
spec: {
dashboards: scope.dashboards.map((dashboard) => dashboard.uid),
scope: scope.uid,
},
})),
};
}
if (url.startsWith('/api/dashboards/uid/')) {
const uid = url.split('/').pop();
if (!uid) {
return {};
}
const dashboard = Object.values(dashboardsMocks).find((dashboard) => dashboard.uid === uid);
if (!dashboard) {
return {};
}
return {
dashboard: {
title: dashboard.title,
uid,
},
meta: {
url: dashboard.url,
},
};
}
return {};
}),
}),
}));
describe('ScopesScene', () => {
describe('Feature flag off', () => {
beforeAll(() => {
config.featureToggles.scopeFilters = false;
});
it('Does not initialize', () => {
const dashboardScene = buildTestScene();
dashboardScene.activate();
const scopesScene = dashboardScene.state.scopes;
expect(scopesScene).toBeUndefined();
});
});
describe('Feature flag on', () => {
let dashboardScene: DashboardScene;
let scopesScene: ScopesScene;
let filtersScene: ScopesFiltersScene;
let dashboardsScene: ScopesDashboardsScene;
let fetchScopesSpy: jest.SpyInstance;
let fetchDashboardsSpy: jest.SpyInstance;
beforeAll(() => {
config.featureToggles.scopeFilters = true;
});
beforeEach(() => {
dashboardScene = buildTestScene();
scopesScene = dashboardScene.state.scopes!;
filtersScene = scopesScene.state.filters;
dashboardsScene = scopesScene.state.dashboards;
fetchScopesSpy = jest.spyOn(filtersScene!, 'fetchScopes');
fetchDashboardsSpy = jest.spyOn(dashboardsScene!, 'fetchDashboards');
dashboardScene.activate();
scopesScene.activate();
filtersScene.activate();
dashboardsScene.activate();
});
it('Initializes', () => {
expect(scopesScene).toBeInstanceOf(ScopesScene);
expect(filtersScene).toBeInstanceOf(ScopesFiltersScene);
expect(dashboardsScene).toBeInstanceOf(ScopesDashboardsScene);
});
it('Fetches scopes list', async () => {
expect(fetchScopesSpy).toHaveBeenCalled();
});
it('Fetches dashboards list', () => {
filtersScene.setScope(scopesMocks.scope1.uid);
waitFor(() => {
expect(fetchDashboardsSpy).toHaveBeenCalled();
expect(dashboardsScene.state.dashboards).toEqual(scopesMocks.scope1.dashboards);
});
filtersScene.setScope(scopesMocks.scope2.uid);
waitFor(() => {
expect(fetchDashboardsSpy).toHaveBeenCalled();
expect(dashboardsScene.state.dashboards).toEqual(scopesMocks.scope2.dashboards);
});
});
it('Enriches data requests', () => {
const { dashboards: _dashboards, ...scope1 } = scopesMocks.scope1;
filtersScene.setScope(scope1.uid);
const queryRunner = sceneGraph.findObject(dashboardScene, (o) => o.state.key === 'data-query-runner')!;
expect(dashboardScene.enrichDataRequest(queryRunner).scope).toEqual(scope1);
});
it('Toggles expanded state', async () => {
scopesScene.toggleIsExpanded();
expect(scopesScene.state.isExpanded).toEqual(true);
});
it('Enters view mode', async () => {
dashboardScene.onEnterEditMode();
expect(scopesScene.state.isViewing).toEqual(true);
expect(scopesScene.state.isExpanded).toEqual(false);
});
it('Exits view mode', async () => {
dashboardScene.onEnterEditMode();
dashboardScene.exitEditMode({ skipConfirm: true });
expect(scopesScene.state.isViewing).toEqual(false);
expect(scopesScene.state.isExpanded).toEqual(false);
});
});
});
function buildTestScene(overrides: Partial<DashboardScene> = {}) {
return new DashboardScene({
title: 'hello',
uid: 'dash-1',
description: 'hello description',
tags: ['tag1', 'tag2'],
editable: true,
$timeRange: new SceneTimeRange({
timeZone: 'browser',
}),
controls: new DashboardControls({}),
$behaviors: [new behaviors.CursorSync({})],
body: new SceneGridLayout({
children: [
new SceneGridItem({
key: 'griditem-1',
x: 0,
y: 0,
width: 300,
height: 300,
body: new VizPanel({
title: 'Panel A',
key: 'panel-1',
pluginId: 'table',
$data: new SceneQueryRunner({ key: 'data-query-runner', queries: [{ refId: 'A' }] }),
}),
}),
],
}),
...overrides,
});
}