mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-31 20:51:26 +00:00
* Fixed issue with dropdown options not resetting for different dropdowns * Added unit test for additional checks Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
b959709275
commit
c2c7281018
@ -11,11 +11,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fireEvent, render } from '@testing-library/react';
|
import { act, fireEvent, render } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { getAdvancedFieldDefaultOptions } from '../../axiosAPIs/miscAPI';
|
||||||
import { SearchIndex } from '../../enums/search.enum';
|
import { SearchIndex } from '../../enums/search.enum';
|
||||||
import { ExploreQuickFilterField } from '../Explore/explore.interface';
|
import { ExploreQuickFilterField } from '../Explore/explore.interface';
|
||||||
|
import { SearchDropdownProps } from '../SearchDropdown/SearchDropdown.interface';
|
||||||
import ExploreQuickFilters from './ExploreQuickFilters';
|
import ExploreQuickFilters from './ExploreQuickFilters';
|
||||||
|
import {
|
||||||
|
mockAdvancedFieldDefaultOptions,
|
||||||
|
mockAdvancedFieldOptions,
|
||||||
|
mockTagSuggestions,
|
||||||
|
mockUserSuggestions,
|
||||||
|
} from './mocks/ExploreQuickFilters.mock';
|
||||||
|
|
||||||
const mockOnFieldRemove = jest.fn();
|
const mockOnFieldRemove = jest.fn();
|
||||||
const mockOnAdvanceSearch = jest.fn();
|
const mockOnAdvanceSearch = jest.fn();
|
||||||
@ -28,18 +37,84 @@ const mockOnUpdateFilterValues = jest.fn();
|
|||||||
jest.mock('../SearchDropdown/SearchDropdown', () =>
|
jest.mock('../SearchDropdown/SearchDropdown', () =>
|
||||||
jest
|
jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockReturnValue(<div data-testid="search-dropdown">SearchDropdown</div>)
|
.mockImplementation(
|
||||||
|
({ options, searchKey, onChange, onSearch }: SearchDropdownProps) => (
|
||||||
|
<div
|
||||||
|
data-testid={`search-dropdown-${searchKey}`}
|
||||||
|
key={searchKey}
|
||||||
|
title="search-dropdown">
|
||||||
|
{options.map((option) => (
|
||||||
|
<div data-testid={`option-${searchKey}`} key={option}>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div
|
||||||
|
data-testid={`onSearch-${searchKey}`}
|
||||||
|
onClick={() => onSearch('', searchKey)}>
|
||||||
|
onSearch
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
data-testid={`onChange-${searchKey}`}
|
||||||
|
onClick={() => onChange([''], searchKey)}>
|
||||||
|
onChange
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
jest.mock('./AdvanceSearchModal.component', () => ({
|
jest.mock('./AdvanceSearchModal.component', () => ({
|
||||||
AdvanceSearchModal: jest.fn().mockReturnValue(<p>AdvanceSearchModal</p>),
|
AdvanceSearchModal: jest.fn().mockReturnValue(<p>AdvanceSearchModal</p>),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../axiosAPIs/miscAPI', () => ({
|
||||||
|
getAdvancedFieldDefaultOptions: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(() => Promise.resolve(mockAdvancedFieldDefaultOptions)),
|
||||||
|
getAdvancedFieldOptions: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(() => Promise.resolve(mockAdvancedFieldOptions)),
|
||||||
|
getTagSuggestions: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(() => Promise.resolve(mockTagSuggestions)),
|
||||||
|
getUserSuggestions: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(() => Promise.resolve(mockUserSuggestions)),
|
||||||
|
}));
|
||||||
|
|
||||||
const index = SearchIndex.TABLE;
|
const index = SearchIndex.TABLE;
|
||||||
const fields = [
|
const mockFields: ExploreQuickFilterField[] = [
|
||||||
{ key: 'owner.name', value: undefined },
|
{
|
||||||
{ key: 'column_names', value: undefined },
|
label: 'Column',
|
||||||
] as ExploreQuickFilterField[];
|
key: 'columns.name',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Schema',
|
||||||
|
key: 'databaseSchema.name',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Database',
|
||||||
|
key: 'database.name',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Owner',
|
||||||
|
key: 'owner.name',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tag',
|
||||||
|
key: 'tags.tagFQN',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Service',
|
||||||
|
key: 'service.name',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const onFieldRemove = mockOnFieldRemove;
|
const onFieldRemove = mockOnFieldRemove;
|
||||||
const onAdvanceSearch = mockOnAdvanceSearch;
|
const onAdvanceSearch = mockOnAdvanceSearch;
|
||||||
@ -51,7 +126,7 @@ const onUpdateFilterValues = mockOnUpdateFilterValues;
|
|||||||
|
|
||||||
const mockProps = {
|
const mockProps = {
|
||||||
index,
|
index,
|
||||||
fields,
|
fields: mockFields,
|
||||||
onFieldRemove,
|
onFieldRemove,
|
||||||
onAdvanceSearch,
|
onAdvanceSearch,
|
||||||
onClear,
|
onClear,
|
||||||
@ -63,22 +138,22 @@ const mockProps = {
|
|||||||
|
|
||||||
describe('Test ExploreQuickFilters component', () => {
|
describe('Test ExploreQuickFilters component', () => {
|
||||||
it('Should render ExploreQuickFilters component', async () => {
|
it('Should render ExploreQuickFilters component', async () => {
|
||||||
const { findAllByTestId } = render(<ExploreQuickFilters {...mockProps} />);
|
const { findAllByTitle } = render(<ExploreQuickFilters {...mockProps} />);
|
||||||
|
|
||||||
const fields = await findAllByTestId('search-dropdown');
|
const fields = await findAllByTitle('search-dropdown');
|
||||||
|
|
||||||
expect(fields).toHaveLength(fields.length);
|
expect(fields).toHaveLength(fields.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should call onAdvanceSearch method on click of Advance Search button', async () => {
|
it('Should call onAdvanceSearch method on click of Advance Search button', async () => {
|
||||||
const { findByTestId, findAllByTestId } = render(
|
const { findByTestId, findAllByTitle } = render(
|
||||||
<ExploreQuickFilters {...mockProps} />
|
<ExploreQuickFilters {...mockProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const fields = await findAllByTestId('search-dropdown');
|
const fields = await findAllByTitle('search-dropdown');
|
||||||
const advanceSearchButton = await findByTestId('advance-search-button');
|
const advanceSearchButton = await findByTestId('advance-search-button');
|
||||||
|
|
||||||
expect(fields).toHaveLength(fields.length);
|
expect(fields).toHaveLength(mockFields.length);
|
||||||
|
|
||||||
expect(advanceSearchButton).toBeInTheDocument();
|
expect(advanceSearchButton).toBeInTheDocument();
|
||||||
|
|
||||||
@ -86,4 +161,58 @@ describe('Test ExploreQuickFilters component', () => {
|
|||||||
|
|
||||||
expect(onAdvanceSearch).toBeCalled();
|
expect(onAdvanceSearch).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('All options should be passed to SearchDropdown component for proper API response', async () => {
|
||||||
|
const { findByTestId, findAllByTestId } = render(
|
||||||
|
<ExploreQuickFilters {...mockProps} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const databaseFieldOnSearch = await findByTestId('onSearch-database.name');
|
||||||
|
|
||||||
|
expect(databaseFieldOnSearch).toBeInTheDocument();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
userEvent.click(databaseFieldOnSearch);
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = await findAllByTestId('option-database.name');
|
||||||
|
|
||||||
|
expect(options).toHaveLength(
|
||||||
|
mockAdvancedFieldDefaultOptions.data.aggregations['sterms#database.name']
|
||||||
|
.buckets.length
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('No previous options should be present after getAdvancedFieldDefaultOptions API fails', async () => {
|
||||||
|
const { findByTestId, findAllByTestId, queryAllByTestId } = render(
|
||||||
|
<ExploreQuickFilters {...mockProps} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const databaseFieldOnSearch = await findByTestId('onSearch-database.name');
|
||||||
|
|
||||||
|
expect(databaseFieldOnSearch).toBeInTheDocument();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
userEvent.click(databaseFieldOnSearch);
|
||||||
|
});
|
||||||
|
|
||||||
|
let options = await findAllByTestId('option-database.name');
|
||||||
|
|
||||||
|
expect(options).toHaveLength(
|
||||||
|
mockAdvancedFieldDefaultOptions.data.aggregations['sterms#database.name']
|
||||||
|
.buckets.length
|
||||||
|
);
|
||||||
|
|
||||||
|
(getAdvancedFieldDefaultOptions as jest.Mock).mockImplementationOnce(() =>
|
||||||
|
Promise.reject('not done')
|
||||||
|
);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
userEvent.click(databaseFieldOnSearch);
|
||||||
|
});
|
||||||
|
|
||||||
|
options = queryAllByTestId('option-database.name');
|
||||||
|
|
||||||
|
expect(options).toHaveLength(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -74,6 +74,7 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
|
|||||||
|
|
||||||
const getFilterOptions = async (value: string, key: string) => {
|
const getFilterOptions = async (value: string, key: string) => {
|
||||||
setIsOptionsLoading(true);
|
setIsOptionsLoading(true);
|
||||||
|
setOptions([]);
|
||||||
try {
|
try {
|
||||||
if (value) {
|
if (value) {
|
||||||
await fetchOptions(value, key);
|
await fetchOptions(value, key);
|
||||||
|
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 Collate
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const mockAdvancedFieldDefaultOptions = {
|
||||||
|
data: {
|
||||||
|
took: 3,
|
||||||
|
_shards: {
|
||||||
|
total: 1,
|
||||||
|
successful: 1,
|
||||||
|
skipped: 0,
|
||||||
|
failed: 0,
|
||||||
|
},
|
||||||
|
hits: {
|
||||||
|
total: {
|
||||||
|
value: 84,
|
||||||
|
relation: 'eq',
|
||||||
|
},
|
||||||
|
hits: [],
|
||||||
|
},
|
||||||
|
aggregations: {
|
||||||
|
'sterms#database.name': {
|
||||||
|
buckets: [
|
||||||
|
{
|
||||||
|
key: 'ecommerce_db',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'modified-leaf-330420',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockAdvancedFieldOptions = {
|
||||||
|
data: {
|
||||||
|
suggest: {
|
||||||
|
'metadata-suggest': [
|
||||||
|
{
|
||||||
|
text: 'e',
|
||||||
|
offset: 0,
|
||||||
|
length: 1,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: 'ecommerce_db',
|
||||||
|
_source: {
|
||||||
|
id: '0e8ec01e-a57f-4173-8d30-deda453174d0',
|
||||||
|
name: 'dim.api/client',
|
||||||
|
fullyQualifiedName:
|
||||||
|
'sample_data.ecommerce_db.shopify."dim.api/client"',
|
||||||
|
version: 5.7,
|
||||||
|
updatedAt: 1670495113513,
|
||||||
|
updatedBy: 'admin',
|
||||||
|
href: 'http://localhost:8585/api/v1/tables/0e8ec01e-a57f-4173-8d30-deda453174d0',
|
||||||
|
tableType: 'Regular',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockTagSuggestions = {
|
||||||
|
data: {
|
||||||
|
suggest: {
|
||||||
|
'metadata-suggest': [
|
||||||
|
{
|
||||||
|
text: 'pi',
|
||||||
|
offset: 0,
|
||||||
|
length: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: 'PII.NonSensitive',
|
||||||
|
_source: {
|
||||||
|
id: '5555ba21-644f-45f7-bb00-4257a120e94f',
|
||||||
|
name: 'NonSensitive',
|
||||||
|
fullyQualifiedName: 'PII.NonSensitive',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'PII.None',
|
||||||
|
_source: {
|
||||||
|
id: 'c3abf789-518d-47f2-9c15-569c9bb1da90',
|
||||||
|
name: 'None',
|
||||||
|
fullyQualifiedName: 'PII.None',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'PII.Sensitive',
|
||||||
|
_source: {
|
||||||
|
id: 'f011a65f-939a-4ee5-b849-7e1f3e22acad',
|
||||||
|
name: 'Sensitive',
|
||||||
|
fullyQualifiedName: 'PII.Sensitive',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockUserSuggestions = {
|
||||||
|
data: {
|
||||||
|
suggest: {
|
||||||
|
'metadata-suggest': [
|
||||||
|
{
|
||||||
|
text: 'aa',
|
||||||
|
offset: 0,
|
||||||
|
length: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: 'Aaron Johnson',
|
||||||
|
_source: {
|
||||||
|
id: '0b4bfce9-0fcb-4578-b563-f566f8c45e10',
|
||||||
|
name: 'aaron_johnson0',
|
||||||
|
fullyQualifiedName: 'aaron_johnson0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Aaron Singh',
|
||||||
|
_source: {
|
||||||
|
id: '4e7b5402-d88a-4eb3-a4a6-788e5dc6f59b',
|
||||||
|
name: 'aaron_singh2',
|
||||||
|
fullyQualifiedName: 'aaron_singh2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Aaron Warren',
|
||||||
|
_source: {
|
||||||
|
id: 'a2802c79-9007-4e75-a04c-0978a406fcd7',
|
||||||
|
name: 'aaron_warren5',
|
||||||
|
fullyQualifiedName: 'aaron_warren5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user