| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   CoreApp, | 
					
						
							|  |  |  |   DataFrame, | 
					
						
							|  |  |  |   DataQueryError, | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |   getDefaultTimeRange, | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  |   DataSourceApi, | 
					
						
							|  |  |  |   dateTime, | 
					
						
							|  |  |  |   LoadingState, | 
					
						
							|  |  |  |   PanelData, | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |   DataQueryRequest, | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  | } from '@grafana/data'; | 
					
						
							| 
									
										
										
										
											2022-04-22 21:33:13 +08:00
										 |  |  | import { MetaAnalyticsEventName, reportMetaAnalytics } from '@grafana/runtime'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 22:04:14 +08:00
										 |  |  | import { createDashboardModelFixture } from '../../dashboard/state/__fixtures__/dashboardFixtures'; | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-22 21:33:13 +08:00
										 |  |  | import { emitDataRequestEvent } from './queryAnalytics'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  | beforeEach(() => { | 
					
						
							|  |  |  |   jest.clearAllMocks(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const datasource = { | 
					
						
							|  |  |  |   name: 'test', | 
					
						
							|  |  |  |   id: 1, | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  |   uid: 'test', | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  | } as DataSourceApi; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 22:04:14 +08:00
										 |  |  | const dashboardModel = createDashboardModelFixture( | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |   { id: 1, title: 'Test Dashboard', uid: 'test' }, | 
					
						
							|  |  |  |   { folderTitle: 'Test Folder' } | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | jest.mock('app/features/dashboard/services/DashboardSrv', () => ({ | 
					
						
							|  |  |  |   getDashboardSrv: () => { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       getCurrent: () => dashboardModel, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | jest.mock('@grafana/runtime', () => ({ | 
					
						
							| 
									
										
										
										
											2022-06-22 00:48:38 +08:00
										 |  |  |   ...jest.requireActual('@grafana/runtime'), | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |   reportMetaAnalytics: jest.fn(), | 
					
						
							|  |  |  | })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const mockGetUrlSearchParams = jest.fn(() => { | 
					
						
							|  |  |  |   return {}; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | jest.mock('@grafana/data', () => ({ | 
					
						
							| 
									
										
										
										
											2022-06-22 00:48:38 +08:00
										 |  |  |   ...jest.requireActual('@grafana/data'), | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |   urlUtil: { | 
					
						
							|  |  |  |     getUrlSearchParams: () => mockGetUrlSearchParams(), | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-21 23:16:13 +08:00
										 |  |  | const partiallyCachedSeries = [ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     refId: 'A', | 
					
						
							|  |  |  |     meta: { | 
					
						
							|  |  |  |       isCachedResponse: true, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     fields: [], | 
					
						
							|  |  |  |     length: 0, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     refId: 'B', | 
					
						
							|  |  |  |     fields: [], | 
					
						
							|  |  |  |     length: 0, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const multipleDataframesWithSameRefId = [ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     refId: 'A', | 
					
						
							|  |  |  |     meta: { | 
					
						
							|  |  |  |       isCachedResponse: true, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     fields: [], | 
					
						
							|  |  |  |     length: 0, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     refId: 'A', | 
					
						
							|  |  |  |     fields: [], | 
					
						
							|  |  |  |     length: 0, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  | function getTestData( | 
					
						
							|  |  |  |   overrides: Partial<DataQueryRequest> = {}, | 
					
						
							|  |  |  |   series?: DataFrame[], | 
					
						
							|  |  |  |   errors?: DataQueryError[] | 
					
						
							|  |  |  | ): PanelData { | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |   const now = dateTime(); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     request: { | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |       app: CoreApp.Dashboard, | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |       startTime: now.unix(), | 
					
						
							|  |  |  |       endTime: now.add(1, 's').unix(), | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |       interval: '1s', | 
					
						
							|  |  |  |       intervalMs: 1000, | 
					
						
							|  |  |  |       range: getDefaultTimeRange(), | 
					
						
							|  |  |  |       requestId: '1', | 
					
						
							|  |  |  |       scopedVars: {}, | 
					
						
							|  |  |  |       targets: [], | 
					
						
							|  |  |  |       timezone: 'utc', | 
					
						
							| 
									
										
										
										
											2024-02-21 16:38:42 +08:00
										 |  |  |       panelPluginId: 'timeseries', | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |       ...overrides, | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |     series: series || [], | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  |     state: LoadingState.Done, | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |     timeRange: getDefaultTimeRange(), | 
					
						
							|  |  |  |     errors, | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  | describe('emitDataRequestEvent', () => { | 
					
						
							|  |  |  |   describe('From a dashboard panel', () => { | 
					
						
							|  |  |  |     it('Should report meta analytics', () => { | 
					
						
							|  |  |  |       const data = getTestData({ | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |         panelId: 2, | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |       }); | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							| 
									
										
										
										
											2022-04-21 23:16:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith( | 
					
						
							|  |  |  |         expect.objectContaining({ | 
					
						
							|  |  |  |           eventName: MetaAnalyticsEventName.DataRequest, | 
					
						
							|  |  |  |           datasourceName: datasource.name, | 
					
						
							|  |  |  |           datasourceUid: datasource.uid, | 
					
						
							|  |  |  |           datasourceType: datasource.type, | 
					
						
							|  |  |  |           source: CoreApp.Dashboard, | 
					
						
							|  |  |  |           panelId: 2, | 
					
						
							|  |  |  |           dashboardUid: 'test', // from dashboard srv
 | 
					
						
							|  |  |  |           dataSize: 0, | 
					
						
							|  |  |  |           duration: 1, | 
					
						
							|  |  |  |           totalQueries: 0, | 
					
						
							|  |  |  |           cachedQueries: 0, | 
					
						
							| 
									
										
										
										
											2024-02-21 16:38:42 +08:00
										 |  |  |           panelPluginId: 'timeseries', | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('Should report meta analytics with counts for cached and total queries', () => { | 
					
						
							|  |  |  |       const data = getTestData( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           panelId: 2, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         partiallyCachedSeries | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith( | 
					
						
							|  |  |  |         expect.objectContaining({ | 
					
						
							|  |  |  |           eventName: MetaAnalyticsEventName.DataRequest, | 
					
						
							|  |  |  |           datasourceName: datasource.name, | 
					
						
							|  |  |  |           datasourceUid: datasource.uid, | 
					
						
							|  |  |  |           datasourceType: datasource.type, | 
					
						
							|  |  |  |           source: CoreApp.Dashboard, | 
					
						
							|  |  |  |           panelId: 2, | 
					
						
							|  |  |  |           dashboardUid: 'test', | 
					
						
							|  |  |  |           dataSize: 2, | 
					
						
							|  |  |  |           duration: 1, | 
					
						
							|  |  |  |           totalQueries: 2, | 
					
						
							|  |  |  |           cachedQueries: 1, | 
					
						
							| 
									
										
										
										
											2024-02-21 16:38:42 +08:00
										 |  |  |           panelPluginId: 'timeseries', | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('Should report meta analytics with counts for cached and total queries when same refId spread across multiple DataFrames', () => { | 
					
						
							|  |  |  |       const data = getTestData( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           panelId: 2, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         multipleDataframesWithSameRefId | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith( | 
					
						
							|  |  |  |         expect.objectContaining({ | 
					
						
							|  |  |  |           eventName: MetaAnalyticsEventName.DataRequest, | 
					
						
							|  |  |  |           datasourceName: datasource.name, | 
					
						
							|  |  |  |           datasourceUid: datasource.uid, | 
					
						
							|  |  |  |           datasourceType: datasource.type, | 
					
						
							|  |  |  |           source: CoreApp.Dashboard, | 
					
						
							|  |  |  |           panelId: 2, | 
					
						
							|  |  |  |           dashboardUid: 'test', // from dashboard srv
 | 
					
						
							|  |  |  |           dataSize: 2, | 
					
						
							|  |  |  |           duration: 1, | 
					
						
							|  |  |  |           totalQueries: 1, | 
					
						
							|  |  |  |           cachedQueries: 1, | 
					
						
							| 
									
										
										
										
											2024-02-21 16:38:42 +08:00
										 |  |  |           panelPluginId: 'timeseries', | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('Should not report meta analytics twice if the request receives multiple responses', () => { | 
					
						
							|  |  |  |       const data = getTestData(); | 
					
						
							|  |  |  |       const fn = emitDataRequestEvent(datasource); | 
					
						
							|  |  |  |       fn(data); | 
					
						
							|  |  |  |       fn(data); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('Should not report meta analytics in edit mode', () => { | 
					
						
							|  |  |  |       mockGetUrlSearchParams.mockImplementationOnce(() => { | 
					
						
							|  |  |  |         return { editPanel: 2 }; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       const data = getTestData(); | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).not.toBeCalled(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-04-21 23:16:13 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |   // Previously we filtered out Explore and Correlations events due to too many errors being generated while a user is building a query
 | 
					
						
							|  |  |  |   // This tests that we send an event for both queries but do not record errors
 | 
					
						
							|  |  |  |   describe('From Explore', () => { | 
					
						
							|  |  |  |     const data = getTestData( | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         app: CoreApp.Explore, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       undefined, | 
					
						
							|  |  |  |       [{ message: 'test error' }] | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |     it('Should report meta analytics', () => { | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith( | 
					
						
							|  |  |  |         expect.objectContaining({ | 
					
						
							|  |  |  |           eventName: MetaAnalyticsEventName.DataRequest, | 
					
						
							|  |  |  |           source: CoreApp.Explore, | 
					
						
							|  |  |  |           datasourceName: 'test', | 
					
						
							|  |  |  |           datasourceUid: 'test', | 
					
						
							|  |  |  |           dataSize: 0, | 
					
						
							|  |  |  |           duration: 1, | 
					
						
							|  |  |  |           totalQueries: 0, | 
					
						
							| 
									
										
										
										
											2024-02-21 16:38:42 +08:00
										 |  |  |           panelPluginId: 'timeseries', | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('Should not report errors', () => { | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith(expect.not.objectContaining({ error: 'test error' })); | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |   // Previously we filtered out Explore and Correlations events due to too many errors being generated while a user is building a query
 | 
					
						
							|  |  |  |   // This tests that we send an event for both queries but do not record errors
 | 
					
						
							|  |  |  |   describe('From Correlations', () => { | 
					
						
							|  |  |  |     const data = getTestData( | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         app: CoreApp.Correlations, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       undefined, | 
					
						
							|  |  |  |       [{ message: 'some error' }] | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |     it('Should report meta analytics', () => { | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith( | 
					
						
							|  |  |  |         expect.objectContaining({ | 
					
						
							|  |  |  |           eventName: MetaAnalyticsEventName.DataRequest, | 
					
						
							|  |  |  |           source: CoreApp.Correlations, | 
					
						
							|  |  |  |           datasourceName: 'test', | 
					
						
							|  |  |  |           datasourceUid: 'test', | 
					
						
							|  |  |  |           dataSize: 0, | 
					
						
							|  |  |  |           duration: 1, | 
					
						
							|  |  |  |           totalQueries: 0, | 
					
						
							| 
									
										
										
										
											2024-02-21 16:38:42 +08:00
										 |  |  |           panelPluginId: 'timeseries', | 
					
						
							| 
									
										
										
										
											2023-11-16 00:32:28 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-08 04:19:35 +08:00
										 |  |  |     it('Should not report errors', () => { | 
					
						
							|  |  |  |       emitDataRequestEvent(datasource)(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledTimes(1); | 
					
						
							|  |  |  |       expect(reportMetaAnalytics).toBeCalledWith(expect.not.objectContaining({ error: 'test error' })); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-09-30 14:29:33 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | }); |