Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix template queries loading and update getSampleQuery interface #8848

Merged
merged 6 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/8848.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fix:
- Fix template queries loading and update getSampleQuery interface ([#8848](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8848))
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,5 @@ export interface DatasetTypeConfig {
/**
* Returns a list of sample queries for this dataset type
*/
getSampleQueries?: (dataset: Dataset, language: string) => any;
getSampleQueries?: (dataset?: Dataset, language?: string) => Promise<any> | any;
jowg-amazon marked this conversation as resolved.
Show resolved Hide resolved
}
4 changes: 3 additions & 1 deletion src/plugins/data/public/ui/filter_bar/filter_options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ import {
import { FilterEditor } from './filter_editor';
import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public';
import { SavedQueryManagementComponent } from '../saved_query_management';
import { SavedQuery, SavedQueryService } from '../../query';
import { QueryStringManager, SavedQuery, SavedQueryService } from '../../query';
import { SavedQueryMeta } from '../saved_query_form';
import { getUseNewSavedQueriesUI } from '../../services';

Expand All @@ -79,6 +79,7 @@ interface Props {
useSaveQueryMenu: boolean;
isQueryEditorControl: boolean;
saveQuery: (savedQueryMeta: SavedQueryMeta, saveAsNew?: boolean) => Promise<void>;
queryStringManager: QueryStringManager;
}
const maxFilterWidth = 600;

Expand Down Expand Up @@ -310,6 +311,7 @@ const FilterOptionsUI = (props: Props) => {
key={'savedQueryManagement'}
useNewSavedQueryUI={getUseNewSavedQueriesUI()}
saveQuery={props.saveQuery}
queryStringManager={props.queryStringManager}
/>,
]}
data-test-subj="save-query-panel"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
import { OpenSavedQueryFlyout } from './open_saved_query_flyout';
import { createSavedQueryService } from '../../../public/query/saved_query/saved_query_service';
import { applicationServiceMock, uiSettingsServiceMock } from '../../../../../core/public/mocks';
import { SavedQueryAttributes } from '../../../public/query/saved_query/types';
import '@testing-library/jest-dom';
import { queryStringManagerMock } from '../../../../data/public/query/query_string/query_string_manager.mock';

const savedQueryAttributesWithTemplate: SavedQueryAttributes = {
title: 'foo',
description: 'bar',
query: {
language: 'kuery',
query: 'response:200',
dataset: 'my_dataset',
},
};

const mockSavedObjectsClient = {
create: jest.fn(),
error: jest.fn(),
find: jest.fn(),
get: jest.fn(),
delete: jest.fn(),
};

mockSavedObjectsClient.create.mockReturnValue({
id: 'foo',
attributes: {
...savedQueryAttributesWithTemplate,
query: {
...savedQueryAttributesWithTemplate.query,
},
},
});

jest.mock('./saved_query_card', () => ({
SavedQueryCard: ({
savedQuery = {
id: 'foo1',
attributes: savedQueryAttributesWithTemplate,
},
onSelect,
handleQueryDelete,
}) => (
<div>
<div>{savedQuery?.attributes?.title}</div>
<button onClick={() => onSelect(savedQuery)}>Select</button>
<button onClick={() => handleQueryDelete(savedQuery)}>Delete</button>
</div>
),
}));

jest.mock('@osd/i18n', () => ({
i18n: {
translate: jest.fn((id, { defaultMessage }) => defaultMessage),
},
}));

const mockSavedQueryService = createSavedQueryService(
// @ts-ignore
mockSavedObjectsClient,
{
application: applicationServiceMock.create(),
uiSettings: uiSettingsServiceMock.createStartContract(),
}
);

const mockHandleQueryDelete = jest.fn();
const mockOnQueryOpen = jest.fn();
const mockOnClose = jest.fn();

const savedQueries = [
{
id: '1',
attributes: {
title: 'Saved Query 1',
description: 'Description for Query 1',
query: { query: 'SELECT * FROM table1', language: 'sql' },
},
},
{
id: '2',
attributes: {
title: 'Saved Query 2',
description: 'Description for Query 2',
query: { query: 'SELECT * FROM table2', language: 'sql' },
},
},
];

jest.spyOn(mockSavedQueryService, 'getAllSavedQueries').mockResolvedValue(savedQueries);

describe('OpenSavedQueryFlyout', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should render the flyout with correct tabs and content', async () => {
render(
<OpenSavedQueryFlyout
savedQueryService={mockSavedQueryService}
onClose={mockOnClose}
onQueryOpen={mockOnQueryOpen}
handleQueryDelete={mockHandleQueryDelete}
queryStringManager={queryStringManagerMock.createSetupContract()}
/>
);

const savedQueriesTextElements = screen.getAllByText('Saved queries');

expect(savedQueriesTextElements).toHaveLength(2);

await waitFor(() => screen.getByPlaceholderText('Search'));

await waitFor(() => screen.getByText('Saved Query 1'));
await waitFor(() => screen.getByText('Saved Query 2'));

const openQueryButton = screen.getByText('Open query');

fireEvent.change(screen.getByPlaceholderText('Search'), { target: { value: 'Saved Query 1' } });

await waitFor(() => screen.getByText('Saved Query 1'));
expect(screen.queryByText('Saved Query 2')).not.toBeInTheDocument();

fireEvent.click(screen.getByText('Saved Query 1'));

expect(openQueryButton).toBeEnabled();
});

it('should filter saved queries based on search input', async () => {
render(
<OpenSavedQueryFlyout
savedQueryService={mockSavedQueryService}
onClose={mockOnClose}
onQueryOpen={mockOnQueryOpen}
handleQueryDelete={mockHandleQueryDelete}
queryStringManager={queryStringManagerMock.createSetupContract()}
/>
);

await waitFor(() => screen.getByText('Saved Query 1'));
await waitFor(() => screen.getByText('Saved Query 2'));

const searchBar = screen.getByPlaceholderText('Search');
fireEvent.change(searchBar, { target: { value: 'Saved Query 1' } });

expect(screen.getByText('Saved Query 1')).toBeInTheDocument();
expect(screen.queryByText('Saved Query 2')).toBeNull();
});

it('should select a query when clicking on it and enable the "Open query" button', async () => {
render(
<OpenSavedQueryFlyout
savedQueryService={mockSavedQueryService}
onClose={mockOnClose}
onQueryOpen={mockOnQueryOpen}
handleQueryDelete={mockHandleQueryDelete}
queryStringManager={queryStringManagerMock.createSetupContract()}
/>
);

await waitFor(() => screen.getByText('Saved Query 1'));

fireEvent.click(screen.getByText('Saved Query 1'));

expect(screen.getByText('Open query')).toBeEnabled();
});

it('should call handleQueryDelete when deleting a query', async () => {
mockHandleQueryDelete.mockResolvedValueOnce();
render(
<OpenSavedQueryFlyout
savedQueryService={mockSavedQueryService}
onClose={mockOnClose}
onQueryOpen={mockOnQueryOpen}
handleQueryDelete={mockHandleQueryDelete}
queryStringManager={queryStringManagerMock.createSetupContract()}
/>
);

await waitFor(() => screen.getByText('Saved Query 1'));

const deleteButtons = screen.getAllByText('Delete');

fireEvent.click(deleteButtons[0]);

await waitFor(() => {
expect(mockHandleQueryDelete).toHaveBeenCalledWith({
id: '1',
attributes: {
description: 'Description for Query 1',
query: {
language: 'sql',
query: 'SELECT * FROM table1',
},
title: 'Saved Query 1',
},
});
});
expect(mockHandleQueryDelete).toHaveBeenCalledTimes(1);
});

it('should handle pagination controls correctly', async () => {
render(
<OpenSavedQueryFlyout
savedQueryService={mockSavedQueryService}
onClose={mockOnClose}
onQueryOpen={mockOnQueryOpen}
handleQueryDelete={mockHandleQueryDelete}
queryStringManager={queryStringManagerMock.createSetupContract()}
/>
);

await waitFor(() => screen.getByText('Saved Query 1'));

const pageSizeButton = await screen.findByText(/10/);
fireEvent.click(pageSizeButton);

expect(mockSavedQueryService.getAllSavedQueries).toHaveBeenCalled();
});
});
Loading
Loading