123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- import { fireEvent, render, screen, within } from '@testing-library/react';
- import React from 'react';
- import { Provider } from 'react-redux';
- import configureMockStore from 'redux-mock-store';
- import {
- FieldConfigSource,
- FieldType,
- LoadingState,
- PanelData,
- standardEditorsRegistry,
- standardFieldConfigEditorRegistry,
- toDataFrame,
- } from '@grafana/data';
- import { selectors } from '@grafana/e2e-selectors';
- import { getAllOptionEditors, getAllStandardFieldConfigs } from 'app/core/components/editors/registry';
- import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks';
- import { DashboardModel, PanelModel } from '../../state';
- import { OptionsPaneOptions } from './OptionsPaneOptions';
- import { dataOverrideTooltipDescription, overrideRuleTooltipDescription } from './state/getOptionOverrides';
- standardEditorsRegistry.setInit(getAllOptionEditors);
- standardFieldConfigEditorRegistry.setInit(getAllStandardFieldConfigs);
- const mockStore = configureMockStore<any, any>();
- const OptionsPaneSelector = selectors.components.PanelEditor.OptionsPane;
- jest.mock('react-router-dom', () => ({
- ...(jest.requireActual('react-router-dom') as any),
- useLocation: () => ({
- pathname: 'localhost:3000/example/path',
- }),
- }));
- class OptionsPaneOptionsTestScenario {
- onFieldConfigsChange = jest.fn();
- onPanelOptionsChanged = jest.fn();
- onPanelConfigChange = jest.fn();
- panelData: PanelData = {
- series: [],
- state: LoadingState.Done,
- timeRange: {} as any,
- };
- plugin = getPanelPlugin({
- id: 'TestPanel',
- }).useFieldConfig({
- standardOptions: {},
- useCustomConfig: (b) => {
- b.addBooleanSwitch({
- name: 'CustomBool',
- path: 'CustomBool',
- })
- .addBooleanSwitch({
- name: 'HiddenFromDef',
- path: 'HiddenFromDef',
- hideFromDefaults: true,
- })
- .addTextInput({
- name: 'TextPropWithCategory',
- path: 'TextPropWithCategory',
- settings: {
- placeholder: 'CustomTextPropPlaceholder',
- },
- category: ['Axis'],
- });
- },
- });
- panel = new PanelModel({
- title: 'Test title',
- type: this.plugin.meta.id,
- fieldConfig: {
- defaults: {
- max: 100,
- thresholds: {
- mode: 'absolute',
- steps: [
- { value: -Infinity, color: 'green' },
- { value: 100, color: 'green' },
- ],
- },
- },
- overrides: [],
- },
- options: {},
- });
- dashboard = new DashboardModel({});
- store = mockStore({
- dashboard: { panels: [] },
- templating: {
- variables: {},
- },
- });
- render() {
- render(
- <Provider store={this.store}>
- <OptionsPaneOptions
- data={this.panelData}
- plugin={this.plugin}
- panel={this.panel}
- dashboard={this.dashboard}
- onFieldConfigsChange={this.onFieldConfigsChange}
- onPanelConfigChange={this.onPanelConfigChange}
- onPanelOptionsChanged={this.onPanelOptionsChanged}
- instanceState={undefined}
- />
- </Provider>
- );
- }
- }
- describe('OptionsPaneOptions', () => {
- it('should render panel frame options', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- expect(screen.getByLabelText(OptionsPaneSelector.fieldLabel('Panel options Title'))).toBeInTheDocument();
- });
- it('should render all categories', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- expect(screen.getByRole('heading', { name: /Panel options/ })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: /Standard options/ })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: /Value mappings/ })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: /Thresholds/ })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: /TestPanel/ })).toBeInTheDocument();
- });
- it('should render custom options', () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- expect(screen.getByLabelText(OptionsPaneSelector.fieldLabel('TestPanel CustomBool'))).toBeInTheDocument();
- });
- it('should not render options that are marked as hidden from defaults', () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- expect(screen.queryByLabelText(OptionsPaneSelector.fieldLabel('TestPanel HiddenFromDef'))).not.toBeInTheDocument();
- });
- it('should create categories for field options with category', () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- expect(screen.getByRole('heading', { name: /Axis/ })).toBeInTheDocument();
- });
- it('should not render categories with hidden fields only', () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.plugin = getPanelPlugin({
- id: 'TestPanel',
- }).useFieldConfig({
- standardOptions: {},
- useCustomConfig: (b) => {
- b.addBooleanSwitch({
- name: 'CustomBool',
- path: 'CustomBool',
- hideFromDefaults: true,
- category: ['Axis'],
- });
- },
- });
- scenario.render();
- expect(screen.queryByRole('heading', { name: /Axis/ })).not.toBeInTheDocument();
- });
- it('should call onPanelConfigChange when updating title', () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- const input = screen.getByDisplayValue(scenario.panel.title);
- fireEvent.change(input, { target: { value: 'New' } });
- fireEvent.blur(input);
- expect(scenario.onPanelConfigChange).toHaveBeenCalledWith('title', 'New');
- });
- it('should call onFieldConfigsChange when updating field config', () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- const input = screen.getByPlaceholderText('CustomTextPropPlaceholder');
- fireEvent.change(input, { target: { value: 'New' } });
- fireEvent.blur(input);
- const newFieldConfig: FieldConfigSource = scenario.panel.fieldConfig;
- newFieldConfig.defaults.custom = { TextPropWithCategory: 'New' };
- expect(scenario.onFieldConfigsChange).toHaveBeenCalledWith(newFieldConfig);
- });
- it('should only render hits when search query specified', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.render();
- const input = screen.getByPlaceholderText('Search options');
- fireEvent.change(input, { target: { value: 'TextPropWithCategory' } });
- fireEvent.blur(input);
- expect(screen.queryByLabelText(OptionsPaneSelector.fieldLabel('Panel options Title'))).not.toBeInTheDocument();
- expect(screen.getByLabelText(OptionsPaneSelector.fieldLabel('Axis TextPropWithCategory'))).toBeInTheDocument();
- });
- it('should not render field override options non data panel', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.plugin = getPanelPlugin({
- id: 'TestPanel',
- });
- scenario.render();
- expect(
- screen.queryByLabelText(selectors.components.ValuePicker.button('Add field override'))
- ).not.toBeInTheDocument();
- });
- it('should allow standard properties extension', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.plugin = getPanelPlugin({
- id: 'TestPanel',
- }).useFieldConfig({
- useCustomConfig: (b) => {
- b.addBooleanSwitch({
- name: 'CustomThresholdOption',
- path: 'CustomThresholdOption',
- category: ['Thresholds'],
- });
- },
- });
- scenario.render();
- const thresholdsSection = screen.getByLabelText(selectors.components.OptionsGroup.group('Thresholds'));
- expect(
- within(thresholdsSection).getByLabelText(OptionsPaneSelector.fieldLabel('Thresholds CustomThresholdOption'))
- ).toBeInTheDocument();
- });
- it('should show data override info dot', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.panelData.series = [
- toDataFrame({
- fields: [
- {
- name: 'Value',
- type: FieldType.number,
- values: [10, 200],
- config: {
- min: 100,
- },
- },
- ],
- refId: 'A',
- }),
- ];
- scenario.render();
- expect(screen.getByLabelText(dataOverrideTooltipDescription)).toBeInTheDocument();
- expect(screen.queryByLabelText(overrideRuleTooltipDescription)).not.toBeInTheDocument();
- });
- it('should show override rule info dot', async () => {
- const scenario = new OptionsPaneOptionsTestScenario();
- scenario.panel.fieldConfig.overrides = [
- {
- matcher: { id: 'byName', options: 'SeriesA' },
- properties: [
- {
- id: 'decimals',
- value: 2,
- },
- ],
- },
- ];
- scenario.render();
- expect(screen.getByLabelText(overrideRuleTooltipDescription)).toBeInTheDocument();
- });
- });
|