github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/graph/GraphControls.test.tsx (about) 1 import * as React from 'react'; 2 import { shallow } from 'enzyme'; 3 import GraphControls from './GraphControls'; 4 import { Button, ButtonGroup, Form, InputGroup, InputGroupAddon, Input } from 'reactstrap'; 5 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 import { faPlus, faMinus, faChartArea, faChartLine } from '@fortawesome/free-solid-svg-icons'; 7 import TimeInput from './TimeInput'; 8 9 const defaultGraphControlProps = { 10 range: 60 * 60 * 24 * 1000, 11 endTime: 1572100217898, 12 useLocalTime: false, 13 resolution: 10, 14 stacked: false, 15 maxSourceResolution: '0s', 16 17 onChangeRange: (): void => { 18 // Do nothing. 19 }, 20 onChangeEndTime: (): void => { 21 // Do nothing. 22 }, 23 onChangeResolution: (): void => { 24 // Do nothing. 25 }, 26 onChangeStacking: (): void => { 27 // Do nothing. 28 }, 29 onChangeMaxSourceResolution: (): void => { 30 // Do nothing. 31 }, 32 }; 33 34 describe('GraphControls', () => { 35 it('renders a form', () => { 36 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 37 const form = controls.find(Form); 38 expect(form).toHaveLength(1); 39 expect(form.prop('className')).toEqual('graph-controls'); 40 expect(form.prop('inline')).toBe(true); 41 }); 42 43 it('renders an Input Group for range', () => { 44 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 45 const form = controls.find(InputGroup); 46 expect(form).toHaveLength(1); 47 expect(form.prop('className')).toEqual('range-input'); 48 expect(form.prop('size')).toBe('sm'); 49 }); 50 51 it('renders a decrease/increase range buttons', () => { 52 [ 53 { 54 position: 'prepend', 55 title: 'Decrease range', 56 icon: faMinus, 57 }, 58 { 59 position: 'append', 60 title: 'Increase range', 61 icon: faPlus, 62 }, 63 ].forEach((testCase) => { 64 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 65 const addon = controls.find(InputGroupAddon).filterWhere((addon) => addon.prop('addonType') === testCase.position); 66 const button = addon.find(Button); 67 const icon = button.find(FontAwesomeIcon); 68 expect(button.prop('title')).toEqual(testCase.title); 69 expect(icon).toHaveLength(1); 70 expect(icon.prop('icon')).toEqual(testCase.icon); 71 expect(icon.prop('fixedWidth')).toBe(true); 72 }); 73 }); 74 75 it('renders an Input for range', () => { 76 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 77 const form = controls.find(InputGroup); 78 const input = form.find(Input); 79 expect(input).toHaveLength(1); 80 expect(input.prop('defaultValue')).toEqual('1d'); 81 expect(input.prop('innerRef')).toEqual({ current: null }); 82 }); 83 84 it('renders a TimeInput with props', () => { 85 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 86 const timeInput = controls.find(TimeInput); 87 expect(timeInput).toHaveLength(1); 88 expect(timeInput.prop('time')).toEqual(1572100217898); 89 expect(timeInput.prop('range')).toEqual(86400000); 90 expect(timeInput.prop('placeholder')).toEqual('End time'); 91 }); 92 93 it('renders a TimeInput with a callback', () => { 94 const results: (number | null)[] = []; 95 const onChange = (endTime: number | null): void => { 96 results.push(endTime); 97 }; 98 const controls = shallow(<GraphControls {...defaultGraphControlProps} onChangeEndTime={onChange} />); 99 const timeInput = controls.find(TimeInput); 100 const onChangeTime = timeInput.prop('onChangeTime'); 101 if (onChangeTime) { 102 onChangeTime(5); 103 expect(results).toHaveLength(1); 104 expect(results[0]).toEqual(5); 105 results.pop(); 106 } else { 107 fail('Expected onChangeTime to be defined but it was not'); 108 } 109 }); 110 111 it('renders a resolution Input with props', () => { 112 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 113 const input = controls.find(Input).filterWhere((input) => input.prop('className') === 'resolution-input'); 114 expect(input.prop('placeholder')).toEqual('Res. (s)'); 115 expect(input.prop('defaultValue')).toEqual('10'); 116 expect(input.prop('innerRef')).toEqual({ current: null }); 117 expect(input.prop('bsSize')).toEqual('sm'); 118 }); 119 120 it('renders a button group', () => { 121 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 122 const group = controls.find(ButtonGroup); 123 expect(group.prop('className')).toEqual('stacked-input'); 124 expect(group.prop('size')).toEqual('sm'); 125 }); 126 127 it('renders buttons inside the button group', () => { 128 [ 129 { 130 title: 'Show unstacked line graph', 131 icon: faChartLine, 132 active: true, 133 }, 134 { 135 title: 'Show stacked graph', 136 icon: faChartArea, 137 active: false, 138 }, 139 ].forEach((testCase) => { 140 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 141 const group = controls.find(ButtonGroup); 142 const btn = group.find(Button).filterWhere((btn) => btn.prop('title') === testCase.title); 143 expect(btn.prop('active')).toEqual(testCase.active); 144 const icon = btn.find(FontAwesomeIcon); 145 expect(icon.prop('icon')).toEqual(testCase.icon); 146 }); 147 }); 148 149 it('renders buttons with callbacks', () => { 150 [ 151 { 152 title: 'Show unstacked line graph', 153 active: true, 154 }, 155 { 156 title: 'Show stacked graph', 157 active: false, 158 }, 159 ].forEach((testCase) => { 160 const results: boolean[] = []; 161 const onChange = (stacked: boolean): void => { 162 results.push(stacked); 163 }; 164 const controls = shallow(<GraphControls {...defaultGraphControlProps} onChangeStacking={onChange} />); 165 const group = controls.find(ButtonGroup); 166 const btn = group.find(Button).filterWhere((btn) => btn.prop('title') === testCase.title); 167 const onClick = btn.prop('onClick'); 168 if (onClick) { 169 onClick({} as React.MouseEvent<HTMLButtonElement, MouseEvent>); 170 expect(results).toHaveLength(1); 171 expect(results[0]).toBe(!testCase.active); 172 results.pop(); 173 } else { 174 fail('Expected onClick to be defined but it was not'); 175 } 176 }); 177 }); 178 179 it('renders a select box for max source resolution', () => { 180 const controls = shallow(<GraphControls {...defaultGraphControlProps} />); 181 const input = controls.find(Input).filterWhere((input) => input.prop('className') === 'max-source-resolution-input'); 182 expect(input.prop('type')).toEqual('select'); 183 expect(input.prop('value')).toEqual('0s'); 184 }); 185 });