github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/graph/Panel.test.tsx (about)

     1  import * as React from 'react';
     2  import { mount, shallow } from 'enzyme';
     3  import Panel, { PanelOptions, PanelProps, PanelType } from './Panel';
     4  import GraphControls from './GraphControls';
     5  import { NavLink, TabPane } from 'reactstrap';
     6  import TimeInput from './TimeInput';
     7  import DataTable from './DataTable';
     8  import { GraphTabContent } from './GraphTabContent';
     9  
    10  const defaultProps: PanelProps = {
    11    id: 'abc123',
    12    useLocalTime: false,
    13    options: {
    14      expr: 'prometheus_engine',
    15      type: PanelType.Table,
    16      range: 10,
    17      endTime: 1572100217898,
    18      resolution: 28,
    19      stacked: false,
    20      maxSourceResolution: 'auto',
    21      useDeduplication: true,
    22      usePartialResponse: false,
    23      storeMatches: [],
    24      engine: 'prometheus',
    25      explain: false,
    26      disableExplainCheckbox: false,
    27    },
    28    onOptionsChanged: (): void => {
    29      // Do nothing.
    30    },
    31    pastQueries: [],
    32    metricNames: [
    33      'prometheus_engine_queries',
    34      'prometheus_engine_queries_concurrent_max',
    35      'prometheus_engine_query_duration_seconds',
    36    ],
    37    removePanel: (): void => {
    38      // Do nothing.
    39    },
    40    onExecuteQuery: (): void => {
    41      // Do nothing.
    42    },
    43    stores: [],
    44    enableAutocomplete: true,
    45    defaultStep: '1s',
    46    enableHighlighting: true,
    47    enableLinter: true,
    48    defaultEngine: 'prometheus',
    49  };
    50  
    51  describe('Panel', () => {
    52    const panel = shallow(<Panel {...defaultProps} />);
    53  
    54    it('renders NavLinks', () => {
    55      const results: PanelOptions[] = [];
    56      const onOptionsChanged = (opts: PanelOptions): void => {
    57        results.push(opts);
    58      };
    59      const panel = shallow(<Panel {...defaultProps} onOptionsChanged={onOptionsChanged} />);
    60      // Panel construction updates Explain checkbox prop to disbale.
    61      // Hence, a result is added and dropping it.
    62      results.length = 0;
    63      const links = panel.find(NavLink);
    64      [
    65        { panelType: 'Table', active: true },
    66        { panelType: 'Graph', active: false },
    67      ].forEach((tc: { panelType: string; active: boolean }, i: number) => {
    68        const link = links.at(i);
    69        const className = tc.active ? 'active' : '';
    70        expect(link.prop('className')).toEqual(className);
    71        link.simulate('click');
    72        expect(results).toHaveLength(1);
    73        expect(results[0].type).toEqual(tc.panelType.toLowerCase());
    74        results.pop();
    75      });
    76    });
    77  
    78    it('renders a TabPane with a TimeInput and a DataTable when in table mode', () => {
    79      const tab = panel.find(TabPane).filterWhere((tab) => tab.prop('tabId') === 'table');
    80      const timeInput = tab.find(TimeInput);
    81      expect(timeInput.prop('time')).toEqual(defaultProps.options.endTime);
    82      expect(timeInput.prop('range')).toEqual(defaultProps.options.range);
    83      expect(timeInput.prop('placeholder')).toEqual('Evaluation time');
    84      expect(tab.find(DataTable)).toHaveLength(1);
    85    });
    86  
    87    it('renders a TabPane with a Graph and GraphControls when in graph mode', () => {
    88      const options = {
    89        expr: 'prometheus_engine',
    90        type: PanelType.Graph,
    91        range: 10,
    92        endTime: 1572100217898,
    93        resolution: 28,
    94        stacked: false,
    95        maxSourceResolution: 'auto',
    96        useDeduplication: true,
    97        usePartialResponse: false,
    98        storeMatches: [],
    99        engine: 'prometheus',
   100        explain: false,
   101        disableExplainCheckbox: false,
   102      };
   103      const graphPanel = mount(<Panel {...defaultProps} options={options} />);
   104      const controls = graphPanel.find(GraphControls);
   105      graphPanel.setState({ data: { resultType: 'matrix', result: [] } });
   106      const graph = graphPanel.find(GraphTabContent);
   107      expect(controls.prop('endTime')).toEqual(options.endTime);
   108      expect(controls.prop('range')).toEqual(options.range);
   109      expect(controls.prop('resolution')).toEqual(options.resolution);
   110      expect(controls.prop('stacked')).toEqual(options.stacked);
   111      expect(graph.prop('stacked')).toEqual(options.stacked);
   112      expect(controls.prop('maxSourceResolution')).toEqual(options.maxSourceResolution);
   113    });
   114  
   115    describe('when switching between modes', () => {
   116      [
   117        { from: PanelType.Table, to: PanelType.Graph },
   118        { from: PanelType.Graph, to: PanelType.Table },
   119      ].forEach(({ from, to }: { from: PanelType; to: PanelType }) => {
   120        it(`${from} -> ${to} nulls out data`, () => {
   121          const props = {
   122            ...defaultProps,
   123            options: { ...defaultProps.options, type: from },
   124          };
   125          const panel = shallow(<Panel {...props} />);
   126          const instance: any = panel.instance();
   127          panel.setState({ data: 'somedata' });
   128          expect(panel.state('data')).toEqual('somedata');
   129          instance.handleChangeType(to);
   130          expect(panel.state('data')).toBeNull();
   131        });
   132      });
   133    });
   134  
   135    describe('when changing query then time', () => {
   136      it('executes the new query', () => {
   137        const initialExpr = 'time()';
   138        const newExpr = 'time() - time()';
   139        const panel = shallow(<Panel {...defaultProps} options={{ ...defaultProps.options, expr: initialExpr }} />);
   140        const instance: any = panel.instance();
   141        instance.executeQuery();
   142        const executeQuerySpy = jest.spyOn(instance, 'executeQuery');
   143        //change query without executing
   144        panel.setProps({ options: { ...defaultProps.options, expr: newExpr } });
   145        expect(executeQuerySpy).toHaveBeenCalledTimes(0);
   146        //execute query implicitly with time change
   147        panel.setProps({ options: { ...defaultProps.options, expr: newExpr, endTime: 1575744840 } });
   148        expect(executeQuerySpy).toHaveBeenCalledTimes(1);
   149      });
   150    });
   151  });