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; }