From f98ea0fa878f4ca37f10f873e95bd49d0033a3c4 Mon Sep 17 00:00:00 2001 From: Sweta Agarwalla <105535990+sweta1308@users.noreply.github.com> Date: Thu, 16 Oct 2025 15:16:17 +0530 Subject: [PATCH] fix(ui): add fixes for workflow API (#23917) * add fixes for workflow API * Fix the ingestion runner display name being passed to API --------- Co-authored-by: Aniket Katkar --- .../TestConnection/TestConnection.test.tsx | 48 ++++++++++++++++++ .../common/TestConnection/TestConnection.tsx | 12 ++++- .../ServiceDetailsPage.test.tsx | 49 +++++++++++++++++-- .../ServiceDetailsPage/ServiceDetailsPage.tsx | 2 +- 4 files changed, 103 insertions(+), 8 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.test.tsx index 85b8d370a27..06142208680 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.test.tsx @@ -238,6 +238,54 @@ describe('Test Connection Component', () => { ); }); + it('Should create workflow with ingestionRunner when ingestionRunner is present in formData', async () => { + jest.useFakeTimers(); + await act(async () => { + render( + + ({ + ...FORM_DATA, + ingestionRunner: 'custom-runner-name', + } as ConfigData) + } + /> + ); + }); + const controller = new AbortController(); + + const testConnectionButton = screen.getByTestId('test-connection-btn'); + + await act(async () => { + fireEvent.click(testConnectionButton); + }); + + expect(addWorkflow).toHaveBeenCalledWith( + CREATE_WORKFLOW_PAYLOAD_WITH_RUNNER, + controller.signal + ); + }); + + it('Should create workflow without ingestionRunner field when ingestionRunner is not in formData and in extraInfo', async () => { + jest.useFakeTimers(); + await act(async () => { + render(); + }); + const controller = new AbortController(); + + const testConnectionButton = screen.getByTestId('test-connection-btn'); + + await act(async () => { + fireEvent.click(testConnectionButton); + }); + + expect(addWorkflow).toHaveBeenCalledWith( + CREATE_WORKFLOW_PAYLOAD, + controller.signal + ); + }); + it('Should show success message if test connection successful', async () => { jest.useFakeTimers(); await act(async () => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.tsx index 45ad5a28190..5e5487e4e76 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/TestConnection/TestConnection.tsx @@ -280,16 +280,24 @@ const TestConnection: FC = ({ timeoutId?: number; } = {}; + const { ingestionRunner, ...rest } = updatedFormData as ConfigObject & { + ingestionRunner?: string; + }; + try { + const ingestionRunnerValue = extraInfo ?? ingestionRunner; + const createWorkflowData: CreateWorkflow = { name: getTestConnectionName(connectionType), workflowType: WorkflowType.TestConnection, request: { - connection: { config: updatedFormData as ConfigObject }, + connection: { config: rest }, serviceType, connectionType, serviceName, - ingestionRunner: extraInfo, + ...(ingestionRunnerValue && { + ingestionRunner: ingestionRunnerValue, + }), }, }; diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.test.tsx index d6780da7942..ea035245eb9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.test.tsx @@ -17,6 +17,7 @@ import { MemoryRouter, useNavigate } from 'react-router-dom'; import { noop } from 'lodash'; import { act } from 'react'; +import { TestConnectionProps } from '../../components/common/TestConnection/TestConnection.interface'; import { ROUTES } from '../../constants/constants'; import { OPEN_METADATA } from '../../constants/Services.constant'; import { usePermissionProvider } from '../../context/PermissionProvider/PermissionProvider'; @@ -42,6 +43,7 @@ import { getWorkflowInstancesForApplication, getWorkflowInstanceStateById, } from '../../rest/workflowAPI'; +import serviceUtilClassBase from '../../utils/ServiceUtilClassBase'; import { getCountLabel, shouldTestConnection } from '../../utils/ServiceUtils'; import { showErrorToast } from '../../utils/ToastUtils'; import { useRequiredParams } from '../../utils/useRequiredParams'; @@ -357,11 +359,16 @@ jest.mock( ); jest.mock('../../components/common/TestConnection/TestConnection', () => - jest.fn().mockImplementation(({ serviceCategory }: any) => ( -
- {serviceCategory} -
- )) + jest + .fn() + .mockImplementation( + ({ serviceCategory, extraInfo }: TestConnectionProps) => ( +
+ {serviceCategory} + {extraInfo} +
+ ) + ) ); jest.mock('../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder', () => @@ -1092,6 +1099,38 @@ describe('ServiceDetailsPage', () => { }); }); + describe('Test connection tab', () => { + const mockServiceUtil = serviceUtilClassBase as jest.Mocked< + typeof serviceUtilClassBase + >; + + it('should pass ingestion runner name to TestConnection component', async () => { + const ingestionRunnerName = 'IngestionRunner1'; + mockServiceUtil.getServiceExtraInfo.mockReturnValue({ + name: ingestionRunnerName, + }); + (useRequiredParams as jest.Mock).mockImplementation(() => ({ + serviceCategory: ServiceCategory.DATABASE_SERVICES, + tab: EntityTabs.CONNECTION, + })); + (getServiceByFQN as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ + ...mockServiceDetails, + ingestionRunnerName, + }) + ); + + await renderComponent(); + + await waitFor(() => { + expect(screen.getByTestId('test-connection')).toBeInTheDocument(); + expect( + screen.getByTestId('test-connection-extra-info') + ).toHaveTextContent(ingestionRunnerName); + }); + }); + }); + describe('Utility Function Integration', () => { it('should use correct service utilities', async () => { (getPipelineServiceHostIp as jest.Mock).mockResolvedValue({}); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.tsx index c8245a339d1..d1748bd8bac 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/ServiceDetailsPage/ServiceDetailsPage.tsx @@ -1467,7 +1467,7 @@ const ServiceDetailsPage: FunctionComponent = () => { {allowTestConn && ( connectionDetails} hostIp={hostIp} isTestingDisabled={isTestingDisabled}