From 128481735cc9341bdb36efa65041ec994067fd84 Mon Sep 17 00:00:00 2001 From: alexandra vargas Date: Fri, 18 Jul 2025 12:03:07 +0200 Subject: [PATCH] Add QueryEditor.test and useStateSync test --- .../explore/hooks/useStateSync/index.test.tsx | 77 +++++++++++++++++++ .../query/components/QueryEditorRow.test.tsx | 48 +++++++++++- .../query/components/QueryEditorRow.tsx | 2 +- 3 files changed, 122 insertions(+), 5 deletions(-) diff --git a/public/app/features/explore/hooks/useStateSync/index.test.tsx b/public/app/features/explore/hooks/useStateSync/index.test.tsx index 841a220d03e..01aa4046af5 100644 --- a/public/app/features/explore/hooks/useStateSync/index.test.tsx +++ b/public/app/features/explore/hooks/useStateSync/index.test.tsx @@ -12,6 +12,7 @@ import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSou import { configureStore } from 'app/store/configureStore'; import { makeDatasourceSetup } from '../../spec/helper/setup'; +import { updateQueryRefAction } from '../../state/explorePane'; import { splitClose, splitOpen } from '../../state/main'; import { useStateSync } from './'; @@ -584,4 +585,80 @@ describe('useStateSync', () => { expect(store.getState().explore.panes['one']?.queries[0]).toMatchObject({ expr: 'b', refId: 'B' }); }); }); + + it('should sync queryRef from URL to state', async () => { + const { store } = setup({ + queryParams: { + panes: JSON.stringify({ + one: { + datasource: 'loki-uid', + queries: [{ expr: 'test', refId: 'A' }], + queryRef: 'library-query-123', + }, + }), + schemaVersion: 1, + }, + }); + + await waitFor(() => { + expect(store.getState().explore.panes['one']?.queryRef).toBe('library-query-123'); + }); + }); + + it('should sync queryRef from state to URL', async () => { + const { store, location } = setup({ + queryParams: { + panes: JSON.stringify({ + one: { + datasource: 'loki-uid', + queries: [{ expr: 'test', refId: 'A' }], + }, + }), + schemaVersion: 1, + }, + }); + + await waitFor(() => { + expect(store.getState().explore.panes['one']).toBeDefined(); + }); + + act(() => { + store.dispatch(updateQueryRefAction({ exploreId: 'one', queryRef: 'library-query-456' })); + }); + + await waitFor(() => { + const search = location.getSearchObject(); + const panes = search.panes && typeof search.panes === 'string' ? JSON.parse(search.panes) : {}; + expect(panes.one?.queryRef).toBe('library-query-456'); + }); + }); + + it('should handle queryRef cleanup in URL when queryRef is undefined', async () => { + const { store, location } = setup({ + queryParams: { + panes: JSON.stringify({ + one: { + datasource: 'loki-uid', + queries: [{ expr: 'test', refId: 'A' }], + queryRef: 'library-query-123', + }, + }), + schemaVersion: 1, + }, + }); + + await waitFor(() => { + expect(store.getState().explore.panes['one']?.queryRef).toBe('library-query-123'); + }); + + act(() => { + store.dispatch(updateQueryRefAction({ exploreId: 'one', queryRef: undefined })); + }); + + await waitFor(() => { + const search = location.getSearchObject(); + const panes = search.panes && typeof search.panes === 'string' ? JSON.parse(search.panes) : {}; + expect(panes.one?.queryRef).toBeUndefined(); + }); + }); }); diff --git a/public/app/features/query/components/QueryEditorRow.test.tsx b/public/app/features/query/components/QueryEditorRow.test.tsx index 3a9d33542f1..98b1f0cc031 100644 --- a/public/app/features/query/components/QueryEditorRow.test.tsx +++ b/public/app/features/query/components/QueryEditorRow.test.tsx @@ -5,15 +5,28 @@ import { DataQueryRequest, dateTime, LoadingState, PanelData, toDataFrame } from import { DataQuery } from '@grafana/schema'; import { mockDataSource } from 'app/features/alerting/unified/mocks'; -import { DataSourceType } from '../../alerting/unified/utils/datasource'; - -import { filterPanelDataToQuery, Props, QueryEditorRow } from './QueryEditorRow'; +import { filterPanelDataToQuery, Props, QueryEditorRow, QueryLibraryBadgeWrapper } from './QueryEditorRow'; const mockDS = mockDataSource({ name: 'test', - type: DataSourceType.Alertmanager, + type: 'testdata', }); +// Mock the QueryLibraryContext +const mockQueryLibraryContext = { + queryLibraryEnabled: true, +}; + +jest.mock('app/features/explore/QueryLibrary/QueryLibraryContext', () => ({ + useQueryLibraryContext: () => mockQueryLibraryContext, +})); + +// Mock the internationalization function +jest.mock('@grafana/i18n', () => ({ + ...jest.requireActual('@grafana/i18n'), + t: (key: string, defaultValue: string) => defaultValue, +})); + jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), getDataSourceSrv: () => ({ @@ -392,3 +405,30 @@ describe('QueryEditorRow', () => { }); }); }); + +describe('QueryLibraryBadge', () => { + beforeEach(() => { + mockQueryLibraryContext.queryLibraryEnabled = true; + }); + + it('should display badge when queryLibraryEnabled is true and queryRef is provided', () => { + render(); + expect(screen.getByText('Editing From Query Library')).toBeInTheDocument(); + }); + + it('should not display badge when queryLibraryEnabled is false', () => { + mockQueryLibraryContext.queryLibraryEnabled = false; + render(); + expect(screen.queryByText('Editing From Query Library')).not.toBeInTheDocument(); + }); + + it('should not display badge when queryRef is not provided', () => { + render(); + expect(screen.queryByText('Editing From Query Library')).not.toBeInTheDocument(); + }); + + it('should not display badge when queryRef is empty string', () => { + render(); + expect(screen.queryByText('Editing From Query Library')).not.toBeInTheDocument(); + }); +}); diff --git a/public/app/features/query/components/QueryEditorRow.tsx b/public/app/features/query/components/QueryEditorRow.tsx index 8ba101449f9..41330d74228 100644 --- a/public/app/features/query/components/QueryEditorRow.tsx +++ b/public/app/features/query/components/QueryEditorRow.tsx @@ -489,7 +489,7 @@ export class QueryEditorRow extends PureComponent