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