github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/graph/Graph.test.tsx (about) 1 import * as React from 'react'; 2 import $ from 'jquery'; 3 import { shallow, mount } from 'enzyme'; 4 import Graph from './Graph'; 5 import ReactResizeDetector from 'react-resize-detector'; 6 import { Legend } from './Legend'; 7 8 describe('Graph', () => { 9 beforeAll(() => { 10 jest.spyOn(window, 'requestAnimationFrame').mockImplementation((cb: any) => cb()); 11 }); 12 describe('data is returned', () => { 13 const props: any = { 14 queryParams: { 15 startTime: 1572128592, 16 endTime: 1572130692, 17 resolution: 28, 18 }, 19 stacked: false, 20 data: { 21 resultType: 'matrix', 22 result: [ 23 { 24 metric: { 25 code: '200', 26 handler: '/graph', 27 instance: 'localhost:9090', 28 job: 'prometheus', 29 }, 30 values: [ 31 [1572128592, '23'], 32 [1572128620, '2'], 33 [1572128648, '4'], 34 [1572128676, '1'], 35 [1572128704, '2'], 36 [1572128732, '12'], 37 [1572128760, '1'], 38 [1572128788, '0'], 39 [1572128816, '0'], 40 [1572128844, '2'], 41 [1572128872, '5'], 42 [1572130384, '6'], 43 [1572130412, '7'], 44 [1572130440, '19'], 45 [1572130468, '33'], 46 [1572130496, '14'], 47 [1572130524, '7'], 48 [1572130552, '6'], 49 [1572130580, '0'], 50 [1572130608, '0'], 51 [1572130636, '0'], 52 [1572130664, '0'], 53 [1572130692, '0'], 54 ], 55 }, 56 ], 57 }, 58 }; 59 it('renders a graph with props', () => { 60 const graph = shallow(<Graph {...props} />); 61 const div = graph.find('div').filterWhere((elem) => elem.prop('className') === 'graph'); 62 const resize = div.find(ReactResizeDetector); 63 const innerdiv = div.find('div').filterWhere((elem) => elem.prop('className') === 'graph-chart'); 64 expect(resize.prop('handleWidth')).toBe(true); 65 expect(div).toHaveLength(1); 66 expect(innerdiv).toHaveLength(1); 67 }); 68 describe('Legend', () => { 69 it('renders a legend', () => { 70 const graph = shallow(<Graph {...props} />); 71 expect(graph.find(Legend)).toHaveLength(1); 72 }); 73 }); 74 }); 75 describe('on component update', () => { 76 let graph: any; 77 let spyState: any; 78 let mockPlot: any; 79 beforeEach(() => { 80 mockPlot = jest.spyOn($, 'plot').mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: jest.fn() } as any); 81 graph = mount( 82 <Graph 83 {...({ 84 stacked: true, 85 queryParams: { 86 startTime: 1572128592, 87 endTime: 1572128598, 88 resolution: 28, 89 }, 90 data: { result: [{ values: [], metric: {} }] }, 91 } as any)} 92 /> 93 ); 94 spyState = jest.spyOn(graph.instance(), 'setState'); 95 }); 96 afterEach(() => { 97 spyState.mockReset(); 98 mockPlot.mockReset(); 99 }); 100 it('should trigger state update when new data is received', () => { 101 graph.setProps({ data: { result: [{ values: [{}], metric: {} }] } }); 102 expect(spyState).toHaveBeenCalledWith( 103 { 104 chartData: [ 105 { 106 color: '#008000', 107 data: [[1572128592000, null]], 108 index: 0, 109 labels: {}, 110 }, 111 ], 112 }, 113 expect.anything() 114 ); 115 }); 116 it('should trigger state update when stacked prop is changed', () => { 117 graph.setProps({ stacked: false }); 118 expect(spyState).toHaveBeenCalledWith( 119 { 120 chartData: [ 121 { 122 color: '#008000', 123 data: [[1572128592000, null]], 124 index: 0, 125 labels: {}, 126 }, 127 ], 128 }, 129 expect.anything() 130 ); 131 }); 132 }); 133 describe('on unmount', () => { 134 it('should call destroy plot', () => { 135 const graph = mount( 136 <Graph 137 {...({ 138 stacked: true, 139 queryParams: { 140 startTime: 1572128592, 141 endTime: 1572130692, 142 resolution: 28, 143 }, 144 data: { result: [{ values: [], metric: {} }] }, 145 } as any)} 146 /> 147 ); 148 const spyPlotDestroy = jest.spyOn(graph.instance(), 'componentWillUnmount'); 149 graph.unmount(); 150 expect(spyPlotDestroy).toHaveBeenCalledTimes(1); 151 spyPlotDestroy.mockReset(); 152 }); 153 }); 154 155 describe('plot', () => { 156 it('should not call jquery.plot if chartRef not exist', () => { 157 const mockSetData = jest.fn(); 158 jest.spyOn($, 'plot').mockReturnValue({ setData: mockSetData, draw: jest.fn(), destroy: jest.fn() } as any); 159 const graph = shallow( 160 <Graph 161 {...({ 162 stacked: true, 163 queryParams: { 164 startTime: 1572128592, 165 endTime: 1572128598, 166 resolution: 28, 167 }, 168 data: { result: [{ values: [], metric: {} }] }, 169 } as any)} 170 /> 171 ); 172 (graph.instance() as any).plot(); 173 expect(mockSetData).not.toBeCalled(); 174 }); 175 it('should call jquery.plot if chartRef exist', () => { 176 const mockPlot = jest 177 .spyOn($, 'plot') 178 .mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: jest.fn() } as any); 179 const graph = mount( 180 <Graph 181 {...({ 182 stacked: true, 183 queryParams: { 184 startTime: 1572128592, 185 endTime: 1572128598, 186 resolution: 28, 187 }, 188 data: { result: [{ values: [], metric: {} }] }, 189 } as any)} 190 /> 191 ); 192 (graph.instance() as any).plot(); 193 expect(mockPlot).toBeCalled(); 194 }); 195 it('should destroy plot', () => { 196 const mockDestroy = jest.fn(); 197 jest.spyOn($, 'plot').mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: mockDestroy } as any); 198 const graph = mount( 199 <Graph 200 {...({ 201 stacked: true, 202 queryParams: { 203 startTime: 1572128592, 204 endTime: 1572128598, 205 resolution: 28, 206 }, 207 data: { result: [{ values: [], metric: {} }] }, 208 } as any)} 209 /> 210 ); 211 (graph.instance() as any).plot(); 212 (graph.instance() as any).destroyPlot(); 213 expect(mockDestroy).toHaveBeenCalledTimes(2); 214 }); 215 }); 216 describe('plotSetAndDraw', () => { 217 it('should call spyPlotSetAndDraw on legend hover', () => { 218 jest.spyOn($, 'plot').mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: jest.fn() } as any); 219 const graph = mount( 220 <Graph 221 {...({ 222 stacked: true, 223 queryParams: { 224 startTime: 1572128592, 225 endTime: 1572128598, 226 resolution: 28, 227 }, 228 data: { 229 result: [ 230 { values: [], metric: {} }, 231 { values: [], metric: {} }, 232 ], 233 }, 234 } as any)} 235 /> 236 ); 237 (graph.instance() as any).plot(); // create chart 238 const spyPlotSetAndDraw = jest.spyOn(graph.instance() as any, 'plotSetAndDraw'); 239 graph.find('.legend-item').at(0).simulate('mouseover'); 240 expect(spyPlotSetAndDraw).toHaveBeenCalledTimes(1); 241 }); 242 it('should call spyPlotSetAndDraw with chartDate from state as default value', () => { 243 const mockSetData = jest.fn(); 244 const spyPlot = jest 245 .spyOn($, 'plot') 246 .mockReturnValue({ setData: mockSetData, draw: jest.fn(), destroy: jest.fn() } as any); 247 const graph: any = mount( 248 <Graph 249 {...({ 250 stacked: true, 251 queryParams: { 252 startTime: 1572128592, 253 endTime: 1572128598, 254 resolution: 28, 255 }, 256 data: { 257 result: [ 258 { values: [], metric: {} }, 259 { values: [], metric: {} }, 260 ], 261 }, 262 } as any)} 263 /> 264 ); 265 (graph.instance() as any).plot(); // create chart 266 graph.find('.graph-legend').simulate('mouseout'); 267 expect(mockSetData).toHaveBeenCalledWith(graph.state().chartData); 268 spyPlot.mockReset(); 269 }); 270 }); 271 });