diff --git a/public/app/features/dashboard/state/analyticsProcessor.test.ts b/public/app/features/dashboard/state/analyticsProcessor.test.ts new file mode 100644 index 00000000000..5cd1590d1bf --- /dev/null +++ b/public/app/features/dashboard/state/analyticsProcessor.test.ts @@ -0,0 +1,106 @@ +import { MetaAnalyticsEventName, reportMetaAnalytics } from '@grafana/runtime'; +import { CoreApp, DataQueryRequest, DataSourceApi, dateTime, LoadingState, PanelData } from '@grafana/data'; +import { emitDataRequestEvent } from './analyticsProcessor'; +import { DashboardModel } from './DashboardModel'; + +beforeEach(() => { + jest.clearAllMocks(); +}); + +const datasource = { + name: 'test', + id: 1, +} as DataSourceApi; + +const dashboardModel = new DashboardModel( + { 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', () => ({ + ...(jest.requireActual('@grafana/runtime') as any), + reportMetaAnalytics: jest.fn(), +})); + +const mockGetUrlSearchParams = jest.fn(() => { + return {}; +}); +jest.mock('@grafana/data', () => ({ + ...(jest.requireActual('@grafana/data') as any), + urlUtil: { + getUrlSearchParams: () => mockGetUrlSearchParams(), + }, +})); + +function getTestData(requestApp: string): PanelData { + const now = dateTime(); + return { + request: { + app: requestApp, + dashboardId: 1, + panelId: 2, + startTime: now.unix(), + endTime: now.add(1, 's').unix(), + } as DataQueryRequest, + series: [], + state: LoadingState.Done, + timeRange: { + from: dateTime(), + to: dateTime(), + raw: { from: '1h', to: 'now' }, + }, + }; +} + +describe('emitDataRequestEvent - from a dashboard panel', () => { + const data = getTestData(CoreApp.Dashboard); + const fn = emitDataRequestEvent(datasource); + it('Should report meta analytics', () => { + fn(data); + + expect(reportMetaAnalytics).toBeCalledTimes(1); + expect(reportMetaAnalytics).toBeCalledWith( + expect.objectContaining({ + eventName: MetaAnalyticsEventName.DataRequest, + datasourceName: datasource.name, + datasourceId: datasource.id, + panelId: 2, + dashboardId: 1, + dashboardName: 'Test Dashboard', + dashboardUid: 'test', + folderName: 'Test Folder', + dataSize: 0, + duration: 1, + }) + ); + }); + + it('Should not report meta analytics twice if the request receives multiple responses', () => { + fn(data); + expect(reportMetaAnalytics).not.toBeCalled(); + }); + + it('Should not report meta analytics in edit mode', () => { + mockGetUrlSearchParams.mockImplementationOnce(() => { + return { editPanel: 2 }; + }); + emitDataRequestEvent(datasource)(data); + expect(reportMetaAnalytics).not.toBeCalled(); + }); +}); + +describe('emitDataRequestEvent - from Explore', () => { + const data = getTestData(CoreApp.Explore); + it('Should not report meta analytics', () => { + emitDataRequestEvent(datasource)(data); + expect(reportMetaAnalytics).not.toBeCalled(); + }); +}); diff --git a/public/app/features/dashboard/state/analyticsProcessor.ts b/public/app/features/dashboard/state/analyticsProcessor.ts index dde389fa8c4..9fe1caf6049 100644 --- a/public/app/features/dashboard/state/analyticsProcessor.ts +++ b/public/app/features/dashboard/state/analyticsProcessor.ts @@ -1,7 +1,7 @@ import { getDashboardSrv } from '../services/DashboardSrv'; import { DashboardModel } from './DashboardModel'; -import { PanelData, LoadingState, DataSourceApi } from '@grafana/data'; +import { PanelData, LoadingState, DataSourceApi, CoreApp, urlUtil } from '@grafana/data'; import { reportMetaAnalytics, @@ -14,11 +14,12 @@ export function emitDataRequestEvent(datasource: DataSourceApi) { let done = false; return (data: PanelData) => { - if (!data.request || done) { + if (!data.request || done || data.request.app === CoreApp.Explore) { return; } - if (data.request.exploreMode) { + const params = urlUtil.getUrlSearchParams(); + if (params.editPanel != null) { return; }