diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx index b0f44f06d80..48302876af6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.component.tsx @@ -226,7 +226,7 @@ const Ingestion: React.FC = ({ return ( -
+
{searchText || getSearchedIngestions().length > 0 ? ( @@ -246,7 +246,7 @@ const Ingestion: React.FC = ({ className={classNames('tw-h-8 tw-rounded tw-mb-2', { 'tw-opacity-40': !isAdminUser && !isAuthDisabled, })} - data-testid="add-new-user-button" + data-testid="add-new-ingestion-button" size="small" theme="primary" variant="contained" @@ -260,7 +260,7 @@ const Ingestion: React.FC = ({
- + diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.test.tsx new file mode 100644 index 00000000000..4ef65a471e4 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Ingestion/Ingestion.test.tsx @@ -0,0 +1,223 @@ +import { + findByTestId, + findByText, + fireEvent, + render, +} from '@testing-library/react'; +import React from 'react'; +import { MemoryRouter } from 'react-router'; +import { mockIngestionWorkFlow } from '../../pages/IngestionPage/IngestionPage.mock'; +import Ingestion from './Ingestion.component'; +import { IngestionData } from './ingestion.interface'; + +const mockPaging = { + after: 'after', + before: 'befor', + total: 1, +}; + +const mockFunction = jest.fn(); +const mockPaginghandler = jest.fn(); +const mockDeleteIngestion = jest.fn(); +const mockTriggerIngestion = jest + .fn() + .mockImplementation(() => Promise.resolve()); + +jest.mock('../common/non-admin-action/NonAdminAction', () => { + return jest + .fn() + .mockImplementation(({ children }: { children: React.ReactNode }) => ( +
{children}
+ )); +}); + +jest.mock('../containers/PageContainer', () => { + return jest + .fn() + .mockImplementation(({ children }: { children: React.ReactNode }) => ( +
{children}
+ )); +}); + +jest.mock('../common/searchbar/Searchbar', () => { + return jest.fn().mockImplementation(() =>
Searchbar
); +}); + +jest.mock('../common/next-previous/NextPrevious', () => { + return jest.fn().mockImplementation(() =>
NextPrevious
); +}); + +jest.mock('../IngestionModal/IngestionModal.component', () => { + return jest.fn().mockImplementation(() =>
IngestionModal
); +}); + +jest.mock('../Modals/ConfirmationModal/ConfirmationModal', () => { + return jest.fn().mockImplementation(() =>
ConfirmationModal
); +}); + +describe('Test Ingestion page', () => { + it('Page Should render', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + + const ingestionPageContainer = await findByTestId( + container, + 'ingestion-container' + ); + const searchBox = await findByText(container, /Searchbar/i); + const addIngestionButton = await findByTestId( + container, + 'add-new-ingestion-button' + ); + const ingestionTable = await findByTestId(container, 'ingestion-table'); + + expect(ingestionPageContainer).toBeInTheDocument(); + expect(searchBox).toBeInTheDocument(); + expect(addIngestionButton).toBeInTheDocument(); + expect(ingestionTable).toBeInTheDocument(); + }); + + it('Table should render necessary fields', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + + const ingestionTable = await findByTestId(container, 'ingestion-table'); + const tableHeaderContainer = await findByTestId(container, 'table-header'); + const runButton = await findByTestId(container, 'run'); + const editButton = await findByTestId(container, 'edit'); + const deleteButton = await findByTestId(container, 'delete'); + const tableHeaders: string[] = []; + + tableHeaderContainer.childNodes.forEach( + (node) => node.textContent && tableHeaders.push(node.textContent) + ); + + expect(ingestionTable).toBeInTheDocument(); + expect(tableHeaderContainer).toBeInTheDocument(); + expect(tableHeaders.length).toBe(6); + expect(tableHeaders).toStrictEqual([ + 'Name', + 'Type', + 'Service', + 'Schedule', + 'Recent Runs', + 'Actions', + ]); + expect(runButton).toBeInTheDocument(); + expect(editButton).toBeInTheDocument(); + expect(deleteButton).toBeInTheDocument(); + }); + + it('Pagination should be render if paging is provided', async () => { + const mockPagingAfter = { + after: 'afterKey', + before: 'beforeKey', + }; + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + + const nextPrevious = await findByText(container, /NextPrevious/i); + + expect(nextPrevious).toBeInTheDocument(); + }); + + it('CTA should work', async () => { + const mockPagingAfter = { + after: 'afterKey', + before: 'beforeKey', + }; + + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + + // on click of add ingestion + const addIngestionButton = await findByTestId( + container, + 'add-new-ingestion-button' + ); + fireEvent.click(addIngestionButton); + + expect(await findByText(container, /IngestionModal/i)).toBeInTheDocument(); + + (await findByText(container, /IngestionModal/i)).remove(); + + // on click of run button + + const runButton = await findByTestId(container, 'run'); + fireEvent.click(runButton); + + expect(mockTriggerIngestion).toBeCalled(); + + // on click of edit button + + const editButton = await findByTestId(container, 'edit'); + fireEvent.click(editButton); + + expect(await findByText(container, /IngestionModal/i)).toBeInTheDocument(); + + (await findByText(container, /IngestionModal/i)).remove(); + + // on click of delete button + + const deleteButton = await findByTestId(container, 'delete'); + fireEvent.click(deleteButton); + + expect( + await findByText(container, /ConfirmationModal/i) + ).toBeInTheDocument(); + + (await findByText(container, /ConfirmationModal/i)).remove(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/IngestionPage/IngestionPage.mock.ts b/openmetadata-ui/src/main/resources/ui/src/pages/IngestionPage/IngestionPage.mock.ts new file mode 100644 index 00000000000..6a6d6935bb0 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/pages/IngestionPage/IngestionPage.mock.ts @@ -0,0 +1,80 @@ +export const mockIngestionWorkFlow = { + data: { + data: [ + { + id: '3dae41fd-0469-483b-9d48-622577f2e075', + name: 'test1', + displayName: 'Test1', + owner: { + id: '360d5fd9-ba6b-4205-a92c-8eb98286c1c5', + type: 'user', + name: 'Aaron Johnson', + href: 'http://localhost:8585/api/v1/users/360d5fd9-ba6b-4205-a92c-8eb98286c1c5', + }, + fullyQualifiedName: 'bigquery.test1', + ingestionType: 'bigquery', + tags: [], + forceDeploy: true, + pauseWorkflow: false, + concurrency: 1, + startDate: '2021-11-24', + endDate: '2022-11-25', + workflowTimezone: 'UTC', + retries: 1, + retryDelay: 300, + workflowCatchup: false, + scheduleInterval: '0 12 * * *', + workflowTimeout: 60, + connectorConfig: { + username: 'test', + password: 'test', + host: 'http://localhost:3000/ingestion', + database: 'mysql', + includeViews: true, + enableDataProfiler: false, + includeFilterPattern: [], + excludeFilterPattern: [], + }, + ingestionStatuses: [], + service: { + id: 'e7e34bc7-fc12-40d6-9478-a6297cdefe7a', + type: 'databaseService', + name: 'bigquery', + description: 'BigQuery service used for shopify data', + href: 'http://localhost:8585/api/v1/services/databaseServices/e7e34bc7-fc12-40d6-9478-a6297cdefe7a', + }, + href: 'http://localhost:8585/api/ingestion/3dae41fd-0469-483b-9d48-622577f2e075', + version: 0.1, + updatedAt: 1637736180218, + updatedBy: 'anonymous', + }, + ], + paging: { + total: 1, + }, + }, +}; + +export const mockService = { + data: { + data: [ + { + id: 'e7e34bc7-fc12-40d6-9478-a6297cdefe7a', + name: 'bigquery', + serviceType: 'BigQuery', + description: 'BigQuery service used for shopify data', + version: 0.1, + updatedAt: 1637734235276, + updatedBy: 'anonymous', + href: 'http://localhost:8585/api/v1/services/databaseServices/e7e34bc7-fc12-40d6-9478-a6297cdefe7a', + jdbc: { + driverClass: 'jdbc', + connectionUrl: 'jdbc://localhost', + }, + }, + ], + paging: { + total: 1, + }, + }, +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/IngestionPage/IngestionPage.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/IngestionPage/IngestionPage.test.tsx new file mode 100644 index 00000000000..a3ebb3862bd --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/pages/IngestionPage/IngestionPage.test.tsx @@ -0,0 +1,36 @@ +import { findByText, render } from '@testing-library/react'; +import React from 'react'; +import IngestionPage from './IngestionPage.component'; +import { mockIngestionWorkFlow, mockService } from './IngestionPage.mock'; + +jest.mock('../../components/Ingestion/Ingestion.component', () => { + return jest.fn().mockReturnValue(

Ingestion Component

); +}); + +jest.mock('../../axiosAPIs/serviceAPI', () => ({ + getServices: jest.fn().mockImplementation(() => Promise.resolve(mockService)), +})); + +jest.mock('../../axiosAPIs/ingestionWorkflowAPI', () => ({ + addIngestionWorkflow: jest.fn(), + deleteIngestionWorkflowsById: jest + .fn() + .mockImplementation(() => Promise.resolve()), + getIngestionWorkflows: jest + .fn() + .mockImplementation(() => Promise.resolve(mockIngestionWorkFlow)), + triggerIngestionWorkflowsById: jest + .fn() + .mockImplementation(() => Promise.resolve()), + updateIngestionWorkflow: jest.fn(), +})); + +describe('Test Ingestion page', () => { + it('Page Should render', async () => { + const { container } = render(); + + const ingestionPage = await findByText(container, /Ingestion Component/i); + + expect(ingestionPage).toBeInTheDocument(); + }); +});
Name Type Service