| 
									
										
										
										
											2024-05-13 18:03:21 +08:00
										 |  |  | import { render, screen, waitFor, fireEvent, userEvent } from 'test/test-utils'; | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   createDataFrame, | 
					
						
							|  |  |  |   FieldType, | 
					
						
							|  |  |  |   LogRowContextQueryDirection, | 
					
						
							|  |  |  |   LogsSortOrder, | 
					
						
							|  |  |  |   SplitOpenOptions, | 
					
						
							|  |  |  | } from '@grafana/data'; | 
					
						
							| 
									
										
										
										
											2023-07-04 19:27:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { dataFrameToLogsModel } from '../../logsModel'; | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { LogRowContextModal } from './LogRowContextModal'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  | const dfBefore = createDataFrame({ | 
					
						
							|  |  |  |   fields: [ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'time', | 
					
						
							|  |  |  |       type: FieldType.time, | 
					
						
							|  |  |  |       values: ['2019-04-26T07:28:11.352440161Z', '2019-04-26T09:28:11.352440161Z'], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'message', | 
					
						
							|  |  |  |       type: FieldType.string, | 
					
						
							|  |  |  |       values: ['foo123', 'foo123'], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   ], | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | const dfNow = createDataFrame({ | 
					
						
							|  |  |  |   fields: [ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'time', | 
					
						
							|  |  |  |       type: FieldType.time, | 
					
						
							|  |  |  |       values: ['2019-04-26T09:28:11.352440161Z'], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'message', | 
					
						
							|  |  |  |       type: FieldType.string, | 
					
						
							|  |  |  |       values: ['foo123'], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   ], | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | const dfAfter = createDataFrame({ | 
					
						
							|  |  |  |   fields: [ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'time', | 
					
						
							|  |  |  |       type: FieldType.time, | 
					
						
							|  |  |  |       values: ['2019-04-26T14:42:50.991981292Z', '2019-04-26T16:28:11.352440161Z'], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'message', | 
					
						
							|  |  |  |       type: FieldType.string, | 
					
						
							|  |  |  |       values: ['foo123', 'bar123'], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   ], | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 02:03:47 +08:00
										 |  |  | let getRowContext = jest.fn(); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  | const dispatchMock = jest.fn(); | 
					
						
							| 
									
										
										
										
											2025-07-09 12:15:33 +08:00
										 |  |  | jest.mock('app/types/store', () => ({ | 
					
						
							|  |  |  |   ...jest.requireActual('app/types/store'), | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   useDispatch: () => dispatchMock, | 
					
						
							|  |  |  | })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:00:35 +08:00
										 |  |  | const splitOpenSym = Symbol('splitOpen'); | 
					
						
							|  |  |  | const splitOpen = jest.fn().mockReturnValue(splitOpenSym); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  | jest.mock('app/features/explore/state/main', () => ({ | 
					
						
							|  |  |  |   ...jest.requireActual('app/features/explore/state/main'), | 
					
						
							| 
									
										
										
										
											2023-06-22 20:00:35 +08:00
										 |  |  |   splitOpen: (arg?: SplitOpenOptions) => { | 
					
						
							|  |  |  |     return splitOpen(arg); | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  | })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  | const logs = dataFrameToLogsModel([dfNow]); | 
					
						
							|  |  |  | const row = logs.rows[0]; | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | const timeZone = 'UTC'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('LogRowContextModal', () => { | 
					
						
							|  |  |  |   const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView; | 
					
						
							| 
									
										
										
										
											2024-12-19 02:03:47 +08:00
										 |  |  |   let uniqueRefIdCounter = 1; | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     window.HTMLElement.prototype.scrollIntoView = jest.fn(); | 
					
						
							| 
									
										
										
										
											2024-12-19 02:03:47 +08:00
										 |  |  |     uniqueRefIdCounter = 1; | 
					
						
							|  |  |  |     getRowContext = jest.fn().mockImplementation(async (_, options) => { | 
					
						
							|  |  |  |       uniqueRefIdCounter += 1; | 
					
						
							|  |  |  |       const refId = `refid_${uniqueRefIdCounter}`; | 
					
						
							|  |  |  |       if (options.direction === LogRowContextQueryDirection.Forward) { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           data: [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               refId, | 
					
						
							|  |  |  |               ...dfBefore, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           data: [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               refId, | 
					
						
							|  |  |  |               ...dfAfter, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  |   afterEach(() => { | 
					
						
							|  |  |  |     window.HTMLElement.prototype.scrollIntoView = originalScrollIntoView; | 
					
						
							|  |  |  |     jest.clearAllMocks(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   it('should not render modal when it is closed', async () => { | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     render( | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={false} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |     await waitFor(() => expect(screen.queryByText('Log context')).not.toBeInTheDocument()); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should render modal when it is open', async () => { | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     render( | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await waitFor(() => expect(screen.queryByText('Log context')).toBeInTheDocument()); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   it('should call getRowContext on open and change of row', async () => { | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     render( | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={false} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |     await waitFor(() => expect(getRowContext).not.toHaveBeenCalled()); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |   it('should call getRowContext on open', async () => { | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  |     await waitFor(() => expect(getRowContext).toHaveBeenCalledTimes(2)); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |   it('should render 3 lines containing `foo123`', async () => { | 
					
						
							| 
									
										
										
										
											2023-06-02 02:39:13 +08:00
										 |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							| 
									
										
										
										
											2023-06-02 02:39:13 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |     // there need to be 2 lines with that message. 1 in before, 1 in now, 1 in after
 | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |     await waitFor(() => expect(screen.getAllByText('foo123').length).toBe(3)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should render 3 lines containing `foo123` with the same ms timestamp', async () => { | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |     const dfBeforeNs = createDataFrame({ | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |       fields: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'time', | 
					
						
							|  |  |  |           type: FieldType.time, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |           values: [1, 1], | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'message', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['foo123', 'foo123'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'tsNs', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |           values: ['1', '2'], | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |     const dfNowNs = createDataFrame({ | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |       fields: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'time', | 
					
						
							|  |  |  |           type: FieldType.time, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |           values: [1], | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'message', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['foo123'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'tsNs', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |           values: ['2'], | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |     const dfAfterNs = createDataFrame({ | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |       fields: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'time', | 
					
						
							|  |  |  |           type: FieldType.time, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |           values: [1, 1], | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'message', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['foo123', 'foo123'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'tsNs', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |           values: ['2', '3'], | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let uniqueRefIdCounter = 1; | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |     const logs = dataFrameToLogsModel([dfNowNs]); | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |     const row = logs.rows[0]; | 
					
						
							|  |  |  |     const getRowContext = jest.fn().mockImplementation(async (_, options) => { | 
					
						
							|  |  |  |       uniqueRefIdCounter += 1; | 
					
						
							|  |  |  |       const refId = `refid_${uniqueRefIdCounter}`; | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |       if (uniqueRefIdCounter === 2) { | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         return { | 
					
						
							|  |  |  |           data: [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               refId, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |               ...dfBeforeNs, | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |             }, | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |       } else if (uniqueRefIdCounter === 3) { | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |         return { | 
					
						
							|  |  |  |           data: [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               refId, | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |               ...dfAfterNs, | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |             }, | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  |       return { data: [] }; | 
					
						
							| 
									
										
										
										
											2023-07-11 16:00:10 +08:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-07-11 22:20:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // there need to be 3 lines with that message. 1 in before, 1 in now, 1 in after
 | 
					
						
							|  |  |  |     await waitFor(() => { | 
					
						
							|  |  |  |       expect(screen.getAllByText('foo123').length).toBe(3); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-06-02 02:39:13 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-09 18:56:48 +08:00
										 |  |  |   it('should highlight the same `foo123` searchwords', async () => { | 
					
						
							|  |  |  |     const dfBeforeNs = createDataFrame({ | 
					
						
							|  |  |  |       fields: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'time', | 
					
						
							|  |  |  |           type: FieldType.time, | 
					
						
							|  |  |  |           values: [1, 1], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'message', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['this contains foo123', 'this contains foo123'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'tsNs', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['1', '2'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     const dfNowNs = createDataFrame({ | 
					
						
							|  |  |  |       fields: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'time', | 
					
						
							|  |  |  |           type: FieldType.time, | 
					
						
							|  |  |  |           values: [1], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'message', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['this contains foo123'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'tsNs', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['2'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     const dfAfterNs = createDataFrame({ | 
					
						
							|  |  |  |       fields: [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'time', | 
					
						
							|  |  |  |           type: FieldType.time, | 
					
						
							|  |  |  |           values: [1, 1], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'message', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['this contains foo123', 'this contains foo123'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           name: 'tsNs', | 
					
						
							|  |  |  |           type: FieldType.string, | 
					
						
							|  |  |  |           values: ['2', '3'], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let uniqueRefIdCounter = 1; | 
					
						
							|  |  |  |     const logs = dataFrameToLogsModel([dfNowNs]); | 
					
						
							|  |  |  |     const row = logs.rows[0]; | 
					
						
							|  |  |  |     row.searchWords = ['foo123']; | 
					
						
							|  |  |  |     const getRowContext = jest.fn().mockImplementation(async (_, options) => { | 
					
						
							|  |  |  |       uniqueRefIdCounter += 1; | 
					
						
							|  |  |  |       const refId = `refid_${uniqueRefIdCounter}`; | 
					
						
							|  |  |  |       if (uniqueRefIdCounter === 2) { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           data: [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               refId, | 
					
						
							|  |  |  |               ...dfBeforeNs, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } else if (uniqueRefIdCounter === 3) { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           data: [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               refId, | 
					
						
							|  |  |  |               ...dfAfterNs, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return { data: [] }; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // there need to be 3 lines with that message, all `foo123` should be highlighted
 | 
					
						
							|  |  |  |     await waitFor(() => { | 
					
						
							|  |  |  |       expect(screen.getAllByText('foo123').length).toBe(3); | 
					
						
							|  |  |  |       for (const el of screen.getAllByText('foo123')) { | 
					
						
							|  |  |  |         // highlights are done in `<mark>` tags
 | 
					
						
							|  |  |  |         expect(el.tagName).toBe('MARK'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       // test that the rest is not in a MARK
 | 
					
						
							|  |  |  |       expect(screen.getAllByText('this contains')[0].tagName).not.toBe('MARK'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   it('should show a split view button', async () => { | 
					
						
							|  |  |  |     const getRowContextQuery = jest.fn().mockResolvedValue({ datasource: { uid: 'test-uid' } }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         getRowContextQuery={getRowContextQuery} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await waitFor(() => | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         screen.getByRole('button', { | 
					
						
							|  |  |  |           name: /open in split view/i, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       ).toBeInTheDocument() | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not show a split view button', async () => { | 
					
						
							|  |  |  |     render( | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     await waitFor(() => { | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         screen.queryByRole('button', { | 
					
						
							|  |  |  |           name: /open in split view/i, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       ).not.toBeInTheDocument(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should call getRowContextQuery', async () => { | 
					
						
							|  |  |  |     const getRowContextQuery = jest.fn().mockResolvedValue({ datasource: { uid: 'test-uid' } }); | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         getRowContextQuery={getRowContextQuery} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-02 02:39:13 +08:00
										 |  |  |     await waitFor(() => expect(getRowContextQuery).toHaveBeenCalledTimes(2)); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should close modal', async () => { | 
					
						
							|  |  |  |     const getRowContextQuery = jest.fn().mockResolvedValue({ datasource: { uid: 'test-uid' } }); | 
					
						
							|  |  |  |     const onClose = jest.fn(); | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={onClose} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         getRowContextQuery={getRowContextQuery} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const splitViewButton = await screen.findByRole('button', { | 
					
						
							|  |  |  |       name: /open in split view/i, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await userEvent.click(splitViewButton); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-23 16:20:07 +08:00
										 |  |  |     await waitFor(() => expect(onClose).toHaveBeenCalled()); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:00:35 +08:00
										 |  |  |   it('should create correct splitOpen', async () => { | 
					
						
							|  |  |  |     const queryObj = { datasource: { uid: 'test-uid' } }; | 
					
						
							|  |  |  |     const getRowContextQuery = jest.fn().mockResolvedValue(queryObj); | 
					
						
							|  |  |  |     const onClose = jest.fn(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={onClose} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         getRowContextQuery={getRowContextQuery} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							| 
									
										
										
										
											2023-06-22 20:00:35 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const splitViewButton = await screen.findByRole('button', { | 
					
						
							|  |  |  |       name: /open in split view/i, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await userEvent.click(splitViewButton); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await waitFor(() => | 
					
						
							|  |  |  |       expect(splitOpen).toHaveBeenCalledWith( | 
					
						
							|  |  |  |         expect.objectContaining({ | 
					
						
							|  |  |  |           queries: [queryObj], | 
					
						
							|  |  |  |           panelsState: { | 
					
						
							|  |  |  |             logs: { | 
					
						
							|  |  |  |               id: row.uid, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   it('should dispatch splitOpen', async () => { | 
					
						
							|  |  |  |     const getRowContextQuery = jest.fn().mockResolvedValue({ datasource: { uid: 'test-uid' } }); | 
					
						
							|  |  |  |     const onClose = jest.fn(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={onClose} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         getRowContextQuery={getRowContextQuery} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							| 
									
										
										
										
											2023-06-28 16:51:16 +08:00
										 |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const splitViewButton = await screen.findByRole('button', { | 
					
						
							|  |  |  |       name: /open in split view/i, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await userEvent.click(splitViewButton); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:00:35 +08:00
										 |  |  |     await waitFor(() => expect(dispatchMock).toHaveBeenCalledWith(splitOpenSym)); | 
					
						
							| 
									
										
										
										
											2023-04-20 20:21:14 +08:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2023-06-28 21:22:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should make the center row sticky on load', async () => { | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await waitFor(() => { | 
					
						
							|  |  |  |       const rows = screen.getByTestId('entry-row'); | 
					
						
							|  |  |  |       expect(rows).toHaveStyle('position: sticky'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should make the center row unsticky on unPinClick', async () => { | 
					
						
							|  |  |  |     render( | 
					
						
							|  |  |  |       <LogRowContextModal | 
					
						
							|  |  |  |         row={row} | 
					
						
							|  |  |  |         open={true} | 
					
						
							|  |  |  |         onClose={() => {}} | 
					
						
							|  |  |  |         getRowContext={getRowContext} | 
					
						
							|  |  |  |         timeZone={timeZone} | 
					
						
							|  |  |  |         logsSortOrder={LogsSortOrder.Descending} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await waitFor(() => { | 
					
						
							|  |  |  |       const rows = screen.getByTestId('entry-row'); | 
					
						
							|  |  |  |       expect(rows).toHaveStyle('position: sticky'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     const unpinButtons = screen.getAllByLabelText('Unpin line')[0]; | 
					
						
							| 
									
										
										
										
											2023-07-14 19:49:08 +08:00
										 |  |  |     fireEvent.click(unpinButtons); | 
					
						
							|  |  |  |     await waitFor(() => { | 
					
						
							|  |  |  |       const rows = screen.getByTestId('entry-row'); | 
					
						
							|  |  |  |       expect(rows).not.toHaveStyle('position: sticky'); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-06-28 21:22:54 +08:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2023-04-14 23:05:43 +08:00
										 |  |  | }); |