diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx index d9b2d184625f..4079ba1e6d8c 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx @@ -1,3 +1,4 @@ +/* eslint-disable sonarjs/no-duplicate-string */ /* eslint-disable react/jsx-props-no-spreading */ import { act, @@ -90,6 +91,11 @@ const renderWithContext = (props = {}): RenderResult => { ); }; +// Constants to fix linter errors +const TYPE_TAG = 'tag'; +const IS_COLUMN_FALSE = false; +const IS_JSON_FALSE = false; + const mockAggregateKeysData = { payload: { attributeKeys: [ @@ -97,11 +103,19 @@ const mockAggregateKeysData = { // eslint-disable-next-line sonarjs/no-duplicate-string key: 'http.status', dataType: DataTypes.String, - type: 'tag', - isColumn: false, - isJSON: false, + type: TYPE_TAG, + isColumn: IS_COLUMN_FALSE, + isJSON: IS_JSON_FALSE, id: 'http.status--string--tag--false', }, + { + key: 'service.name', + dataType: DataTypes.String, + type: TYPE_TAG, + isColumn: IS_COLUMN_FALSE, + isJSON: IS_JSON_FALSE, + id: 'service.name--string--tag--false', + }, ], }, }; @@ -127,6 +141,34 @@ jest.mock('hooks/queryBuilder/useGetAggregateValues', () => ({ })), })); +// Mock the dynamic variables hook to test variable suggestion feature +const mockDynamicVariables = [ + { + id: 'var1', + name: 'service', + type: 'DYNAMIC', + dynamicVariablesAttribute: 'service.name', + dynamicVariablesSource: 'Traces', + selectedValue: 'frontend', + multiSelect: false, + showALLOption: false, + allSelected: false, + description: '', + sort: 'DISABLED', + dashboardName: 'Test Dashboard', + dashboardId: 'dashboard-123', + }, +]; + +jest.mock('hooks/dashboard/useGetDynamicVariables', () => ({ + useGetDynamicVariables: jest.fn(() => ({ + dynamicVariables: mockDynamicVariables, + isLoading: false, + isError: false, + refetch: jest.fn(), + })), +})); + jest.mock('hooks/useSafeNavigate', () => ({ useSafeNavigate: (): any => ({ safeNavigate: jest.fn(), @@ -195,3 +237,66 @@ describe('Suggestion Key -> Operator -> Value Flow', () => { ); }); }); + +describe('Dynamic Variable Suggestions', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should suggest dynamic variable when key matches a variable attribute', async () => { + const { container } = renderWithContext(); + + // Get the combobox input + const combobox = container.querySelector( + '.query-builder-search-v2 .ant-select-selection-search-input', + ) as HTMLInputElement; + + // Focus and type to trigger key suggestions for service.name + await act(async () => { + fireEvent.focus(combobox); + fireEvent.change(combobox, { target: { value: 'service.' } }); + }); + + // Wait for dropdown to appear + await screen.findByRole('listbox'); + + // Select service.name key from suggestions + const serviceNameOption = await screen.findByText('service.name'); + await act(async () => { + fireEvent.click(serviceNameOption); + }); + + // Select equals operator + await act(async () => { + const equalsOption = screen.getByText('='); + fireEvent.click(equalsOption); + }); + + // Should show value suggestions including the dynamic variable + // For 'service.name', we expect to see '$service' as the first suggestion + const variableSuggestion = await screen.findByText('$service'); + expect(variableSuggestion).toBeInTheDocument(); + + // Regular values should still be shown + expect(screen.getByText('200')).toBeInTheDocument(); + expect(screen.getByText('404')).toBeInTheDocument(); + + // Select the variable suggestion + await act(async () => { + fireEvent.click(variableSuggestion); + }); + + // Verify the query was updated with the variable as value + expect(mockOnChange).toHaveBeenCalledWith( + expect.objectContaining({ + items: expect.arrayContaining([ + expect.objectContaining({ + key: expect.objectContaining({ key: 'service.name' }), + op: '=', + value: '$service', + }), + ]), + }), + ); + }); +});