import { render } from '@testing-library/react';
import { selectors } from '@grafana/e2e-selectors';
import { SceneDataLayerControls, SceneVariableSet, TextBoxVariable, VariableValueSelectors } from '@grafana/scenes';
import { DashboardControls, DashboardControlsState } from './DashboardControls';
import { DashboardScene } from './DashboardScene';
describe('DashboardControls', () => {
describe('Given a standard scene', () => {
it('should initialize with default values', () => {
const scene = buildTestScene();
expect(scene.state.variableControls).toEqual([]);
expect(scene.state.timePicker).toBeDefined();
expect(scene.state.refreshPicker).toBeDefined();
});
it('should return if time controls are hidden', () => {
const scene = buildTestScene({
hideTimeControls: false,
hideVariableControls: false,
hideLinksControls: false,
});
expect(scene.hasControls()).toBeTruthy();
scene.setState({ hideTimeControls: true });
expect(scene.hasControls()).toBeTruthy();
scene.setState({ hideVariableControls: true, hideLinksControls: true });
expect(scene.hasControls()).toBeFalsy();
});
});
describe('Component', () => {
it('should render', () => {
const scene = buildTestScene();
expect(() => {
render();
}).not.toThrow();
});
it('should render visible controls', async () => {
const scene = buildTestScene({
variableControls: [new VariableValueSelectors({}), new SceneDataLayerControls()],
});
const renderer = render();
expect(await renderer.findByTestId(selectors.pages.Dashboard.Controls)).toBeInTheDocument();
expect(await renderer.findByTestId(selectors.components.DashboardLinks.container)).toBeInTheDocument();
expect(await renderer.findByTestId(selectors.components.TimePicker.openButton)).toBeInTheDocument();
expect(await renderer.findByTestId(selectors.components.RefreshPicker.runButtonV2)).toBeInTheDocument();
expect(await renderer.findByTestId(selectors.pages.Dashboard.SubMenu.submenuItem)).toBeInTheDocument();
});
it('should render with hidden controls', async () => {
const scene = buildTestScene({
hideTimeControls: true,
hideVariableControls: true,
hideLinksControls: true,
variableControls: [new VariableValueSelectors({}), new SceneDataLayerControls()],
});
const renderer = render();
expect(await renderer.queryByTestId(selectors.pages.Dashboard.Controls)).not.toBeInTheDocument();
});
});
describe('UrlSync', () => {
it('should return keys', () => {
const scene = buildTestScene();
// @ts-expect-error
expect(scene._urlSync.getKeys()).toEqual(['_dash.hideTimePicker', '_dash.hideVariables', '_dash.hideLinks']);
});
it('should not return url state for hide flags', () => {
const scene = buildTestScene();
expect(scene.getUrlState()).toEqual({});
scene.setState({
hideTimeControls: true,
hideVariableControls: true,
hideLinksControls: true,
});
expect(scene.getUrlState()).toEqual({});
});
it('should update from url', () => {
const scene = buildTestScene();
scene.updateFromUrl({
'_dash.hideTimePicker': 'true',
'_dash.hideVariables': 'true',
'_dash.hideLinks': 'true',
});
expect(scene.state.hideTimeControls).toBeTruthy();
expect(scene.state.hideVariableControls).toBeTruthy();
expect(scene.state.hideLinksControls).toBeTruthy();
scene.updateFromUrl({
'_dash.hideTimePicker': '',
'_dash.hideVariables': '',
'_dash.hideLinks': '',
});
expect(scene.state.hideTimeControls).toBeTruthy();
expect(scene.state.hideVariableControls).toBeTruthy();
expect(scene.state.hideLinksControls).toBeTruthy();
});
it('should not override state if no new state comes from url', () => {
const scene = buildTestScene({
hideTimeControls: true,
hideVariableControls: true,
hideLinksControls: true,
});
scene.updateFromUrl({});
expect(scene.state.hideTimeControls).toBeTruthy();
expect(scene.state.hideVariableControls).toBeTruthy();
expect(scene.state.hideLinksControls).toBeTruthy();
});
it('should not call setState if no changes', () => {
const scene = buildTestScene({
hideTimeControls: true,
hideVariableControls: true,
hideLinksControls: true,
});
const setState = jest.spyOn(scene, 'setState');
scene.updateFromUrl({
'_dash.hideTimePicker': 'true',
'_dash.hideVariables': 'true',
'_dash.hideLinks': 'true',
});
expect(setState).toHaveBeenCalledTimes(0);
});
});
});
function buildTestScene(state?: Partial): DashboardControls {
const variable = new TextBoxVariable({
name: 'A',
label: 'A',
description: 'A',
type: 'textbox',
value: 'Text',
});
const dashboard = new DashboardScene({
uid: 'A',
links: [
{
title: 'Link',
url: 'http://localhost:3000/$A',
type: 'link',
asDropdown: false,
icon: '',
includeVars: true,
keepTime: true,
tags: [],
targetBlank: false,
tooltip: 'Link',
},
],
$variables: new SceneVariableSet({
variables: [variable],
}),
controls: new DashboardControls({
...state,
}),
});
dashboard.activate();
variable.activate();
return dashboard.state.controls as DashboardControls;
}