Minor: added support for search param based test case filter (#17030)

* Minor: added support for search param based test case filter

* fixed remove filter issue
This commit is contained in:
Shailesh Parmar 2024-07-16 10:44:48 +05:30 committed by GitHub
parent f8beaa6c30
commit c2db1bbf0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 409 additions and 215 deletions

View File

@ -1057,6 +1057,7 @@ describe(
}); });
cy.get('[value="serviceName"]').click({ waitForAnimations: true }); cy.get('[value="serviceName"]').click({ waitForAnimations: true });
verifyResponseStatusCode('@getTestCase', 200); verifyResponseStatusCode('@getTestCase', 200);
cy.get('#serviceName').should('not.exist');
// Test case filter by Tags // Test case filter by Tags
interceptURL( interceptURL(
@ -1073,12 +1074,13 @@ describe(
verifyResponseStatusCode('@getTestCaseByTags', 200); verifyResponseStatusCode('@getTestCaseByTags', 200);
verifyFilterTestCase(); verifyFilterTestCase();
verifyFilter2TestCase(true); verifyFilter2TestCase(true);
// remove service filter // remove tags filter
cy.get('[data-testid="advanced-filter"]').click({ cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true, waitForAnimations: true,
}); });
cy.get('[value="tags"]').click({ waitForAnimations: true }); cy.get('[value="tags"]').click({ waitForAnimations: true });
verifyResponseStatusCode('@getTestCase', 200); verifyResponseStatusCode('@getTestCase', 200);
cy.get('#tags').should('not.exist');
// Test case filter by Tier // Test case filter by Tier
interceptURL( interceptURL(
@ -1094,12 +1096,13 @@ describe(
verifyResponseStatusCode('@getTestCaseByTier', 200); verifyResponseStatusCode('@getTestCaseByTier', 200);
verifyFilterTestCase(); verifyFilterTestCase();
verifyFilter2TestCase(true); verifyFilter2TestCase(true);
// remove service filter // remove tier filter
cy.get('[data-testid="advanced-filter"]').click({ cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true, waitForAnimations: true,
}); });
cy.get('[value="tier"]').click({ waitForAnimations: true }); cy.get('[value="tier"]').click({ waitForAnimations: true });
verifyResponseStatusCode('@getTestCase', 200); verifyResponseStatusCode('@getTestCase', 200);
cy.get('#tier').should('not.exist');
// Test case filter by table name // Test case filter by table name
interceptURL( interceptURL(
@ -1196,6 +1199,25 @@ describe(
verifyResponseStatusCode('@testCasePlatformByOpenMetadata', 200); verifyResponseStatusCode('@testCasePlatformByOpenMetadata', 200);
cy.clickOutside(); cy.clickOutside();
verifyFilterTestCase(); verifyFilterTestCase();
cy.url().then((url) => {
cy.reload();
verifyResponseStatusCode('@testCasePlatformByOpenMetadata', 200);
cy.url().then((updatedUrl) => {
expect(url).to.be.equal(updatedUrl);
});
});
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="testPlatforms"]').click({
waitForAnimations: true,
});
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[value="platform-select-filter"]').should('not.exist');
cy.reload();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[value="tier"]').should('not.exist');
}); });
it('Filter with domain', () => { it('Filter with domain', () => {

View File

@ -1,3 +1,8 @@
import { DateRangeObject } from 'Models';
import { TestCaseStatus } from '../../generated/tests/testCase';
import { TestPlatform } from '../../generated/tests/testDefinition';
import { TestCaseType } from '../../rest/testAPI';
/* /*
* Copyright 2023 Collate. * Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -10,9 +15,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
export type DataQualitySearchParams = { export type TestSuiteSearchParams = {
searchValue: string; searchValue: string;
status: string; status: string;
type: string; type: string;
owner: string; owner: string;
}; };
export type TestCaseSearchParams = {
searchValue?: string;
tableFqn?: string;
testPlatforms?: TestPlatform[];
testCaseStatus?: TestCaseStatus;
testCaseType?: TestCaseType;
lastRunRange?: DateRangeObject;
tier?: string;
tags?: string;
serviceName?: string;
};

View File

@ -30,11 +30,9 @@ import {
debounce, debounce,
entries, entries,
isEmpty, isEmpty,
isEqual,
isUndefined, isUndefined,
omit,
omitBy,
startCase, startCase,
uniq,
} from 'lodash'; } from 'lodash';
import QueryString from 'qs'; import QueryString from 'qs';
import React, { import React, {
@ -67,14 +65,10 @@ import { usePaging } from '../../../hooks/paging/usePaging';
import { DataQualityPageTabs } from '../../../pages/DataQuality/DataQualityPage.interface'; import { DataQualityPageTabs } from '../../../pages/DataQuality/DataQualityPage.interface';
import { searchQuery } from '../../../rest/searchAPI'; import { searchQuery } from '../../../rest/searchAPI';
import { getTags } from '../../../rest/tagAPI'; import { getTags } from '../../../rest/tagAPI';
import { import { getListTestCaseBySearch } from '../../../rest/testAPI';
getListTestCaseBySearch, import { getTestCaseFiltersValue } from '../../../utils/DataQuality/DataQualityUtils';
ListTestCaseParamsBySearch,
} from '../../../rest/testAPI';
import { buildTestCaseParams } from '../../../utils/DataQuality/DataQualityUtils';
import { getEntityName } from '../../../utils/EntityUtils'; import { getEntityName } from '../../../utils/EntityUtils';
import { getDataQualityPagePath } from '../../../utils/RouterUtils'; import { getDataQualityPagePath } from '../../../utils/RouterUtils';
import { generateEntityLink } from '../../../utils/TableUtils';
import tagClassBase from '../../../utils/TagClassBase'; import tagClassBase from '../../../utils/TagClassBase';
import { showErrorToast } from '../../../utils/ToastUtils'; import { showErrorToast } from '../../../utils/ToastUtils';
import DatePickerMenu from '../../common/DatePickerMenu/DatePickerMenu.component'; import DatePickerMenu from '../../common/DatePickerMenu/DatePickerMenu.component';
@ -82,7 +76,7 @@ import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder
import { PagingHandlerParams } from '../../common/NextPrevious/NextPrevious.interface'; import { PagingHandlerParams } from '../../common/NextPrevious/NextPrevious.interface';
import Searchbar from '../../common/SearchBarComponent/SearchBar.component'; import Searchbar from '../../common/SearchBarComponent/SearchBar.component';
import DataQualityTab from '../../Database/Profiler/DataQualityTab/DataQualityTab'; import DataQualityTab from '../../Database/Profiler/DataQualityTab/DataQualityTab';
import { DataQualitySearchParams } from '../DataQuality.interface'; import { TestCaseSearchParams } from '../DataQuality.interface';
export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => { export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
const [form] = useForm(); const [form] = useForm();
@ -105,13 +99,12 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
search.startsWith('?') ? search.substring(1) : search search.startsWith('?') ? search.substring(1) : search
); );
return params as DataQualitySearchParams; return params as TestCaseSearchParams;
}, [location]); }, [location.search]);
const { searchValue = '' } = params; const { searchValue = '' } = params;
const [testCase, setTestCase] = useState<TestCase[]>([]); const [testCase, setTestCase] = useState<TestCase[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
const [filters, setFilters] = useState<ListTestCaseParamsBySearch>({});
const [selectedFilter, setSelectedFilter] = useState<string[]>([ const [selectedFilter, setSelectedFilter] = useState<string[]>([
TEST_CASE_FILTERS.status, TEST_CASE_FILTERS.status,
TEST_CASE_FILTERS.type, TEST_CASE_FILTERS.type,
@ -127,12 +120,12 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
showPagination, showPagination,
} = usePaging(PAGE_SIZE); } = usePaging(PAGE_SIZE);
const handleSearchParam = ( const handleSearchParam = <K extends keyof TestCaseSearchParams>(
value: string | boolean, key: K,
key: keyof DataQualitySearchParams value?: TestCaseSearchParams[K]
) => { ) => {
history.push({ history.push({
search: QueryString.stringify({ ...params, [key]: value }), search: QueryString.stringify({ ...params, [key]: value || undefined }),
}); });
}; };
@ -150,12 +143,17 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
const fetchTestCases = async ( const fetchTestCases = async (
currentPage = INITIAL_PAGING_VALUE, currentPage = INITIAL_PAGING_VALUE,
params?: ListTestCaseParamsBySearch filters?: string[]
) => { ) => {
const updatedParams = getTestCaseFiltersValue(
params,
filters ?? selectedFilter
);
setIsLoading(true); setIsLoading(true);
try { try {
const { data, paging } = await getListTestCaseBySearch({ const { data, paging } = await getListTestCaseBySearch({
...params, ...updatedParams,
testCaseStatus: isEmpty(params?.testCaseStatus) testCaseStatus: isEmpty(params?.testCaseStatus)
? undefined ? undefined
: params?.testCaseStatus, : params?.testCaseStatus,
@ -192,30 +190,15 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
}; };
const handlePagingClick = ({ currentPage }: PagingHandlerParams) => { const handlePagingClick = ({ currentPage }: PagingHandlerParams) => {
fetchTestCases(currentPage, filters); fetchTestCases(currentPage);
}; };
const handleFilterChange: FormProps['onValuesChange'] = (_, values) => { const handleFilterChange: FormProps<TestCaseSearchParams>['onValuesChange'] =
const { lastRunRange, tableFqn } = values; (value?: TestCaseSearchParams) => {
const startTimestamp = lastRunRange?.startTs; if (!isUndefined(value)) {
const endTimestamp = lastRunRange?.endTs; const [data] = Object.entries(value);
const entityLink = tableFqn ? generateEntityLink(tableFqn) : undefined; handleSearchParam(data[0] as keyof TestCaseSearchParams, data[1]);
const params = {
...omit(values, ['lastRunRange', 'tableFqn']),
startTimestamp,
endTimestamp,
entityLink,
};
const updatedParams = omitBy(
buildTestCaseParams(params, selectedFilter),
isUndefined
);
if (!isEqual(filters, updatedParams)) {
fetchTestCases(INITIAL_PAGING_VALUE, updatedParams);
} }
setFilters(updatedParams);
}; };
const fetchTierOptions = async () => { const fetchTierOptions = async () => {
@ -360,33 +343,46 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
} }
}; };
const getInitialOptions = (key: string, isLengthCheck = false) => {
switch (key) {
case TEST_CASE_FILTERS.tier:
(isEmpty(tierOptions) || !isLengthCheck) && fetchTierOptions();
break;
case TEST_CASE_FILTERS.table:
(isEmpty(tableOptions) || !isLengthCheck) && fetchTableData();
break;
case TEST_CASE_FILTERS.tags:
(isEmpty(tagOptions) || !isLengthCheck) && fetchTagOptions();
break;
case TEST_CASE_FILTERS.service:
(isEmpty(serviceOptions) || !isLengthCheck) && fetchServiceOptions();
break;
default:
break;
}
};
const handleMenuClick = ({ key }: { key: string }) => { const handleMenuClick = ({ key }: { key: string }) => {
setSelectedFilter((prevSelected) => { setSelectedFilter((prevSelected) => {
if (prevSelected.includes(key)) { if (prevSelected.includes(key)) {
const updatedValue = prevSelected.filter( const updatedValue = prevSelected.filter(
(selected) => selected !== key (selected) => selected !== key
); );
const updatedFilters = omitBy(
buildTestCaseParams(filters, updatedValue),
isUndefined
);
form.setFieldsValue({ [key]: undefined }); form.setFieldsValue({ [key]: undefined });
if (!isEqual(filters, updatedFilters)) {
fetchTestCases(INITIAL_PAGING_VALUE, updatedFilters);
}
setFilters(updatedFilters);
return updatedValue; return updatedValue;
} }
return [...prevSelected, key]; return uniq([...prevSelected, key]);
}); });
// Fetch options based on the selected filter // Fetch options based on the selected filter
key === TEST_CASE_FILTERS.tier && fetchTierOptions(); getInitialOptions(key);
key === TEST_CASE_FILTERS.tags && fetchTagOptions(); handleSearchParam(key as keyof TestCaseSearchParams, undefined);
key === TEST_CASE_FILTERS.table && fetchTableData();
key === TEST_CASE_FILTERS.service && fetchServiceOptions();
}; };
const filterMenu: ItemType[] = useMemo(() => { const filterMenu: ItemType[] = useMemo(() => {
@ -396,7 +392,7 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
value: filter, value: filter,
onClick: handleMenuClick, onClick: handleMenuClick,
})); }));
}, [filters]); }, []);
const debounceFetchTableData = useCallback(debounce(fetchTableData, 1000), [ const debounceFetchTableData = useCallback(debounce(fetchTableData, 1000), [
fetchTableData, fetchTableData,
@ -411,15 +407,30 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
[fetchServiceOptions] [fetchServiceOptions]
); );
useEffect(() => { const getTestCases = () => {
if (testCasePermission?.ViewAll || testCasePermission?.ViewBasic) { if (!isEmpty(params)) {
if (tab === DataQualityPageTabs.TEST_CASES) { const updatedValue = uniq([...selectedFilter, ...Object.keys(params)]);
fetchTestCases(INITIAL_PAGING_VALUE, filters); for (const key of updatedValue) {
getInitialOptions(key, true);
} }
setSelectedFilter(updatedValue);
fetchTestCases(INITIAL_PAGING_VALUE, updatedValue);
form.setFieldsValue(params);
} else {
fetchTestCases(INITIAL_PAGING_VALUE);
}
};
useEffect(() => {
if (
(testCasePermission?.ViewAll || testCasePermission?.ViewBasic) &&
tab === DataQualityPageTabs.TEST_CASES
) {
getTestCases();
} else { } else {
setIsLoading(false); setIsLoading(false);
} }
}, [tab, searchValue, testCasePermission, pageSize]); }, [tab, testCasePermission, pageSize, params]);
const pagingData = useMemo( const pagingData = useMemo(
() => ({ () => ({
@ -443,9 +454,8 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
data-testid="test-case-container" data-testid="test-case-container"
gutter={[16, 16]}> gutter={[16, 16]}>
<Col span={24}> <Col span={24}>
<Form <Form<TestCaseSearchParams>
form={form} form={form}
initialValues={filters}
layout="horizontal" layout="horizontal"
onValuesChange={handleFilterChange}> onValuesChange={handleFilterChange}>
<Space wrap align="center" className="w-full" size={16}> <Space wrap align="center" className="w-full" size={16}>
@ -456,7 +466,7 @@ export const TestCases = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
entity: t('label.test-case-lowercase'), entity: t('label.test-case-lowercase'),
})} })}
searchValue={searchValue} searchValue={searchValue}
onSearch={(value) => handleSearchParam(value, 'searchValue')} onSearch={(value) => handleSearchParam('searchValue', value)}
/> />
</Form.Item> </Form.Item>
<Form.Item noStyle name="selectedFilters"> <Form.Item noStyle name="selectedFilters">

View File

@ -58,7 +58,7 @@ import Table from '../../../common/Table/Table';
import { UserTeamSelectableList } from '../../../common/UserTeamSelectableList/UserTeamSelectableList.component'; import { UserTeamSelectableList } from '../../../common/UserTeamSelectableList/UserTeamSelectableList.component';
import { TableProfilerTab } from '../../../Database/Profiler/ProfilerDashboard/profilerDashboard.interface'; import { TableProfilerTab } from '../../../Database/Profiler/ProfilerDashboard/profilerDashboard.interface';
import ProfilerProgressWidget from '../../../Database/Profiler/TableProfiler/ProfilerProgressWidget/ProfilerProgressWidget'; import ProfilerProgressWidget from '../../../Database/Profiler/TableProfiler/ProfilerProgressWidget/ProfilerProgressWidget';
import { DataQualitySearchParams } from '../../DataQuality.interface'; import { TestSuiteSearchParams } from '../../DataQuality.interface';
export const TestSuites = ({ summaryPanel }: { summaryPanel: ReactNode }) => { export const TestSuites = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -74,7 +74,7 @@ export const TestSuites = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
search.startsWith('?') ? search.substring(1) : search search.startsWith('?') ? search.substring(1) : search
); );
return params as DataQualitySearchParams; return params as TestSuiteSearchParams;
}, [location]); }, [location]);
const { searchValue, owner } = params; const { searchValue, owner } = params;
const selectedOwner = useMemo( const selectedOwner = useMemo(
@ -228,7 +228,7 @@ export const TestSuites = ({ summaryPanel }: { summaryPanel: ReactNode }) => {
const handleSearchParam = ( const handleSearchParam = (
value: string, value: string,
key: keyof DataQualitySearchParams key: keyof TestSuiteSearchParams
) => { ) => {
history.push({ history.push({
search: QueryString.stringify({ search: QueryString.stringify({

View File

@ -14,6 +14,7 @@
import { t } from 'i18next'; import { t } from 'i18next';
import { capitalize, map, startCase, values } from 'lodash'; import { capitalize, map, startCase, values } from 'lodash';
import { DateFilterType, StepperStepType } from 'Models'; import { DateFilterType, StepperStepType } from 'Models';
import { TestCaseSearchParams } from '../components/DataQuality/DataQuality.interface';
import { CSMode } from '../enums/codemirror.enum'; import { CSMode } from '../enums/codemirror.enum';
import { DMLOperationType } from '../generated/api/data/createTableProfile'; import { DMLOperationType } from '../generated/api/data/createTableProfile';
import { import {
@ -417,7 +418,7 @@ export const TEST_CASE_STATUS_OPTION = [
})), })),
]; ];
export const TEST_CASE_FILTERS = { export const TEST_CASE_FILTERS: Record<string, keyof TestCaseSearchParams> = {
table: 'tableFqn', table: 'tableFqn',
platform: 'testPlatforms', platform: 'testPlatforms',
type: 'testCaseType', type: 'testCaseType',

View File

@ -10,6 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { TestCaseSearchParams } from '../../components/DataQuality/DataQuality.interface';
import { import {
TestDataType, TestDataType,
TestDefinition, TestDefinition,
@ -18,19 +19,30 @@ import { ListTestCaseParamsBySearch } from '../../rest/testAPI';
import { import {
buildTestCaseParams, buildTestCaseParams,
createTestCaseParameters, createTestCaseParameters,
getTestCaseFiltersValue,
} from './DataQualityUtils'; } from './DataQualityUtils';
jest.mock('../../constants/profiler.constant', () => ({ jest.mock('../../constants/profiler.constant', () => ({
TEST_CASE_FILTERS: { TEST_CASE_FILTERS: {
lastRun: 'lastRun', table: 'tableFqn',
table: 'table', platform: 'testPlatforms',
platform: 'platform', type: 'testCaseType',
type: 'type', status: 'testCaseStatus',
status: 'status', lastRun: 'lastRunRange',
tier: 'tier',
tags: 'tags',
service: 'serviceName',
}, },
})); }));
describe('buildTestCaseParams', () => { jest.mock('../TableUtils', () => ({
generateEntityLink: jest.fn().mockImplementation((fqn: string) => {
return `<#E::table::${fqn}>`;
}),
}));
describe('DataQualityUtils', () => {
describe('buildTestCaseParams', () => {
it('should return an empty object if params is undefined', () => { it('should return an empty object if params is undefined', () => {
const params = undefined; const params = undefined;
const filters = ['lastRun', 'table']; const filters = ['lastRun', 'table'];
@ -47,7 +59,7 @@ describe('buildTestCaseParams', () => {
entityLink: 'table1', entityLink: 'table1',
testPlatforms: ['DBT'], testPlatforms: ['DBT'],
} as ListTestCaseParamsBySearch; } as ListTestCaseParamsBySearch;
const filters = ['lastRun', 'table']; const filters = ['lastRunRange', 'tableFqn'];
const result = buildTestCaseParams(params, filters); const result = buildTestCaseParams(params, filters);
@ -57,9 +69,9 @@ describe('buildTestCaseParams', () => {
entityLink: 'table1', entityLink: 'table1',
}); });
}); });
}); });
describe('createTestCaseParameters', () => { describe('createTestCaseParameters', () => {
const mockDefinition = { const mockDefinition = {
parameterDefinition: [ parameterDefinition: [
{ name: 'arrayParam', dataType: TestDataType.Array }, { name: 'arrayParam', dataType: TestDataType.Array },
@ -176,4 +188,110 @@ describe('createTestCaseParameters', () => {
expect(result).toEqual(expected); expect(result).toEqual(expected);
}); });
});
describe('getTestCaseFiltersValue', () => {
const testCaseSearchParams = {
testCaseType: 'column',
testCaseStatus: 'Success',
searchValue: 'between',
testPlatforms: ['DBT', 'Deequ'],
lastRunRange: {
startTs: '1720417883445',
endTs: '1721022683445',
key: 'last7days',
title: 'Last 7 days',
},
tags: ['PII.None'],
tier: 'Tier.Tier1',
serviceName: 'sample_data',
tableFqn: 'sample_data.ecommerce_db.shopify.fact_sale',
} as unknown as TestCaseSearchParams;
it('should correctly process values and selectedFilter', () => {
const selectedFilter = [
'testCaseStatus',
'testCaseType',
'searchValue',
'testPlatforms',
'lastRunRange',
'tags',
'tier',
'serviceName',
'tableFqn',
];
const expected = {
endTimestamp: '1721022683445',
startTimestamp: '1720417883445',
entityLink: '<#E::table::sample_data.ecommerce_db.shopify.fact_sale>',
testPlatforms: ['DBT', 'Deequ'],
testCaseType: 'column',
testCaseStatus: 'Success',
tags: ['PII.None'],
tier: 'Tier.Tier1',
serviceName: 'sample_data',
};
const result = getTestCaseFiltersValue(
testCaseSearchParams,
selectedFilter
);
expect(result).toEqual(expected);
});
it('should only create params based on selected filters', () => {
const selectedFilter = ['testPlatforms', 'lastRunRange'];
const expected = {
testPlatforms: ['DBT', 'Deequ'],
endTimestamp: '1721022683445',
startTimestamp: '1720417883445',
};
const result = getTestCaseFiltersValue(
testCaseSearchParams,
selectedFilter
);
expect(result).toEqual(expected);
});
it('should only create params based on selected filters and available data', () => {
const testCaseSearchParams = {
testCaseType: 'column',
testCaseStatus: 'Success',
searchValue: 'between',
testPlatforms: ['DBT', 'Deequ'],
tags: ['PII.None'],
tier: 'Tier.Tier1',
} as unknown as TestCaseSearchParams;
const selectedFilter = ['testPlatforms', 'tags', 'testCaseStatus'];
const expected = {
testPlatforms: ['DBT', 'Deequ'],
tags: ['PII.None'],
testCaseStatus: 'Success',
};
const result = getTestCaseFiltersValue(
testCaseSearchParams,
selectedFilter
);
expect(result).toEqual(expected);
});
it('should not send params if selected filter is empty', () => {
const selectedFilter: string[] = [];
const result = getTestCaseFiltersValue(
testCaseSearchParams,
selectedFilter
);
expect(result).toEqual({});
});
});
}); });

View File

@ -10,7 +10,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { isArray } from 'lodash'; import { isArray, isUndefined, omit, omitBy } from 'lodash';
import { TestCaseSearchParams } from '../../components/DataQuality/DataQuality.interface';
import { TEST_CASE_FILTERS } from '../../constants/profiler.constant'; import { TEST_CASE_FILTERS } from '../../constants/profiler.constant';
import { TestCaseParameterValue } from '../../generated/tests/testCase'; import { TestCaseParameterValue } from '../../generated/tests/testCase';
import { import {
@ -18,6 +19,7 @@ import {
TestDefinition, TestDefinition,
} from '../../generated/tests/testDefinition'; } from '../../generated/tests/testDefinition';
import { ListTestCaseParamsBySearch } from '../../rest/testAPI'; import { ListTestCaseParamsBySearch } from '../../rest/testAPI';
import { generateEntityLink } from '../TableUtils';
/** /**
* Builds the parameters for a test case search based on the given filters. * Builds the parameters for a test case search based on the given filters.
@ -74,3 +76,27 @@ export const createTestCaseParameters = (
}, [] as TestCaseParameterValue[]) }, [] as TestCaseParameterValue[])
: params; : params;
}; };
export const getTestCaseFiltersValue = (
values: TestCaseSearchParams,
selectedFilter: string[]
) => {
const { lastRunRange, tableFqn } = values;
const startTimestamp = lastRunRange?.startTs;
const endTimestamp = lastRunRange?.endTs;
const entityLink = tableFqn ? generateEntityLink(tableFqn) : undefined;
const apiParams = {
...omit(values, ['lastRunRange', 'tableFqn', 'searchValue']),
startTimestamp,
endTimestamp,
entityLink,
};
const updatedParams = omitBy(
buildTestCaseParams(apiParams, selectedFilter),
isUndefined
);
return updatedParams;
};