ui: added unit test for data quality component part 2 (#12279)

* ui: added unit test for data quality component part 2

* added unit test for testSuitePage and editTestCaseModal

* updated test with findByLabelText function

* updated test for editTestCaseModal

* fixed redirection spec in cypress
This commit is contained in:
Shailesh Parmar 2023-07-11 10:34:44 +05:30 committed by GitHub
parent 56ac4157e6
commit c3e37f4f55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 697 additions and 19 deletions

View File

@ -63,7 +63,7 @@ export const LEFT_PANEL_DETAILS = {
export const NAVBAR_DETAILS = {
explore: {
testid: '[data-testid="appbar-item-explore"]',
url: `${BASE_URL}/explore/tables?page=1`,
url: `${BASE_URL}/explore/tables`,
},
quality: {
testid: '[data-testid="appbar-item-data-quality"]',

View File

@ -0,0 +1,121 @@
/*
* 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 { act, fireEvent, render, screen } from '@testing-library/react';
import {
MOCK_TEST_CASE,
MOCK_TEST_DEFINITION_COLUMN_VALUES_TO_MATCH_REGEX,
} from 'mocks/TestSuite.mock';
import React, { forwardRef } from 'react';
import { EditTestCaseModalProps } from './AddDataQualityTest.interface';
import EditTestCaseModal from './EditTestCaseModal';
const mockProps: EditTestCaseModalProps = {
visible: true,
testCase: MOCK_TEST_CASE[0],
onCancel: jest.fn(),
onUpdate: jest.fn(),
};
jest.mock('../common/rich-text-editor/RichTextEditor', () => {
return forwardRef(
jest.fn().mockImplementation(() => <div>RichTextEditor.component</div>)
);
});
jest.mock('./components/ParameterForm', () => {
return jest.fn().mockImplementation(() => <div>ParameterForm.component</div>);
});
jest.mock('rest/testAPI', () => {
return {
getTestDefinitionById: jest
.fn()
.mockImplementation(() =>
Promise.resolve(MOCK_TEST_DEFINITION_COLUMN_VALUES_TO_MATCH_REGEX)
),
updateTestCaseById: jest.fn().mockImplementation(() => Promise.resolve()),
};
});
describe('EditTestCaseModal Component', () => {
it('component should render', async () => {
render(<EditTestCaseModal {...mockProps} />);
expect(await screen.findByTestId('edit-test-form')).toBeInTheDocument();
expect(await screen.findByLabelText('label.table')).toBeInTheDocument();
expect(await screen.findByLabelText('label.column')).toBeInTheDocument();
expect(await screen.findByLabelText('label.name')).toBeInTheDocument();
expect(
await screen.findByLabelText('label.display-name')
).toBeInTheDocument();
expect(
await screen.findByLabelText('label.test-entity')
).toBeInTheDocument();
expect(
await screen.findByText('RichTextEditor.component')
).toBeInTheDocument();
expect(
await screen.findByText('ParameterForm.component')
).toBeInTheDocument();
expect(await screen.findByText('label.cancel')).toBeInTheDocument();
expect(await screen.findByText('label.submit')).toBeInTheDocument();
});
it('table, name, test definition, should be disabled', async () => {
render(<EditTestCaseModal {...mockProps} />);
expect(await screen.findByLabelText('label.name')).toBeDisabled();
expect(await screen.findByLabelText('label.column')).toBeDisabled();
expect(await screen.findByLabelText('label.table')).toBeDisabled();
expect(await screen.findByLabelText('label.test-entity')).toBeDisabled();
});
it('fields should have data based on testCase value', async () => {
render(<EditTestCaseModal {...mockProps} />);
expect(await screen.findByLabelText('label.table')).toHaveValue(
'dim_address'
);
expect(await screen.findByLabelText('label.column')).toHaveValue(
'last_name'
);
expect(await screen.findByLabelText('label.name')).toHaveValue(
'column_values_to_match_regex'
);
expect(await screen.findByLabelText('label.test-entity')).toHaveValue(
'columnValuesToMatchRegex'
);
});
it('should call onCancel function, on click of cancel button', async () => {
render(<EditTestCaseModal {...mockProps} />);
const cancelBtn = await screen.findByText('label.cancel');
await act(async () => {
fireEvent.click(cancelBtn);
});
expect(mockProps.onCancel).toHaveBeenCalled();
});
it('should call onUpdate function, on click of submit button', async () => {
render(<EditTestCaseModal {...mockProps} />);
const submitBtn = await screen.findByText('label.submit');
await act(async () => {
fireEvent.click(submitBtn);
});
expect(mockProps.onUpdate).toHaveBeenCalled();
});
});

View File

@ -198,6 +198,7 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
form.resetFields();
onCancel();
}}
cancelText={t('label.cancel')}
closable={false}
confirmLoading={isLoadingOnSave}
maskClosable={false}
@ -212,21 +213,22 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
) : (
<Form
className="tw-h-70vh tw-overflow-auto"
data-testid="edit-test-form"
form={form}
layout="vertical"
name="tableTestForm"
onFinish={handleFormSubmit}>
<Form.Item required label={`${t('label.table')}`} name="table">
<Form.Item required label={t('label.table')} name="table">
<Input disabled />
</Form.Item>
{isColumn && (
<Form.Item required label={`${t('label.column')}`} name="column">
<Form.Item required label={t('label.column')} name="column">
<Input disabled />
</Form.Item>
)}
<Form.Item
required
label={`${t('label.name')}`}
label={t('label.name')}
name="name"
rules={[
{
@ -241,16 +243,16 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
</Form.Item>
<Form.Item
required
label={`${t('label.test-entity', {
label={t('label.test-entity', {
entity: t('label.type'),
})}:`}
})}
name="testDefinition">
<Input disabled placeholder={t('message.enter-test-case-name')} />
</Form.Item>
{GenerateParamsField()}
<Form.Item label={`${t('label.description')}`} name="description">
<Form.Item label={t('label.description')} name="description">
<RichTextEditor
height="200px"
initialValue={testCase?.description || ''}

View File

@ -14,12 +14,12 @@ import { Col, Row } from 'antd';
import { AxiosError } from 'axios';
import { SummaryCard } from 'components/common/SummaryCard/SummaryCard.component';
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
import { INITIAL_TEST_SUMMARY } from 'constants/TestSuite.constant';
import { TestSummary } from 'generated/tests/testSuite';
import { isUndefined } from 'lodash';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { getTestCaseExecutionSummary } from 'rest/testAPI';
import {} from 'utils/CommonUtils';
import { showErrorToast } from 'utils/ToastUtils';
import { SummaryPanelProps } from './SummaryPanel.interface';
@ -44,12 +44,13 @@ export const SummaryPanel = ({ testSummary }: SummaryPanelProps) => {
};
useEffect(() => {
if (isUndefined(testSummary)) {
if (testCasePermission?.ViewAll || testCasePermission?.ViewBasic) {
fetchTestSummary();
}
if (
isUndefined(testSummary) &&
(testCasePermission?.ViewAll || testCasePermission?.ViewBasic)
) {
fetchTestSummary();
} else {
setSummary(testSummary);
setSummary(testSummary ?? INITIAL_TEST_SUMMARY);
setIsLoading(false);
}
}, [testCasePermission]);

View File

@ -0,0 +1,89 @@
/*
* 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 { render, screen } from '@testing-library/react';
import React from 'react';
import { getTestCaseExecutionSummary } from 'rest/testAPI';
import { SummaryPanel } from './SummaryPanel.component';
const testCasePermission = {
Create: true,
Delete: true,
ViewAll: true,
EditAll: true,
EditDescription: true,
EditDisplayName: true,
EditCustomFields: true,
};
const mockSummary = {
total: 10,
success: 7,
aborted: 2,
failed: 1,
};
jest.mock('components/PermissionProvider/PermissionProvider', () => ({
usePermissionProvider: jest.fn().mockImplementation(() => ({
permissions: {
testCase: testCasePermission,
},
})),
}));
jest.mock('components/common/SummaryCard/SummaryCard.component', () => {
return {
SummaryCard: jest
.fn()
.mockImplementation(() => <div>SummaryCard.component</div>),
};
});
jest.mock('rest/testAPI', () => {
return {
getTestCaseExecutionSummary: jest
.fn()
.mockImplementation(() => Promise.resolve(mockSummary)),
};
});
describe('SummaryPanel component', () => {
it('component should render', async () => {
render(<SummaryPanel />);
const summaryCards = await screen.findAllByText('SummaryCard.component');
expect(summaryCards).toHaveLength(4);
});
it('on page load getTestCaseExecutionSummary API should call', async () => {
const mockGetTestCaseExecutionSummary =
getTestCaseExecutionSummary as jest.Mock;
render(<SummaryPanel />);
expect(mockGetTestCaseExecutionSummary).toHaveBeenCalled();
});
it('should not call getTestCaseExecutionSummary API, if testSummary data is provided', async () => {
const mockGetTestCaseExecutionSummary =
getTestCaseExecutionSummary as jest.Mock;
render(<SummaryPanel testSummary={mockSummary} />);
expect(mockGetTestCaseExecutionSummary).not.toHaveBeenCalled();
});
it('should not call getTestCaseExecutionSummary API, if there is no permission', async () => {
const mockGetTestCaseExecutionSummary =
getTestCaseExecutionSummary as jest.Mock;
testCasePermission.ViewAll = false;
render(<SummaryPanel />);
expect(mockGetTestCaseExecutionSummary).not.toHaveBeenCalled();
});
});

View File

@ -51,6 +51,7 @@ export const TestCaseStatusModal = ({
return (
<Modal
cancelText={t('label.cancel')}
closable={false}
okButtonProps={{
form: 'update-status-form',
@ -63,6 +64,7 @@ export const TestCaseStatusModal = ({
width={750}
onCancel={onCancel}>
<Form<TestCaseFailureStatus>
data-testid="update-status-form"
form={form}
id="update-status-form"
initialValues={data}

View File

@ -0,0 +1,97 @@
/*
* 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 { act, fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TestCaseFailureStatusType } from 'generated/tests/testCase';
import React, { forwardRef } from 'react';
import { TestCaseStatusModal } from './TestCaseStatusModal.component';
import { TestCaseStatusModalProps } from './TestCaseStatusModal.interface';
const mockProps: TestCaseStatusModalProps = {
open: true,
onCancel: jest.fn(),
onSubmit: jest.fn().mockImplementation(() => Promise.resolve()),
};
jest.mock('components/common/rich-text-editor/RichTextEditor', () => {
return forwardRef(jest.fn().mockReturnValue(<div>RichTextEditor</div>));
});
jest.mock('generated/tests/testCase', () => ({
...jest.requireActual('generated/tests/testCase'),
TestCaseFailureStatusType: {
ACK: 'Ack',
New: 'New',
Resolved: 'Resolved',
},
}));
describe('TestCaseStatusModal component', () => {
it('component should render', async () => {
render(<TestCaseStatusModal {...mockProps} />);
expect(await screen.findByTestId('update-status-form')).toBeInTheDocument();
expect(await screen.findByLabelText('label.status')).toBeInTheDocument();
expect(await screen.findByText('label.cancel')).toBeInTheDocument();
expect(await screen.findByText('label.submit')).toBeInTheDocument();
});
it('should render test case reason and comment field, if status is resolved', async () => {
render(
<TestCaseStatusModal
{...mockProps}
data={{ testCaseFailureStatusType: TestCaseFailureStatusType.Resolved }}
/>
);
expect(await screen.findByLabelText('label.status')).toBeInTheDocument();
expect(await screen.findByLabelText('label.reason')).toBeInTheDocument();
expect(await screen.findByText('RichTextEditor')).toBeInTheDocument();
});
it('should call onCancel function, on click of cancel button', async () => {
render(
<TestCaseStatusModal
{...mockProps}
data={{ testCaseFailureStatusType: TestCaseFailureStatusType.Resolved }}
/>
);
const cancelBtn = await screen.findByText('label.cancel');
await act(async () => {
fireEvent.click(cancelBtn);
});
expect(mockProps.onCancel).toHaveBeenCalled();
});
it('should call onSubmit function, on click of save button', async () => {
render(<TestCaseStatusModal {...mockProps} />);
const submitBtn = await screen.findByText('label.submit');
const status = await screen.findByLabelText('label.status');
await act(async () => {
userEvent.click(status);
});
const statusOption = await screen.findAllByText('New');
await act(async () => {
fireEvent.click(statusOption[1]);
});
await act(async () => {
fireEvent.click(submitBtn);
});
expect(mockProps.onSubmit).toHaveBeenCalled();
});
});

View File

@ -40,11 +40,11 @@ export const OwnerLabel = ({
const profilePicture = useMemo(() => {
if (isUndefined(owner)) {
return <IconUser height={18} width={18} />;
return <IconUser data-testid="no-owner-icon" height={18} width={18} />;
}
return owner.type === OwnerType.TEAM ? (
<IconTeamsGrey height={18} width={18} />
<IconTeamsGrey data-testid="team-owner-icon" height={18} width={18} />
) : (
<ProfilePicture
displayName={displayName}

View File

@ -0,0 +1,100 @@
/*
* 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 { render, screen } from '@testing-library/react';
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { OwnerLabel } from './OwnerLabel.component';
const mockOwner = {
id: 'id',
type: 'user',
name: 'Test Name',
};
const mockTeamOwner = {
id: 'id',
type: 'team',
name: 'Team Name',
};
jest.mock('../ProfilePicture/ProfilePicture', () => {
return jest.fn().mockReturnValue(<div>ProfilePicture.component</div>);
});
jest.mock('../UserTeamSelectableList/UserTeamSelectableList.component', () => {
return {
UserTeamSelectableList: jest
.fn()
.mockReturnValue(<div>UserTeamSelectableList.component</div>),
};
});
describe('OwnerLabel component', () => {
it('owner name with profile picture should render', async () => {
render(<OwnerLabel owner={mockOwner} />, { wrapper: MemoryRouter });
expect(
await screen.findByText('ProfilePicture.component')
).toBeInTheDocument();
expect(await screen.findByText(mockOwner.name)).toBeInTheDocument();
});
it('should render displayName if provided', async () => {
render(
<OwnerLabel
owner={{ id: 'id', type: 'user', displayName: 'displayName' }}
/>,
{ wrapper: MemoryRouter }
);
expect(
await screen.findByText('ProfilePicture.component')
).toBeInTheDocument();
expect(await screen.findByText('displayName')).toBeInTheDocument();
});
it('should render ownerDisplayName if provided', async () => {
render(
<OwnerLabel owner={mockOwner} ownerDisplayName="ownerDisplayName" />,
{ wrapper: MemoryRouter }
);
expect(
await screen.findByText('ProfilePicture.component')
).toBeInTheDocument();
expect(await screen.findByText('ownerDisplayName')).toBeInTheDocument();
expect(screen.queryByText(mockOwner.name)).not.toBeInTheDocument();
});
it('should render no owner if owner is undefined', async () => {
render(<OwnerLabel />, { wrapper: MemoryRouter });
expect(await screen.findByText('label.no-entity')).toBeInTheDocument();
expect(await screen.findByTestId('no-owner-icon')).toBeInTheDocument();
});
it('should render team icon and team name if owner is team', async () => {
render(<OwnerLabel owner={mockTeamOwner} />, { wrapper: MemoryRouter });
expect(await screen.findByText(mockTeamOwner.name)).toBeInTheDocument();
expect(await screen.findByTestId('team-owner-icon')).toBeInTheDocument();
});
it('should render UserTeamSelectableList if onUpdate function is provided', async () => {
render(<OwnerLabel owner={mockTeamOwner} onUpdate={jest.fn()} />, {
wrapper: MemoryRouter,
});
expect(
await screen.findByText('UserTeamSelectableList.component')
).toBeInTheDocument();
});
});

View File

@ -37,19 +37,27 @@ export const SummaryCard = ({
if (isLoading) {
return (
<div className={classNames('summary-card', className)}>
<div
className={classNames('summary-card', className)}
data-testid="skeleton-loading">
<Skeleton active loading />
</div>
);
}
return (
<Space className={classNames('summary-card', className)}>
<Space
className={classNames('summary-card', className)}
data-testid="summary-card-container">
<div>
<Typography.Paragraph className="summary-card-title">
<Typography.Paragraph
className="summary-card-title"
data-testid="summary-card-title">
{title}
</Typography.Paragraph>
<Typography.Paragraph className="summary-card-description">
<Typography.Paragraph
className="summary-card-description"
data-testid="summary-card-description">
{isNumber(value) ? formatNumberWithComma(value) : value}
</Typography.Paragraph>
</div>
@ -57,6 +65,7 @@ export const SummaryCard = ({
{showProgressBar && (
<Progress
className={type}
data-testid="progress-bar"
format={(percent) => `${percent}%`}
percent={percent}
type="circle"

View File

@ -0,0 +1,70 @@
/*
* 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 { render, screen } from '@testing-library/react';
import React from 'react';
import { SummaryCard } from './SummaryCard.component';
import { SummaryCardProps } from './SummaryCard.interface';
const mockProps: SummaryCardProps = {
title: 'title',
value: 10,
total: 100,
};
describe('SummaryCard component', () => {
it('component should render', async () => {
render(<SummaryCard {...mockProps} />);
expect(
await screen.findByTestId('summary-card-container')
).toBeInTheDocument();
expect(await screen.findByTestId('summary-card-title')).toBeInTheDocument();
expect(
await screen.findByTestId('summary-card-description')
).toBeInTheDocument();
expect(await screen.findByRole('presentation')).toBeInTheDocument();
});
it('should not render progress bar, if showProgressBar is false', async () => {
render(<SummaryCard {...mockProps} showProgressBar={false} />);
expect(screen.queryByRole('presentation')).not.toBeInTheDocument();
});
it('should not render skeleton loader, if isLoading is true', async () => {
render(<SummaryCard {...mockProps} isLoading />);
expect(await screen.findByTestId('skeleton-loading')).toBeInTheDocument();
});
it('should render progress bar based on type', async () => {
render(<SummaryCard {...mockProps} type="success" />);
const progressBar = await screen.findByTestId('progress-bar');
expect(progressBar).toBeInTheDocument();
expect(progressBar).toHaveClass('success');
});
it('should render title and description based on props', async () => {
render(<SummaryCard title="summary title" total={0} value="description" />);
const title = await screen.findByTestId('summary-card-title');
const description = await screen.findByTestId('summary-card-description');
expect(title).toBeInTheDocument();
expect(description).toBeInTheDocument();
expect(title.textContent).toStrictEqual('summary title');
expect(description.textContent).toStrictEqual('description');
});
});

View File

@ -673,6 +673,41 @@ export const MOCK_SQL_TEST_CASE = {
deleted: false,
} as TestCase;
export const MOCK_TEST_DEFINITION_COLUMN_VALUES_TO_MATCH_REGEX = {
id: '4c69c0d7-c173-4f17-b939-737ce0510f66',
name: 'columnValuesToMatchRegex',
displayName: 'Column Values To Match Regex Pattern',
fullyQualifiedName: 'columnValuesToMatchRegex',
description:
'This schema defines the test ColumnValuesToMatchRegex. Test the values in a column to match a given regular expression. ',
entityType: 'COLUMN',
testPlatforms: ['OpenMetadata'],
supportedDataTypes: [
'BYTES',
'STRING',
'MEDIUMTEXT',
'TEXT',
'CHAR',
'VARCHAR',
],
parameterDefinition: [
{
name: 'regex',
displayName: 'RegEx Pattern',
dataType: 'STRING',
description:
'The regular expression the column entries should match. For database without regex support (i.e. MSSQL, AzureSQL) this test will use `LIKE`.',
required: true,
optionValues: [],
},
],
version: 0.1,
updatedAt: 1682571176093,
updatedBy: 'admin',
href: 'href',
deleted: false,
};
export const MOCK_CHART_COLLECTION_DATA = {
data: [
{

View File

@ -332,6 +332,7 @@ const TestSuiteDetailsPage = () => {
{(testSuitePermissions.EditAll ||
testSuitePermissions.EditTests) && (
<Button
data-testid="add-test-case-btn"
type="primary"
onClick={() => setIsTestCaseModalOpen(true)}>
{t('label.add-entity', {

View File

@ -0,0 +1,151 @@
/*
* 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 { act, render, screen } from '@testing-library/react';
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
import { mockEntityPermissions } from 'pages/DatabaseSchemaPage/mocks/DatabaseSchemaPage.mock';
import React from 'react';
import { getTestSuiteByName } from 'rest/testAPI';
import TestSuiteDetailsPage from './TestSuiteDetailsPage.component';
jest.mock('components/containers/PageLayoutV1', () => {
return jest.fn().mockImplementation(({ children }) => <div>{children}</div>);
});
jest.mock('components/Loader/Loader', () => {
return jest.fn().mockImplementation(() => <div>Loader.component</div>);
});
jest.mock(
'components/common/title-breadcrumb/title-breadcrumb.component',
() => {
return jest
.fn()
.mockImplementation(() => <div>TitleBreadcrumb.component</div>);
}
);
jest.mock('components/common/error-with-placeholder/ErrorPlaceHolder', () => {
return jest
.fn()
.mockImplementation(() => <div>ErrorPlaceHolder.component</div>);
});
jest.mock('components/common/EntitySummaryDetails/EntitySummaryDetails', () => {
return jest
.fn()
.mockImplementation(() => <div>EntitySummaryDetails.component</div>);
});
jest.mock('components/common/entityPageInfo/ManageButton/ManageButton', () => {
return jest.fn().mockImplementation(() => <div>ManageButton.component</div>);
});
jest.mock('components/common/description/Description', () => {
return jest.fn().mockImplementation(() => <div>Description.component</div>);
});
jest.mock('components/ProfilerDashboard/component/DataQualityTab', () => {
return jest
.fn()
.mockImplementation(() => <div>DataQualityTab.component</div>);
});
jest.mock('components/authentication/auth-provider/AuthProvider', () => {
return {
useAuthContext: jest
.fn()
.mockImplementation(() => ({ isAuthDisabled: true })),
};
});
jest.mock('hooks/authHooks', () => {
return {
useAuth: jest.fn().mockImplementation(() => ({ isAdminUser: true })),
};
});
jest.mock('react-router-dom', () => {
return {
useHistory: jest.fn().mockImplementation(() => ({ push: jest.fn() })),
useParams: jest
.fn()
.mockImplementation(() => ({ testSuiteFQN: 'testSuiteFQN' })),
};
});
jest.mock('rest/testAPI', () => {
return {
getTestSuiteByName: jest.fn().mockImplementation(() => Promise.resolve()),
updateTestSuiteById: jest.fn().mockImplementation(() => Promise.resolve()),
addTestCaseToLogicalTestSuite: jest
.fn()
.mockImplementation(() => Promise.resolve()),
getListTestCase: jest
.fn()
.mockImplementation(() => Promise.resolve({ data: [] })),
ListTestCaseParams: jest
.fn()
.mockImplementation(() => Promise.resolve({ data: [] })),
};
});
jest.mock('components/PermissionProvider/PermissionProvider', () => ({
usePermissionProvider: jest.fn().mockImplementation(() => ({
getEntityPermissionByFqn: jest
.fn()
.mockImplementation(() => Promise.resolve(mockEntityPermissions)),
})),
}));
describe('TestSuiteDetailsPage component', () => {
it('component should render', async () => {
render(<TestSuiteDetailsPage />);
expect(
await screen.findByText('TitleBreadcrumb.component')
).toBeInTheDocument();
expect(
await screen.findByText('ManageButton.component')
).toBeInTheDocument();
expect(
await screen.findByText('EntitySummaryDetails.component')
).toBeInTheDocument();
expect(
await screen.findByText('Description.component')
).toBeInTheDocument();
expect(
await screen.findByText('DataQualityTab.component')
).toBeInTheDocument();
expect(await screen.findByTestId('add-test-case-btn')).toBeInTheDocument();
});
it('should call test suite API on page load', async () => {
const mockGetTestSuiteByName = getTestSuiteByName as jest.Mock;
await act(async () => {
render(<TestSuiteDetailsPage />);
});
expect(mockGetTestSuiteByName).toHaveBeenCalledWith('testSuiteFQN', {
fields: 'owner,tests',
include: 'all',
});
});
it('should show no permission error if there is no permission', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementation(() =>
Promise.resolve({
...mockEntityPermissions,
ViewAll: false,
ViewBasic: false,
})
),
}));
await act(async () => {
render(<TestSuiteDetailsPage />);
});
expect(
await screen.findByText('ErrorPlaceHolder.component')
).toBeInTheDocument();
});
});