mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-27 10:26:09 +00:00
Display inspection query (#16766)
* Display inspection query * added reset for global state * fixed test failure
This commit is contained in:
parent
b55890f1f9
commit
04d3720df9
@ -30,9 +30,9 @@ import {
|
||||
Thread,
|
||||
ThreadTaskStatus,
|
||||
} from '../../../../generated/entity/feed/thread';
|
||||
import { EntityReference } from '../../../../generated/entity/type';
|
||||
import { useElementInView } from '../../../../hooks/useElementInView';
|
||||
import { useFqn } from '../../../../hooks/useFqn';
|
||||
import { useTestCaseStore } from '../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store';
|
||||
import ActivityFeedListV1 from '../../../ActivityFeed/ActivityFeedList/ActivityFeedListV1.component';
|
||||
import { useActivityFeedProvider } from '../../../ActivityFeed/ActivityFeedProvider/ActivityFeedProvider';
|
||||
import { TaskFilter } from '../../../ActivityFeed/ActivityFeedTab/ActivityFeedTab.interface';
|
||||
@ -40,9 +40,12 @@ import Loader from '../../../common/Loader/Loader';
|
||||
import { TaskTab } from '../../../Entity/Task/TaskTab/TaskTab.component';
|
||||
import './test-case-incident-tab.style.less';
|
||||
|
||||
const TestCaseIncidentTab = ({ owner }: { owner?: EntityReference }) => {
|
||||
const TestCaseIncidentTab = () => {
|
||||
const { t } = useTranslation();
|
||||
const { fqn: decodedFqn } = useFqn();
|
||||
const { testCase } = useTestCaseStore();
|
||||
|
||||
const owner = useMemo(() => testCase?.owner, [testCase]);
|
||||
|
||||
const {
|
||||
selectedThread,
|
||||
|
@ -25,6 +25,22 @@ const mockUseActivityFeedProviderValue = {
|
||||
setActiveThread: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock(
|
||||
'../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store',
|
||||
() => ({
|
||||
useTestCaseStore: jest.fn().mockImplementation(() => ({
|
||||
testCase: {
|
||||
owner: {
|
||||
name: 'arron_johnson',
|
||||
displayName: 'Arron Johnson',
|
||||
id: '1',
|
||||
type: 'user',
|
||||
},
|
||||
},
|
||||
})),
|
||||
})
|
||||
);
|
||||
|
||||
jest.mock('../../../Entity/Task/TaskTab/TaskTab.component', () => {
|
||||
return {
|
||||
TaskTab: jest.fn().mockImplementation(({ onAfterClose }) => (
|
||||
|
@ -30,6 +30,7 @@ import { EntityType } from '../../../../enums/entity.enum';
|
||||
import { Operation } from '../../../../generated/entity/policies/policy';
|
||||
|
||||
import { TestCaseParameterValue } from '../../../../generated/tests/testCase';
|
||||
import { useTestCaseStore } from '../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store';
|
||||
import { updateTestCaseById } from '../../../../rest/testAPI';
|
||||
import { checkPermission } from '../../../../utils/PermissionsUtils';
|
||||
import { showErrorToast, showSuccessToast } from '../../../../utils/ToastUtils';
|
||||
@ -39,14 +40,11 @@ import SchemaEditor from '../../../Database/SchemaEditor/SchemaEditor';
|
||||
import EditTestCaseModal from '../../AddDataQualityTest/EditTestCaseModal';
|
||||
import '../incident-manager.style.less';
|
||||
import './test-case-result-tab.style.less';
|
||||
import { TestCaseResultTabProps } from './TestCaseResultTab.interface';
|
||||
import testCaseResultTabClassBase from './TestCaseResultTabClassBase';
|
||||
|
||||
const TestCaseResultTab = ({
|
||||
testCaseData,
|
||||
onTestCaseUpdate,
|
||||
}: TestCaseResultTabProps) => {
|
||||
const TestCaseResultTab = () => {
|
||||
const { t } = useTranslation();
|
||||
const { testCase: testCaseData, setTestCase } = useTestCaseStore();
|
||||
const additionalComponent =
|
||||
testCaseResultTabClassBase.getAdditionalComponents();
|
||||
const [isDescriptionEdit, setIsDescriptionEdit] = useState<boolean>(false);
|
||||
@ -95,7 +93,7 @@ const TestCaseResultTab = ({
|
||||
testCaseData.id ?? '',
|
||||
jsonPatch
|
||||
);
|
||||
onTestCaseUpdate(res);
|
||||
setTestCase(res);
|
||||
showSuccessToast(
|
||||
t('server.update-entity-success', {
|
||||
entity: t('label.test-case'),
|
||||
@ -109,7 +107,7 @@ const TestCaseResultTab = ({
|
||||
}
|
||||
}
|
||||
},
|
||||
[testCaseData, updateTestCaseById, onTestCaseUpdate]
|
||||
[testCaseData, updateTestCaseById, setTestCase]
|
||||
);
|
||||
|
||||
const handleCancelParameter = useCallback(
|
||||
@ -225,7 +223,7 @@ const TestCaseResultTab = ({
|
||||
testCase={testCaseData}
|
||||
visible={isParameterEdit}
|
||||
onCancel={handleCancelParameter}
|
||||
onUpdate={onTestCaseUpdate}
|
||||
onUpdate={setTestCase}
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
import { TestCase } from '../../../../generated/tests/testCase';
|
||||
|
||||
export interface TestCaseResultTabProps {
|
||||
testCaseData?: TestCase;
|
||||
onTestCaseUpdate: (data: TestCase) => void;
|
||||
}
|
@ -21,54 +21,61 @@ import React from 'react';
|
||||
import { TestCase } from '../../../../generated/tests/testCase';
|
||||
import { checkPermission } from '../../../../utils/PermissionsUtils';
|
||||
import TestCaseResultTab from './TestCaseResultTab.component';
|
||||
import { TestCaseResultTabProps } from './TestCaseResultTab.interface';
|
||||
|
||||
const mockProps: TestCaseResultTabProps = {
|
||||
testCaseData: {
|
||||
id: '1b748634-d24b-4879-9791-289f2f90fc3c',
|
||||
name: 'table_column_count_equals',
|
||||
const mockTestCaseData = {
|
||||
id: '1b748634-d24b-4879-9791-289f2f90fc3c',
|
||||
name: 'table_column_count_equals',
|
||||
fullyQualifiedName:
|
||||
'sample_data.ecommerce_db.shopify.dim_address.table_column_count_equals',
|
||||
testDefinition: {
|
||||
id: '48063740-ac35-4854-9ab3-b1b542c820fe',
|
||||
type: 'testDefinition',
|
||||
name: 'tableColumnCountToEqual',
|
||||
fullyQualifiedName: 'tableColumnCountToEqual',
|
||||
displayName: 'Table Column Count To Equal',
|
||||
},
|
||||
entityLink: '<#E::table::sample_data.ecommerce_db.shopify.dim_address>',
|
||||
entityFQN: 'sample_data.ecommerce_db.shopify.dim_address',
|
||||
testSuite: {
|
||||
id: 'fe44ef1a-1b83-4872-bef6-fbd1885986b8',
|
||||
type: 'testSuite',
|
||||
name: 'sample_data.ecommerce_db.shopify.dim_address.testSuite',
|
||||
fullyQualifiedName:
|
||||
'sample_data.ecommerce_db.shopify.dim_address.table_column_count_equals',
|
||||
testDefinition: {
|
||||
id: '48063740-ac35-4854-9ab3-b1b542c820fe',
|
||||
type: 'testDefinition',
|
||||
name: 'tableColumnCountToEqual',
|
||||
fullyQualifiedName: 'tableColumnCountToEqual',
|
||||
displayName: 'Table Column Count To Equal',
|
||||
'sample_data.ecommerce_db.shopify.dim_address.testSuite',
|
||||
},
|
||||
parameterValues: [
|
||||
{
|
||||
name: 'columnCount',
|
||||
value: '10',
|
||||
},
|
||||
entityLink: '<#E::table::sample_data.ecommerce_db.shopify.dim_address>',
|
||||
entityFQN: 'sample_data.ecommerce_db.shopify.dim_address',
|
||||
testSuite: {
|
||||
id: 'fe44ef1a-1b83-4872-bef6-fbd1885986b8',
|
||||
type: 'testSuite',
|
||||
name: 'sample_data.ecommerce_db.shopify.dim_address.testSuite',
|
||||
fullyQualifiedName:
|
||||
'sample_data.ecommerce_db.shopify.dim_address.testSuite',
|
||||
},
|
||||
parameterValues: [
|
||||
{ name: 'sqlExpression', value: 'select * from dim_address' },
|
||||
],
|
||||
testCaseResult: {
|
||||
timestamp: 1703570591595,
|
||||
testCaseStatus: 'Success',
|
||||
result: 'Found 10 columns vs. the expected 10',
|
||||
testResultValue: [
|
||||
{
|
||||
name: 'columnCount',
|
||||
value: '10',
|
||||
},
|
||||
{ name: 'sqlExpression', value: 'select * from dim_address' },
|
||||
],
|
||||
testCaseResult: {
|
||||
timestamp: 1703570591595,
|
||||
testCaseStatus: 'Success',
|
||||
result: 'Found 10 columns vs. the expected 10',
|
||||
testResultValue: [
|
||||
{
|
||||
name: 'columnCount',
|
||||
value: '10',
|
||||
},
|
||||
],
|
||||
},
|
||||
updatedAt: 1703570589915,
|
||||
updatedBy: 'admin',
|
||||
} as TestCase,
|
||||
onTestCaseUpdate: jest.fn(),
|
||||
};
|
||||
},
|
||||
updatedAt: 1703570589915,
|
||||
updatedBy: 'admin',
|
||||
} as TestCase;
|
||||
|
||||
const mockFunc = jest.fn();
|
||||
|
||||
jest.mock(
|
||||
'../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store',
|
||||
() => ({
|
||||
useTestCaseStore: jest.fn().mockImplementation(() => ({
|
||||
testCase: mockTestCaseData,
|
||||
setTestCase: mockFunc,
|
||||
})),
|
||||
})
|
||||
);
|
||||
jest.mock('../../../common/EntityDescription/DescriptionV1', () => {
|
||||
return jest.fn().mockImplementation(() => <div>DescriptionV1</div>);
|
||||
});
|
||||
@ -97,7 +104,7 @@ jest.mock('../../../../utils/PermissionsUtils', () => ({
|
||||
|
||||
describe('TestCaseResultTab', () => {
|
||||
it('Should render component', async () => {
|
||||
render(<TestCaseResultTab {...mockProps} />);
|
||||
render(<TestCaseResultTab />);
|
||||
|
||||
expect(
|
||||
await screen.findByTestId('test-case-result-tab-container')
|
||||
@ -113,7 +120,7 @@ describe('TestCaseResultTab', () => {
|
||||
});
|
||||
|
||||
it("EditTestCaseModal should be rendered when 'Edit' button is clicked", async () => {
|
||||
render(<TestCaseResultTab {...mockProps} />);
|
||||
render(<TestCaseResultTab />);
|
||||
|
||||
const editButton = await screen.findByTestId('edit-parameter-icon');
|
||||
fireEvent.click(editButton);
|
||||
@ -122,7 +129,7 @@ describe('TestCaseResultTab', () => {
|
||||
});
|
||||
|
||||
it('EditTestCaseModal should be removed on cancel click', async () => {
|
||||
const { container } = render(<TestCaseResultTab {...mockProps} />);
|
||||
const { container } = render(<TestCaseResultTab />);
|
||||
|
||||
const editButton = await screen.findByTestId('edit-parameter-icon');
|
||||
fireEvent.click(editButton);
|
||||
@ -136,7 +143,7 @@ describe('TestCaseResultTab', () => {
|
||||
});
|
||||
|
||||
it('onTestCaseUpdate should be called while updating params', async () => {
|
||||
render(<TestCaseResultTab {...mockProps} />);
|
||||
render(<TestCaseResultTab />);
|
||||
|
||||
const editButton = await screen.findByTestId('edit-parameter-icon');
|
||||
fireEvent.click(editButton);
|
||||
@ -146,14 +153,12 @@ describe('TestCaseResultTab', () => {
|
||||
const updateButton = await screen.findByTestId('update-test');
|
||||
fireEvent.click(updateButton);
|
||||
|
||||
expect(mockProps.onTestCaseUpdate).toHaveBeenCalledWith(
|
||||
mockProps.testCaseData
|
||||
);
|
||||
expect(mockFunc).toHaveBeenCalledWith(mockTestCaseData);
|
||||
});
|
||||
|
||||
it("Should not show edit icon if user doesn't have edit permission", () => {
|
||||
(checkPermission as jest.Mock).mockReturnValueOnce(false);
|
||||
const { container } = render(<TestCaseResultTab {...mockProps} />);
|
||||
const { container } = render(<TestCaseResultTab />);
|
||||
|
||||
const editButton = queryByTestId(container, 'edit-parameter-icon');
|
||||
|
||||
|
@ -15,6 +15,7 @@ import { TestCaseResolutionStatus } from '../../generated/tests/testCaseResoluti
|
||||
|
||||
export enum IncidentManagerTabs {
|
||||
TEST_CASE_RESULTS = 'test-case-results',
|
||||
SQL_QUERY = 'sql-query',
|
||||
ISSUES = 'issues',
|
||||
}
|
||||
export interface TestCaseIncidentStatusData {
|
||||
|
@ -13,10 +13,12 @@
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { TestCase } from '../../../generated/tests/testCase';
|
||||
import { getTestCaseByFqn } from '../../../rest/testAPI';
|
||||
import { checkPermission } from '../../../utils/PermissionsUtils';
|
||||
import { IncidentManagerTabs } from '../IncidentManager.interface';
|
||||
import IncidentManagerDetailPage from './IncidentManagerDetailPage';
|
||||
import { UseTestCaseStoreInterface } from './useTestCase.store';
|
||||
|
||||
const mockTestCaseData = {
|
||||
id: '1b748634-d24b-4879-9791-289f2f90fc3c',
|
||||
@ -67,7 +69,17 @@ const mockTestCaseData = {
|
||||
version: 0.1,
|
||||
updatedAt: 1703570589915,
|
||||
updatedBy: 'admin',
|
||||
} as TestCase;
|
||||
const mockUseTestCase: UseTestCaseStoreInterface = {
|
||||
testCase: mockTestCaseData,
|
||||
setTestCase: jest.fn(),
|
||||
isLoading: false,
|
||||
setIsLoading: jest.fn(),
|
||||
reset: jest.fn(),
|
||||
};
|
||||
jest.mock('./useTestCase.store', () => ({
|
||||
useTestCaseStore: jest.fn().mockImplementation(() => mockUseTestCase),
|
||||
}));
|
||||
|
||||
jest.mock('../../../rest/testAPI', () => ({
|
||||
getTestCaseByFqn: jest
|
||||
@ -179,13 +191,17 @@ describe('IncidentManagerDetailPage', () => {
|
||||
});
|
||||
|
||||
it('should render no data placeholder message if there is no data', async () => {
|
||||
mockUseTestCase.testCase = undefined;
|
||||
(getTestCaseByFqn as jest.Mock).mockImplementationOnce(() =>
|
||||
Promise.reject()
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
render(<IncidentManagerDetailPage />, { wrapper: MemoryRouter });
|
||||
});
|
||||
|
||||
expect(await screen.findByText('ErrorPlaceHolder')).toBeInTheDocument();
|
||||
|
||||
mockUseTestCase.testCase = mockTestCaseData;
|
||||
});
|
||||
});
|
||||
|
@ -22,12 +22,9 @@ import ActivityFeedProvider from '../../../components/ActivityFeed/ActivityFeedP
|
||||
import ManageButton from '../../../components/common/EntityPageInfos/ManageButton/ManageButton';
|
||||
import ErrorPlaceHolder from '../../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder';
|
||||
import Loader from '../../../components/common/Loader/Loader';
|
||||
import TabsLabel from '../../../components/common/TabsLabel/TabsLabel.component';
|
||||
import TitleBreadcrumb from '../../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { TitleBreadcrumbProps } from '../../../components/common/TitleBreadcrumb/TitleBreadcrumb.interface';
|
||||
import IncidentManagerPageHeader from '../../../components/DataQuality/IncidentManager/IncidentManagerPageHeader/IncidentManagerPageHeader.component';
|
||||
import TestCaseIncidentTab from '../../../components/DataQuality/IncidentManager/TestCaseIncidentTab/TestCaseIncidentTab.component';
|
||||
import TestCaseResultTab from '../../../components/DataQuality/IncidentManager/TestCaseResultTab/TestCaseResultTab.component';
|
||||
import EntityHeaderTitle from '../../../components/Entity/EntityHeaderTitle/EntityHeaderTitle.component';
|
||||
import { EntityName } from '../../../components/Modals/EntityNameModal/EntityNameModal.interface';
|
||||
import PageLayoutV1 from '../../../components/PageLayoutV1/PageLayoutV1';
|
||||
@ -38,7 +35,7 @@ import { ResourceEntity } from '../../../context/PermissionProvider/PermissionPr
|
||||
import { ERROR_PLACEHOLDER_TYPE } from '../../../enums/common.enum';
|
||||
import { EntityTabs, EntityType } from '../../../enums/entity.enum';
|
||||
import { Operation } from '../../../generated/entity/policies/policy';
|
||||
import { EntityReference, TestCase } from '../../../generated/tests/testCase';
|
||||
import { EntityReference } from '../../../generated/tests/testCase';
|
||||
import { useFqn } from '../../../hooks/useFqn';
|
||||
import { FeedCounts } from '../../../interface/feed.interface';
|
||||
import { getTestCaseByFqn, updateTestCaseById } from '../../../rest/testAPI';
|
||||
@ -47,7 +44,8 @@ import { checkPermission } from '../../../utils/PermissionsUtils';
|
||||
import { getIncidentManagerDetailPagePath } from '../../../utils/RouterUtils';
|
||||
import { showErrorToast } from '../../../utils/ToastUtils';
|
||||
import { IncidentManagerTabs } from '../IncidentManager.interface';
|
||||
import { TestCaseData } from './IncidentManagerDetailPage.interface';
|
||||
import testCaseClassBase from './TestCaseClassBase';
|
||||
import { useTestCaseStore } from './useTestCase.store';
|
||||
|
||||
const IncidentManagerDetailPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -60,10 +58,8 @@ const IncidentManagerDetailPage = () => {
|
||||
|
||||
const { fqn: testCaseFQN } = useFqn();
|
||||
|
||||
const [testCaseData, setTestCaseData] = useState<TestCaseData>({
|
||||
data: undefined,
|
||||
isLoading: true,
|
||||
});
|
||||
const { isLoading, setIsLoading, setTestCase, testCase, reset } =
|
||||
useTestCaseStore();
|
||||
const [feedCount, setFeedCount] = useState<FeedCounts>(
|
||||
FEED_COUNT_INITIAL_DATA
|
||||
);
|
||||
@ -90,59 +86,33 @@ const IncidentManagerDetailPage = () => {
|
||||
};
|
||||
}, [permissions]);
|
||||
|
||||
const onTestCaseUpdate = (data: TestCase) => {
|
||||
setTestCaseData((prev) => ({ ...prev, data }));
|
||||
};
|
||||
const tabDetails: TabsProps['items'] = useMemo(() => {
|
||||
const tabs = testCaseClassBase.getTab(feedCount.openTaskCount);
|
||||
|
||||
const tabDetails: TabsProps['items'] = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: (
|
||||
<TabsLabel id="test-case-result" name={t('label.test-case-result')} />
|
||||
),
|
||||
children: (
|
||||
<TestCaseResultTab
|
||||
testCaseData={testCaseData.data}
|
||||
onTestCaseUpdate={onTestCaseUpdate}
|
||||
/>
|
||||
),
|
||||
key: IncidentManagerTabs.TEST_CASE_RESULTS,
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<TabsLabel
|
||||
count={feedCount.openTaskCount}
|
||||
id="incident"
|
||||
name={t('label.incident')}
|
||||
/>
|
||||
),
|
||||
key: IncidentManagerTabs.ISSUES,
|
||||
children: <TestCaseIncidentTab owner={testCaseData.data?.owner} />,
|
||||
},
|
||||
],
|
||||
[testCaseData, feedCount.openTaskCount]
|
||||
);
|
||||
return tabs.map(({ LabelComponent, labelProps, key, Tab }) => ({
|
||||
key,
|
||||
label: <LabelComponent {...labelProps} />,
|
||||
children: <Tab />,
|
||||
}));
|
||||
}, [feedCount.openTaskCount, testCaseClassBase.showSqlQueryTab]);
|
||||
|
||||
const fetchTestCaseData = async () => {
|
||||
setTestCaseData((prev) => ({ ...prev, isLoading: true }));
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await getTestCaseByFqn(testCaseFQN, {
|
||||
fields: [
|
||||
'testSuite',
|
||||
'testCaseResult',
|
||||
'testDefinition',
|
||||
'owner',
|
||||
'incidentId',
|
||||
],
|
||||
fields: testCaseClassBase.getFields(),
|
||||
});
|
||||
setTestCaseData((prev) => ({ ...prev, data: response }));
|
||||
testCaseClassBase.setShowSqlQueryTab(
|
||||
!isUndefined(response.inspectionQuery)
|
||||
);
|
||||
setTestCase(response);
|
||||
} catch (error) {
|
||||
showErrorToast(
|
||||
error as AxiosError,
|
||||
t('server.entity-fetch-error', { entity: t('label.test-case') })
|
||||
);
|
||||
} finally {
|
||||
setTestCaseData((prev) => ({ ...prev, isLoading: false }));
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -160,12 +130,12 @@ const IncidentManagerDetailPage = () => {
|
||||
return [
|
||||
...data,
|
||||
{
|
||||
name: testCaseData?.data?.name ?? '',
|
||||
name: testCase?.name ?? '',
|
||||
url: '',
|
||||
activeTitle: true,
|
||||
},
|
||||
];
|
||||
}, [testCaseData]);
|
||||
}, [testCase]);
|
||||
|
||||
const handleTabChange = (activeKey: string) => {
|
||||
if (activeKey !== activeTab) {
|
||||
@ -180,38 +150,36 @@ const IncidentManagerDetailPage = () => {
|
||||
const updateTestCase = async (id: string, patch: PatchOperation[]) => {
|
||||
try {
|
||||
const res = await updateTestCaseById(id, patch);
|
||||
onTestCaseUpdate(res);
|
||||
setTestCase(res);
|
||||
} catch (error) {
|
||||
showErrorToast(error as AxiosError);
|
||||
}
|
||||
};
|
||||
const handleOwnerChange = async (owner?: EntityReference) => {
|
||||
const data = testCaseData.data;
|
||||
if (data) {
|
||||
if (testCase) {
|
||||
const updatedTestCase = {
|
||||
...data,
|
||||
...testCase,
|
||||
owner,
|
||||
};
|
||||
const jsonPatch = compare(data, updatedTestCase);
|
||||
const jsonPatch = compare(testCase, updatedTestCase);
|
||||
|
||||
if (jsonPatch.length && data.id) {
|
||||
await updateTestCase(data.id, jsonPatch);
|
||||
if (jsonPatch.length && testCase.id) {
|
||||
await updateTestCase(testCase.id, jsonPatch);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDisplayNameChange = async (entityName?: EntityName) => {
|
||||
try {
|
||||
const data = testCaseData.data;
|
||||
if (data) {
|
||||
if (testCase) {
|
||||
const updatedTestCase = {
|
||||
...data,
|
||||
...testCase,
|
||||
...entityName,
|
||||
};
|
||||
const jsonPatch = compare(data, updatedTestCase);
|
||||
const jsonPatch = compare(testCase, updatedTestCase);
|
||||
|
||||
if (jsonPatch.length && data.id) {
|
||||
await updateTestCase(data.id, jsonPatch);
|
||||
if (jsonPatch.length && testCase.id) {
|
||||
await updateTestCase(testCase.id, jsonPatch);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@ -232,11 +200,17 @@ const IncidentManagerDetailPage = () => {
|
||||
fetchTestCaseData();
|
||||
getEntityFeedCount();
|
||||
} else {
|
||||
setTestCaseData((prev) => ({ ...prev, isLoading: false }));
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
// Cleanup function for unmount
|
||||
return () => {
|
||||
reset();
|
||||
testCaseClassBase.setShowSqlQueryTab(false);
|
||||
};
|
||||
}, [testCaseFQN, hasViewPermission]);
|
||||
|
||||
if (testCaseData.isLoading) {
|
||||
if (isLoading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
@ -244,7 +218,7 @@ const IncidentManagerDetailPage = () => {
|
||||
return <ErrorPlaceHolder type={ERROR_PLACEHOLDER_TYPE.PERMISSION} />;
|
||||
}
|
||||
|
||||
if (isUndefined(testCaseData.data)) {
|
||||
if (isUndefined(testCase)) {
|
||||
return <ErrorPlaceHolder />;
|
||||
}
|
||||
|
||||
@ -262,9 +236,9 @@ const IncidentManagerDetailPage = () => {
|
||||
<Col span={23}>
|
||||
<EntityHeaderTitle
|
||||
className="w-max-full-45"
|
||||
displayName={testCaseData.data?.displayName}
|
||||
displayName={testCase?.displayName}
|
||||
icon={<TestCaseIcon className="h-9" />}
|
||||
name={testCaseData.data?.name ?? ''}
|
||||
name={testCase?.name ?? ''}
|
||||
serviceName="testCase"
|
||||
/>
|
||||
</Col>
|
||||
@ -276,11 +250,11 @@ const IncidentManagerDetailPage = () => {
|
||||
}
|
||||
allowSoftDelete={false}
|
||||
canDelete={hasDeletePermission}
|
||||
displayName={testCaseData.data.displayName}
|
||||
displayName={testCase.displayName}
|
||||
editDisplayNamePermission={editDisplayNamePermission}
|
||||
entityFQN={testCaseData.data.fullyQualifiedName}
|
||||
entityId={testCaseData.data.id}
|
||||
entityName={testCaseData.data.name}
|
||||
entityFQN={testCase.fullyQualifiedName}
|
||||
entityId={testCase.id}
|
||||
entityName={testCase.name}
|
||||
entityType={EntityType.TEST_CASE}
|
||||
onEditDisplayName={handleDisplayNameChange}
|
||||
/>
|
||||
@ -290,7 +264,7 @@ const IncidentManagerDetailPage = () => {
|
||||
<Col className="p-x-lg">
|
||||
<IncidentManagerPageHeader
|
||||
fetchTaskCount={getEntityFeedCount}
|
||||
testCaseData={testCaseData.data}
|
||||
testCaseData={testCase}
|
||||
onOwnerUpdate={handleOwnerChange}
|
||||
/>
|
||||
</Col>
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
import { ReactElement } from 'react';
|
||||
import TabsLabel from '../../../components/common/TabsLabel/TabsLabel.component';
|
||||
import { TabsLabelProps } from '../../../components/common/TabsLabel/TabsLabel.interface';
|
||||
import TestCaseIncidentTab from '../../../components/DataQuality/IncidentManager/TestCaseIncidentTab/TestCaseIncidentTab.component';
|
||||
import TestCaseResultTab from '../../../components/DataQuality/IncidentManager/TestCaseResultTab/TestCaseResultTab.component';
|
||||
import i18n from '../../../utils/i18next/LocalUtil';
|
||||
import { IncidentManagerTabs } from '../IncidentManager.interface';
|
||||
|
||||
export interface TestCaseTabType {
|
||||
LabelComponent: typeof TabsLabel;
|
||||
labelProps: TabsLabelProps;
|
||||
Tab: () => ReactElement;
|
||||
key: IncidentManagerTabs;
|
||||
}
|
||||
|
||||
class TestCaseClassBase {
|
||||
showSqlQueryTab: boolean;
|
||||
|
||||
constructor() {
|
||||
this.showSqlQueryTab = false;
|
||||
}
|
||||
|
||||
public getTab(openTaskCount: number): TestCaseTabType[] {
|
||||
return [
|
||||
{
|
||||
LabelComponent: TabsLabel,
|
||||
labelProps: {
|
||||
id: 'test-case-result',
|
||||
name: i18n.t('label.test-case-result'),
|
||||
},
|
||||
Tab: TestCaseResultTab,
|
||||
key: IncidentManagerTabs.TEST_CASE_RESULTS,
|
||||
},
|
||||
{
|
||||
LabelComponent: TabsLabel,
|
||||
labelProps: {
|
||||
id: 'incident',
|
||||
name: i18n.t('label.incident'),
|
||||
count: openTaskCount,
|
||||
},
|
||||
Tab: TestCaseIncidentTab,
|
||||
key: IncidentManagerTabs.ISSUES,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
setShowSqlQueryTab(showSqlQueryTab: boolean) {
|
||||
this.showSqlQueryTab = showSqlQueryTab;
|
||||
}
|
||||
|
||||
public getFields(): string[] {
|
||||
return [
|
||||
'testSuite',
|
||||
'testCaseResult',
|
||||
'testDefinition',
|
||||
'owner',
|
||||
'incidentId',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
const testCaseClassBase = new TestCaseClassBase();
|
||||
|
||||
export default testCaseClassBase;
|
||||
export { TestCaseClassBase };
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
import { create } from 'zustand';
|
||||
import { TestCase } from '../../../generated/tests/testCase';
|
||||
|
||||
export interface UseTestCaseStoreInterface {
|
||||
testCase: TestCase | undefined;
|
||||
isLoading: boolean;
|
||||
setTestCase: (testCase: TestCase) => void;
|
||||
setIsLoading: (isLoading: boolean) => void;
|
||||
reset: () => void;
|
||||
}
|
||||
export const useTestCaseStore = create<UseTestCaseStoreInterface>()((set) => ({
|
||||
testCase: undefined,
|
||||
isLoading: true,
|
||||
setTestCase: (testCase: TestCase) => {
|
||||
set({ testCase });
|
||||
},
|
||||
setIsLoading: (isLoading: boolean) => {
|
||||
set({ isLoading });
|
||||
},
|
||||
reset: () => {
|
||||
set({ testCase: undefined, isLoading: true });
|
||||
},
|
||||
}));
|
Loading…
x
Reference in New Issue
Block a user