mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2026-01-04 03:15:27 +00:00
Test: Added test for ingestion and confirmation modal (#1389)
This commit is contained in:
parent
bfbb751faa
commit
bd3beb4604
@ -304,6 +304,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
className={classNames('tw-form-inputs tw-px-3 tw-py-1', {
|
||||
'tw-cursor-not-allowed': isUpdating,
|
||||
})}
|
||||
data-testid="name"
|
||||
id="name"
|
||||
name="name"
|
||||
placeholder="Ingestion name"
|
||||
@ -325,7 +326,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
className={classNames('tw-form-inputs tw-px-3 tw-py-1', {
|
||||
'tw-cursor-not-allowed': isUpdating,
|
||||
})}
|
||||
data-testid="selectService"
|
||||
data-testid="select-service"
|
||||
disabled={isUpdating}
|
||||
id="selectService"
|
||||
name="selectService"
|
||||
@ -350,7 +351,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
className={classNames('tw-form-inputs tw-px-3 tw-py-1', {
|
||||
'tw-cursor-not-allowed': !ingestionService,
|
||||
})}
|
||||
data-testid="selectService"
|
||||
data-testid="ingestion-type"
|
||||
disabled={!ingestionService || isUpdating}
|
||||
id="ingestionType"
|
||||
name="ingestionType"
|
||||
@ -386,6 +387,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="user-name"
|
||||
id="username"
|
||||
name="username"
|
||||
placeholder="User name"
|
||||
@ -401,6 +403,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="password"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
@ -416,6 +419,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="host"
|
||||
id="host"
|
||||
name="host"
|
||||
placeholder="Host"
|
||||
@ -431,6 +435,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="database"
|
||||
id="database"
|
||||
name="database"
|
||||
placeholder="Database"
|
||||
@ -446,7 +451,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="includeFilterPattern"
|
||||
data-testid="include-filter-pattern"
|
||||
id="includeFilterPattern"
|
||||
name="includeFilterPattern"
|
||||
placeholder="Include filter patterns comma seperated"
|
||||
@ -461,7 +466,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="excludeFilterPattern"
|
||||
data-testid="exclude-filter-pattern"
|
||||
id="excludeFilterPattern"
|
||||
name="excludeFilterPattern"
|
||||
placeholder="Exclude filter patterns comma seperated"
|
||||
@ -479,6 +484,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
'toggle-switch',
|
||||
includeViews ? 'open' : null
|
||||
)}
|
||||
data-testid="include-views"
|
||||
onClick={() => setIncludeViews(!includeViews)}>
|
||||
<div className="switch" />
|
||||
</div>
|
||||
@ -490,6 +496,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
'toggle-switch',
|
||||
excludeDataProfiler ? 'open' : null
|
||||
)}
|
||||
data-testid="data-profiler"
|
||||
onClick={() =>
|
||||
setExcludeDataProfiler(!excludeDataProfiler)
|
||||
}>
|
||||
@ -503,7 +510,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
case 3:
|
||||
return (
|
||||
<Fragment>
|
||||
<div className="tw-mt-4">
|
||||
<div className="tw-mt-4" data-testid="schedule-interval">
|
||||
<label htmlFor="">{requiredField('Schedule interval:')}</label>
|
||||
<div className="tw-flex tw-mt-2 tw-ml-3">
|
||||
<CronEditor
|
||||
@ -519,6 +526,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
<label htmlFor="startDate">Start date (UTC):</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="start-date"
|
||||
type="date"
|
||||
value={startDate}
|
||||
onChange={(e) => setStartDate(e.target.value)}
|
||||
@ -528,7 +536,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
<label htmlFor="endDate">End date (UTC):</label>
|
||||
<input
|
||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||
data-testid="endDate"
|
||||
data-testid="end-date"
|
||||
min={startDate}
|
||||
type="date"
|
||||
value={endDate}
|
||||
@ -541,7 +549,9 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
case 4:
|
||||
return (
|
||||
<Fragment>
|
||||
<div className="tw-flex tw-flex-col tw-mt-6">
|
||||
<div
|
||||
className="tw-flex tw-flex-col tw-mt-6"
|
||||
data-testid="preview-section">
|
||||
<PreviewSection
|
||||
className="tw-mb-4 tw-mt-4"
|
||||
data={[
|
||||
@ -658,15 +668,17 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
}, [startDate]);
|
||||
|
||||
return (
|
||||
<dialog className="tw-modal" data-testid="service-modal">
|
||||
<dialog className="tw-modal" data-testid="ingestion-modal-container">
|
||||
<div className="tw-modal-backdrop" />
|
||||
<div className="tw-modal-container tw-max-w-2xl">
|
||||
<div className="tw-modal-header">
|
||||
<p className="tw-modal-title">{header}</p>
|
||||
<p className="tw-modal-title" data-testid="modal-title">
|
||||
{header}
|
||||
</p>
|
||||
<div className="tw-flex">
|
||||
<svg
|
||||
className="tw-w-6 tw-h-6 tw-ml-1 tw-cursor-pointer"
|
||||
data-testid="closeWhatsNew"
|
||||
data-testid="close-modal"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
@ -681,19 +693,21 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tw-modal-body">
|
||||
<div className="tw-modal-body" data-testid="modal-body">
|
||||
<IngestionStepper activeStep={activeStep} steps={STEPS} />
|
||||
|
||||
<form className="tw-min-w-full" data-testid="form">
|
||||
<div className="tw-px-4">{getActiveStepFields(activeStep)}</div>
|
||||
</form>
|
||||
</div>
|
||||
<div className="tw-modal-footer tw-justify-between">
|
||||
<div
|
||||
className="tw-modal-footer tw-justify-between"
|
||||
data-testid="modal-footer">
|
||||
<Button
|
||||
className={classNames('tw-mr-2', {
|
||||
'tw-invisible': activeStep === 1,
|
||||
})}
|
||||
data-testid="cancel"
|
||||
data-testid="previous-button"
|
||||
size="regular"
|
||||
theme="primary"
|
||||
variant="text"
|
||||
@ -705,7 +719,7 @@ const IngestionModal: React.FC<IngestionModalProps> = ({
|
||||
{activeStep === 4 ? (
|
||||
<div className="tw-flex">
|
||||
<Button
|
||||
data-testid="save-button"
|
||||
data-testid="deploy-button"
|
||||
size="regular"
|
||||
theme="primary"
|
||||
type="submit"
|
||||
|
||||
@ -0,0 +1,219 @@
|
||||
import {
|
||||
findByTestId,
|
||||
findByText,
|
||||
fireEvent,
|
||||
render,
|
||||
} from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
import IngestionModal from './IngestionModal.component';
|
||||
|
||||
const mockFunction = jest.fn();
|
||||
const mockServiceList = [
|
||||
{
|
||||
name: 'aws_redshift',
|
||||
serviceType: 'Redshift',
|
||||
},
|
||||
];
|
||||
|
||||
jest.mock('../IngestionStepper/IngestionStepper.component', () => {
|
||||
return jest.fn().mockReturnValue(<p>IngestionStepper</p>);
|
||||
});
|
||||
|
||||
describe('Test Ingestion modal component', () => {
|
||||
it('Component Should render', async () => {
|
||||
const { container } = render(
|
||||
<IngestionModal
|
||||
header="Add Ingestion"
|
||||
ingestionList={[]}
|
||||
serviceList={mockServiceList}
|
||||
onCancel={mockFunction}
|
||||
/>,
|
||||
{
|
||||
wrapper: MemoryRouter,
|
||||
}
|
||||
);
|
||||
|
||||
const ingestionModalContainer = await findByTestId(
|
||||
container,
|
||||
'ingestion-modal-container'
|
||||
);
|
||||
const ingestionModalTitle = await findByTestId(container, 'modal-title');
|
||||
const closeSvgButton = await findByTestId(container, 'close-modal');
|
||||
const modalBody = await findByTestId(container, 'modal-body');
|
||||
const modalFooter = await findByTestId(container, 'modal-footer');
|
||||
const nextButton = await findByTestId(container, 'next-button');
|
||||
const previousButton = await findByTestId(container, 'previous-button');
|
||||
|
||||
expect(ingestionModalContainer).toBeInTheDocument();
|
||||
expect(ingestionModalTitle).toBeInTheDocument();
|
||||
expect(closeSvgButton).toBeInTheDocument();
|
||||
expect(modalBody).toBeInTheDocument();
|
||||
expect(modalFooter).toBeInTheDocument();
|
||||
expect(nextButton).toBeInTheDocument();
|
||||
expect(previousButton).toHaveClass('tw-invisible');
|
||||
expect(
|
||||
await findByText(container, /IngestionStepper/i)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Ingestion journey', async () => {
|
||||
const { container } = render(
|
||||
<IngestionModal
|
||||
addIngestion={mockFunction}
|
||||
header="Add Ingestion"
|
||||
ingestionList={[]}
|
||||
serviceList={mockServiceList}
|
||||
onCancel={mockFunction}
|
||||
/>,
|
||||
{
|
||||
wrapper: MemoryRouter,
|
||||
}
|
||||
);
|
||||
|
||||
// Step 1
|
||||
const nextButton = await findByTestId(container, 'next-button');
|
||||
const previousButton = await findByTestId(container, 'previous-button');
|
||||
|
||||
fireEvent.click(nextButton);
|
||||
|
||||
expect(
|
||||
await findByText(container, /Ingestion Name is required/i)
|
||||
).toBeInTheDocument();
|
||||
|
||||
const name = await findByTestId(container, 'name');
|
||||
fireEvent.change(name, {
|
||||
target: { value: 'mockName' },
|
||||
});
|
||||
|
||||
expect(name).toBeInTheDocument();
|
||||
expect(name).toHaveValue('mockName');
|
||||
|
||||
const service = await findByTestId(container, 'select-service');
|
||||
fireEvent.change(service, {
|
||||
target: { value: 'Redshift$$aws_redshift' },
|
||||
});
|
||||
|
||||
expect(service).toBeInTheDocument();
|
||||
expect(service).toHaveValue('Redshift$$aws_redshift');
|
||||
|
||||
const ingestionType = await findByTestId(container, 'ingestion-type');
|
||||
fireEvent.change(ingestionType, {
|
||||
target: { value: 'redshift' },
|
||||
});
|
||||
|
||||
expect(ingestionType).toBeInTheDocument();
|
||||
expect(ingestionType).toHaveValue('redshift');
|
||||
|
||||
fireEvent.click(nextButton);
|
||||
|
||||
// Step 2
|
||||
fireEvent.click(nextButton);
|
||||
|
||||
expect(
|
||||
await findByText(container, /Username is required/i)
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
await findByText(container, /Password is required/i)
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
await findByText(container, /Host is required/i)
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
await findByText(container, /Database is required/i)
|
||||
).toBeInTheDocument();
|
||||
expect(previousButton).not.toHaveClass('tw-invisible');
|
||||
|
||||
const userName = await findByTestId(container, 'user-name');
|
||||
fireEvent.change(userName, {
|
||||
target: { value: 'test' },
|
||||
});
|
||||
|
||||
expect(userName).toBeInTheDocument();
|
||||
expect(userName).toHaveValue('test');
|
||||
|
||||
const password = await findByTestId(container, 'password');
|
||||
fireEvent.change(password, {
|
||||
target: { value: 'password' },
|
||||
});
|
||||
|
||||
expect(password).toBeInTheDocument();
|
||||
expect(password).toHaveValue('password');
|
||||
|
||||
const host = await findByTestId(container, 'host');
|
||||
fireEvent.change(host, {
|
||||
target: { value: 'host' },
|
||||
});
|
||||
|
||||
expect(host).toBeInTheDocument();
|
||||
expect(host).toHaveValue('host');
|
||||
|
||||
const database = await findByTestId(container, 'database');
|
||||
fireEvent.change(database, {
|
||||
target: { value: 'database' },
|
||||
});
|
||||
|
||||
expect(database).toBeInTheDocument();
|
||||
expect(database).toHaveValue('database');
|
||||
|
||||
const includeFilterPattern = await findByTestId(
|
||||
container,
|
||||
'include-filter-pattern'
|
||||
);
|
||||
fireEvent.change(includeFilterPattern, {
|
||||
target: { value: 'include_pattern' },
|
||||
});
|
||||
|
||||
expect(includeFilterPattern).toBeInTheDocument();
|
||||
expect(includeFilterPattern).toHaveValue('include_pattern');
|
||||
|
||||
const excludeFilterPattern = await findByTestId(
|
||||
container,
|
||||
'exclude-filter-pattern'
|
||||
);
|
||||
fireEvent.change(excludeFilterPattern, {
|
||||
target: { value: 'exclude_pattern' },
|
||||
});
|
||||
|
||||
expect(excludeFilterPattern).toBeInTheDocument();
|
||||
expect(excludeFilterPattern).toHaveValue('exclude_pattern');
|
||||
|
||||
const includeViews = await findByTestId(container, 'include-views');
|
||||
fireEvent.click(includeViews);
|
||||
|
||||
expect(includeViews).toBeInTheDocument();
|
||||
expect(includeViews).not.toHaveClass('open');
|
||||
|
||||
const dataProfiler = await findByTestId(container, 'data-profiler');
|
||||
fireEvent.click(dataProfiler);
|
||||
|
||||
expect(dataProfiler).toBeInTheDocument();
|
||||
expect(dataProfiler).toHaveClass('open');
|
||||
|
||||
fireEvent.click(nextButton);
|
||||
|
||||
// Step 3
|
||||
const scheduleInterval = await findByTestId(container, 'schedule-interval');
|
||||
|
||||
expect(scheduleInterval).toBeInTheDocument();
|
||||
|
||||
const startDate = await findByTestId(container, 'start-date');
|
||||
const endDate = await findByTestId(container, 'end-date');
|
||||
|
||||
expect(startDate).toBeInTheDocument();
|
||||
expect(endDate).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(nextButton);
|
||||
|
||||
// Steps 4
|
||||
const preview = await findByTestId(container, 'preview-section');
|
||||
const deployButton = await findByTestId(container, 'deploy-button');
|
||||
|
||||
expect(preview).toBeInTheDocument();
|
||||
expect(deployButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(deployButton);
|
||||
|
||||
expect(mockFunction).toBeCalled();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,48 @@
|
||||
import { findByTestId, fireEvent, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import ConfirmationModal from './ConfirmationModal';
|
||||
|
||||
const mockConfirmation = jest.fn();
|
||||
const mockCancel = jest.fn();
|
||||
|
||||
describe('Test Ingestion modal component', () => {
|
||||
it('Component Should render', async () => {
|
||||
const { container } = render(
|
||||
<ConfirmationModal
|
||||
bodyText="Are you sure?"
|
||||
cancelText="Cancel"
|
||||
confirmText="Save"
|
||||
header="confirmation modal"
|
||||
onCancel={mockCancel}
|
||||
onConfirm={mockConfirmation}
|
||||
/>
|
||||
);
|
||||
|
||||
const confirmationModal = await findByTestId(
|
||||
container,
|
||||
'confirmation-modal'
|
||||
);
|
||||
const header = await findByTestId(container, 'modal-header');
|
||||
const bodyText = await findByTestId(container, 'body-text');
|
||||
const cancel = await findByTestId(container, 'cancel');
|
||||
const save = await findByTestId(container, 'save-button');
|
||||
|
||||
expect(confirmationModal).toBeInTheDocument();
|
||||
expect(header).toBeInTheDocument();
|
||||
expect(header.textContent).toStrictEqual('confirmation modal');
|
||||
expect(bodyText).toBeInTheDocument();
|
||||
expect(bodyText.textContent).toStrictEqual('Are you sure?');
|
||||
expect(cancel).toBeInTheDocument();
|
||||
expect(cancel.textContent).toStrictEqual('Cancel');
|
||||
expect(save).toBeInTheDocument();
|
||||
expect(save.textContent).toStrictEqual('Save');
|
||||
|
||||
fireEvent.click(cancel);
|
||||
|
||||
expect(mockCancel).toBeCalled();
|
||||
|
||||
fireEvent.click(save);
|
||||
|
||||
expect(mockConfirmation).toBeCalled();
|
||||
});
|
||||
});
|
||||
@ -29,13 +29,17 @@ const ConfirmationModal = ({
|
||||
bodyText,
|
||||
}: Props) => {
|
||||
return (
|
||||
<dialog className="tw-modal">
|
||||
<dialog className="tw-modal" data-testid="confirmation-modal">
|
||||
<div className="tw-modal-backdrop" />
|
||||
<div className="tw-modal-container tw-w-120">
|
||||
<div className={classNames('tw-modal-header', headerClassName)}>
|
||||
<p className="tw-modal-title">{header}</p>
|
||||
<p className="tw-modal-title" data-testid="modal-header">
|
||||
{header}
|
||||
</p>
|
||||
</div>
|
||||
<div className={classNames('tw-modal-body tw-h-28', bodyClassName)}>
|
||||
<div
|
||||
className={classNames('tw-modal-body tw-h-28', bodyClassName)}
|
||||
data-testid="body-text">
|
||||
<p>{bodyText}</p>
|
||||
</div>
|
||||
<div
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user