From 975edf14dcc918fa309996fee17c2b7cca3a56bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Jamr=C3=B3z?= Date: Tue, 5 Sep 2023 13:05:11 +0200 Subject: [PATCH] Explore: Unify spec setup (#73994) * Simplify Explore spec setup * Update public/app/features/explore/spec/helper/setup.tsx Co-authored-by: Giordano Ricci --------- Co-authored-by: Giordano Ricci --- .../explore/spec/datasourceState.test.tsx | 6 -- .../features/explore/spec/helper/setup.tsx | 58 ++++++++++++++++++- .../explore/spec/interpolation.test.tsx | 14 ++--- .../app/features/explore/spec/query.test.tsx | 13 ----- .../explore/spec/queryHistory.test.tsx | 36 +++++------- .../app/features/explore/spec/split.test.tsx | 16 ++--- 6 files changed, 80 insertions(+), 63 deletions(-) diff --git a/public/app/features/explore/spec/datasourceState.test.tsx b/public/app/features/explore/spec/datasourceState.test.tsx index 69b3a1bf8dca..032fa054ae70 100644 --- a/public/app/features/explore/spec/datasourceState.test.tsx +++ b/public/app/features/explore/spec/datasourceState.test.tsx @@ -6,12 +6,6 @@ import { changeDatasource } from './helper/interactions'; import { makeLogsQueryResponse } from './helper/query'; import { setupExplore, tearDown, waitForExplore } from './helper/setup'; -jest.mock('../../correlations/utils', () => { - return { - getCorrelationsBySourceUIDs: jest.fn().mockReturnValue({ correlations: [] }), - }; -}); - const testEventBus = new EventBusSrv(); jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/features/explore/spec/helper/setup.tsx b/public/app/features/explore/spec/helper/setup.tsx index aa2958badc7f..5b5a392d79bf 100644 --- a/public/app/features/explore/spec/helper/setup.tsx +++ b/public/app/features/explore/spec/helper/setup.tsx @@ -6,6 +6,7 @@ import { stringify } from 'querystring'; import React from 'react'; import { Provider } from 'react-redux'; import { Route, Router } from 'react-router-dom'; +import { of } from 'rxjs'; import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; import { @@ -18,10 +19,15 @@ import { import { setDataSourceSrv, setEchoSrv, - setLocationService, + locationService, HistoryWrapper, LocationService, setPluginExtensionGetter, + setBackendSrv, + getBackendSrv, + getDataSourceSrv, + getEchoSrv, + setLocationService, } from '@grafana/runtime'; import { DataSourceRef } from '@grafana/schema'; import { GrafanaContext } from 'app/core/context/GrafanaContext'; @@ -31,6 +37,7 @@ import { setLastUsedDatasourceUID } from 'app/core/utils/explore'; import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource'; import { configureStore } from 'app/store/configureStore'; +import { RichHistoryRemoteStorageDTO } from '../../../../core/history/RichHistoryRemoteStorage'; import { LokiDatasource } from '../../../../plugins/datasource/loki/datasource'; import { LokiQuery } from '../../../../plugins/datasource/loki/types'; import { ExploreQueryParams } from '../../../../types'; @@ -42,10 +49,15 @@ type DatasourceSetup = { settings: DataSourceInstanceSettings; api: DataSourceAp type SetupOptions = { clearLocalStorage?: boolean; datasources?: DatasourceSetup[]; + queryHistory?: { queryHistory: Array>; totalCount: number }; urlParams?: ExploreQueryParams; prevUsedDatasource?: { orgId: number; datasource: string }; }; +type TearDownOptions = { + clearLocalStorage?: boolean; +}; + export function setupExplore(options?: SetupOptions): { datasources: { [uid: string]: DataSourceApi }; store: ReturnType; @@ -53,6 +65,27 @@ export function setupExplore(options?: SetupOptions): { container: HTMLElement; location: LocationService; } { + const previousBackendSrv = getBackendSrv(); + setBackendSrv({ + datasourceRequest: jest.fn().mockRejectedValue(undefined), + delete: jest.fn().mockRejectedValue(undefined), + fetch: jest.fn().mockImplementation((req) => { + const data: Record = {}; + if (req.url.startsWith('/api/datasources/correlations') && req.method === 'GET') { + data.correlations = []; + data.totalCount = 0; + } else if (req.url.startsWith('/api/query-history') && req.method === 'GET') { + data.result = options?.queryHistory || {}; + } + return of({ data }); + }), + get: jest.fn(), + patch: jest.fn().mockRejectedValue(undefined), + post: jest.fn(), + put: jest.fn().mockRejectedValue(undefined), + request: jest.fn().mockRejectedValue(undefined), + }); + setPluginExtensionGetter(() => ({ extensions: [] })); // Clear this up otherwise it persists data source selection @@ -74,6 +107,8 @@ export function setupExplore(options?: SetupOptions): { const dsSettings = options?.datasources || defaultDatasources; + const previousDataSourceSrv = getDataSourceSrv(); + setDataSourceSrv({ getList(): DataSourceInstanceSettings[] { return dsSettings.map((d) => d.settings); @@ -103,6 +138,7 @@ export function setupExplore(options?: SetupOptions): { reload() {}, }); + const previousEchoSrv = getEchoSrv(); setEchoSrv(new Echo()); const storeState = configureStore(); @@ -145,6 +181,16 @@ export function setupExplore(options?: SetupOptions): { ); + exploreTestsHelper.tearDownExplore = (options?: TearDownOptions) => { + setDataSourceSrv(previousDataSourceSrv); + setEchoSrv(previousEchoSrv); + setBackendSrv(previousBackendSrv); + setLocationService(locationService); + if (options?.clearLocalStorage !== false) { + window.localStorage.clear(); + } + }; + return { datasources: fromPairs(dsSettings.map((d) => [d.api.name, d.api])), store: storeState, @@ -227,11 +273,17 @@ export const waitForExplore = (exploreId = 'left') => { }); }; -export const tearDown = () => { - window.localStorage.clear(); +export const tearDown = (options?: TearDownOptions) => { + exploreTestsHelper.tearDownExplore?.(options); }; export const withinExplore = (exploreId: string) => { const container = screen.getAllByTestId('data-testid Explore'); return within(container[exploreId === 'left' ? 0 : 1]); }; + +const exploreTestsHelper: { setupExplore: typeof setupExplore; tearDownExplore?: (options?: TearDownOptions) => void } = + { + setupExplore, + tearDownExplore: undefined, + }; diff --git a/public/app/features/explore/spec/interpolation.test.tsx b/public/app/features/explore/spec/interpolation.test.tsx index 1b41048b2cfe..d910cd0656e0 100644 --- a/public/app/features/explore/spec/interpolation.test.tsx +++ b/public/app/features/explore/spec/interpolation.test.tsx @@ -6,14 +6,12 @@ import { getTemplateSrv } from '@grafana/runtime'; import { LokiQuery } from '../../../plugins/datasource/loki/types'; import { makeLogsQueryResponse } from './helper/query'; -import { setupExplore, waitForExplore } from './helper/setup'; +import { setupExplore, tearDown, waitForExplore } from './helper/setup'; const testEventBus = new EventBusSrv(); -const fetch = jest.fn(); jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), - getBackendSrv: () => ({ fetch }), getAppEvents: () => testEventBus, })); @@ -33,13 +31,11 @@ jest.mock('react-virtualized-auto-sizer', () => { }; }); -jest.mock('../../correlations/utils', () => { - return { - getCorrelationsBySourceUIDs: jest.fn().mockReturnValue({ correlations: [] }), - }; -}); - describe('Explore: interpolation', () => { + afterEach(() => { + tearDown(); + }); + // support-escalations/issues/1459 it('Time is interpolated when explore is opened with a URL', async () => { const urlParams = { diff --git a/public/app/features/explore/spec/query.test.tsx b/public/app/features/explore/spec/query.test.tsx index 13d6c6705083..492b9dcde2a6 100644 --- a/public/app/features/explore/spec/query.test.tsx +++ b/public/app/features/explore/spec/query.test.tsx @@ -12,19 +12,6 @@ jest.mock('@grafana/runtime', () => ({ getAppEvents: () => testEventBus, })); -jest.mock('../../correlations/utils', () => { - return { - getCorrelationsBySourceUIDs: jest.fn().mockReturnValue({ correlations: [] }), - }; -}); - -jest.mock('app/core/core', () => ({ - contextSrv: { - hasAccess: () => true, - getValidIntervals: (defaultIntervals: string[]) => defaultIntervals, - }, -})); - describe('Explore: handle running/not running query', () => { afterEach(() => { tearDown(); diff --git a/public/app/features/explore/spec/queryHistory.test.tsx b/public/app/features/explore/spec/queryHistory.test.tsx index 8cd35ce02c5c..69df5461c400 100644 --- a/public/app/features/explore/spec/queryHistory.test.tsx +++ b/public/app/features/explore/spec/queryHistory.test.tsx @@ -1,7 +1,6 @@ import React from 'react'; -import { of } from 'rxjs'; -import { EventBusSrv, serializeStateToUrlParam } from '@grafana/data'; +import { DataQuery, EventBusSrv, serializeStateToUrlParam } from '@grafana/data'; import { config } from '@grafana/runtime'; import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; @@ -33,15 +32,15 @@ import { import { makeLogsQueryResponse } from './helper/query'; import { setupExplore, tearDown, waitForExplore } from './helper/setup'; -const fetchMock = jest.fn(); -const postMock = jest.fn(); -const getMock = jest.fn(); const reportInteractionMock = jest.fn(); const testEventBus = new EventBusSrv(); +interface MockQuery extends DataQuery { + expr: string; +} + jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), - getBackendSrv: () => ({ fetch: fetchMock, post: postMock, get: getMock }), reportInteraction: (...args: object[]) => { reportInteractionMock(...args); }, @@ -79,12 +78,6 @@ jest.mock('react-virtualized-auto-sizer', () => { }; }); -jest.mock('../../correlations/utils', () => { - return { - getCorrelationsBySourceUIDs: jest.fn().mockReturnValue({ correlations: [] }), - }; -}); - describe('Explore: Query History', () => { const USER_INPUT = 'my query'; const RAW_QUERY = `{"expr":"${USER_INPUT}"}`; @@ -93,9 +86,6 @@ describe('Explore: Query History', () => { afterEach(() => { config.queryHistoryEnabled = false; - fetchMock.mockClear(); - postMock.mockClear(); - getMock.mockClear(); reportInteractionMock.mockClear(); tearDown(); }); @@ -116,6 +106,8 @@ describe('Explore: Query History', () => { // when Explore is opened again unmount(); + + tearDown({ clearLocalStorage: false }); setupExplore({ clearLocalStorage: false }); await waitForExplore(); @@ -265,13 +257,15 @@ describe('Explore: Query History', () => { it('pagination', async () => { config.queryHistoryEnabled = true; - const { datasources } = setupExplore(); + + const mockQuery: MockQuery = { refId: 'A', expr: 'query' }; + const { datasources } = setupExplore({ + queryHistory: { + queryHistory: [{ datasourceUid: 'loki', queries: [mockQuery] }], + totalCount: 2, + }, + }); jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse()); - fetchMock.mockReturnValue( - of({ - data: { result: { queryHistory: [{ datasourceUid: 'loki', queries: [{ expr: 'query' }] }], totalCount: 2 } }, - }) - ); await waitForExplore(); await openQueryHistory(); diff --git a/public/app/features/explore/spec/split.test.tsx b/public/app/features/explore/spec/split.test.tsx index a5706a2392cf..547752238204 100644 --- a/public/app/features/explore/spec/split.test.tsx +++ b/public/app/features/explore/spec/split.test.tsx @@ -8,7 +8,7 @@ import { EventBusSrv, serializeStateToUrlParam } from '@grafana/data'; import * as mainState from '../state/main'; import { makeLogsQueryResponse } from './helper/query'; -import { setupExplore, waitForExplore } from './helper/setup'; +import { setupExplore, tearDown, waitForExplore } from './helper/setup'; const testEventBus = new EventBusSrv(); @@ -31,22 +31,16 @@ jest.mock('react-virtualized-auto-sizer', () => { }; }); -const fetch = jest.fn().mockResolvedValue({ correlations: [] }); jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), - getBackendSrv: () => ({ fetch }), getAppEvents: () => testEventBus, })); -jest.mock('rxjs', () => ({ - ...jest.requireActual('rxjs'), - lastValueFrom: () => - new Promise((resolve, reject) => { - resolve({ data: { correlations: [] } }); - }), -})); - describe('Handles open/close splits and related events in UI and URL', () => { + afterEach(() => { + tearDown(); + }); + it('opens the split pane when split button is clicked', async () => { const { location } = setupExplore();