Fix(UI) #9277: Fixed issue with dropdown options not resetting for different drop-downs (#9279)

* 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:
Aniket Katkar 2022-12-14 18:14:55 +05:30 committed by GitHub
parent b959709275
commit c2c7281018
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 295 additions and 12 deletions

View File

@ -11,11 +11,20 @@
* 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 { getAdvancedFieldDefaultOptions } from '../../axiosAPIs/miscAPI';
import { SearchIndex } from '../../enums/search.enum';
import { ExploreQuickFilterField } from '../Explore/explore.interface';
import { SearchDropdownProps } from '../SearchDropdown/SearchDropdown.interface';
import ExploreQuickFilters from './ExploreQuickFilters';
import {
mockAdvancedFieldDefaultOptions,
mockAdvancedFieldOptions,
mockTagSuggestions,
mockUserSuggestions,
} from './mocks/ExploreQuickFilters.mock';
const mockOnFieldRemove = jest.fn();
const mockOnAdvanceSearch = jest.fn();
@ -28,18 +37,84 @@ const mockOnUpdateFilterValues = jest.fn();
jest.mock('../SearchDropdown/SearchDropdown', () =>
jest
.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', () => ({
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 fields = [
{ key: 'owner.name', value: undefined },
{ key: 'column_names', value: undefined },
] as ExploreQuickFilterField[];
const mockFields: ExploreQuickFilterField[] = [
{
label: 'Column',
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 onAdvanceSearch = mockOnAdvanceSearch;
@ -51,7 +126,7 @@ const onUpdateFilterValues = mockOnUpdateFilterValues;
const mockProps = {
index,
fields,
fields: mockFields,
onFieldRemove,
onAdvanceSearch,
onClear,
@ -63,22 +138,22 @@ const mockProps = {
describe('Test ExploreQuickFilters component', () => {
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);
});
it('Should call onAdvanceSearch method on click of Advance Search button', async () => {
const { findByTestId, findAllByTestId } = render(
const { findByTestId, findAllByTitle } = render(
<ExploreQuickFilters {...mockProps} />
);
const fields = await findAllByTestId('search-dropdown');
const fields = await findAllByTitle('search-dropdown');
const advanceSearchButton = await findByTestId('advance-search-button');
expect(fields).toHaveLength(fields.length);
expect(fields).toHaveLength(mockFields.length);
expect(advanceSearchButton).toBeInTheDocument();
@ -86,4 +161,58 @@ describe('Test ExploreQuickFilters component', () => {
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);
});
});

View File

@ -74,6 +74,7 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
const getFilterOptions = async (value: string, key: string) => {
setIsOptionsLoading(true);
setOptions([]);
try {
if (value) {
await fetchOptions(value, key);

View File

@ -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',
},
},
],
},
],
},
},
};