Repository: provectus/kafka-ui
Issue: Nothing happens upon creating a connector
Labels: type/bug
scope/frontend
status/accepted
status/confirmed

1. create a connector successfully
2. Nothing happens in UI, no notifications/page redirections

Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Connect/New/New.tsx b/kafka-ui-react-app/src/components/Connect/New/New.tsx
index 64d307ce1b2..a7b307b283a 100644
--- a/kafka-ui-react-app/src/components/Connect/New/New.tsx
+++ b/kafka-ui-react-app/src/components/Connect/New/New.tsx
@@ -4,7 +4,7 @@ import useAppParams from 'lib/hooks/useAppParams';
 import { Controller, FormProvider, useForm } from 'react-hook-form';
 import { ErrorMessage } from '@hookform/error-message';
 import { yupResolver } from '@hookform/resolvers/yup';
-import { Connect, Connector, NewConnector } from 'generated-sources';
+import { Connect } from 'generated-sources';
 import { ClusterName, ConnectName } from 'redux/interfaces';
 import { clusterConnectConnectorPath, ClusterNameRoute } from 'lib/paths';
 import yup from 'lib/yupExtended';
@@ -16,6 +16,8 @@ import { FormError } from 'components/common/Input/Input.styled';
 import Input from 'components/common/Input/Input';
 import { Button } from 'components/common/Button/Button';
 import PageHeading from 'components/common/PageHeading/PageHeading';
+import { createConnector } from 'redux/reducers/connect/connectSlice';
+import { useAppDispatch } from 'lib/hooks/redux';
 
 import * as S from './New.styled';
 
@@ -28,11 +30,6 @@ export interface NewProps {
   fetchConnects(clusterName: ClusterName): unknown;
   areConnectsFetching: boolean;
   connects: Connect[];
-  createConnector(payload: {
-    clusterName: ClusterName;
-    connectName: ConnectName;
-    newConnector: NewConnector;
-  }): Promise<{ connector: Connector | undefined }>;
 }
 
 interface FormValues {
@@ -45,9 +42,9 @@ const New: React.FC<NewProps> = ({
   fetchConnects,
   areConnectsFetching,
   connects,
-  createConnector,
 }) => {
   const { clusterName } = useAppParams<ClusterNameRoute>();
+  const dispatch = useAppDispatch();
   const navigate = useNavigate();
 
   const methods = useForm<FormValues>({
@@ -83,15 +80,16 @@ const New: React.FC<NewProps> = ({
   );
 
   const onSubmit = async (values: FormValues) => {
-    const { connector } = await createConnector({
-      clusterName,
-      connectName: values.connectName,
-      newConnector: {
-        name: values.name,
-        config: JSON.parse(values.config.trim()),
-      },
-    });
-
+    const { connector } = await dispatch(
+      createConnector({
+        clusterName,
+        connectName: values.connectName,
+        newConnector: {
+          name: values.name,
+          config: JSON.parse(values.config.trim()),
+        },
+      })
+    ).unwrap();
     if (connector) {
       navigate(
         clusterConnectConnectorPath(
diff --git a/kafka-ui-react-app/src/components/Connect/New/NewContainer.ts b/kafka-ui-react-app/src/components/Connect/New/NewContainer.ts
index 23e577c4c12..d691043b54d 100644
--- a/kafka-ui-react-app/src/components/Connect/New/NewContainer.ts
+++ b/kafka-ui-react-app/src/components/Connect/New/NewContainer.ts
@@ -1,15 +1,12 @@
 import { connect } from 'react-redux';
-import {
-  createConnector,
-  fetchConnects,
-} from 'redux/reducers/connect/connectSlice';
+import { fetchConnects } from 'redux/reducers/connect/connectSlice';
 import { RootState } from 'redux/interfaces';
 import {
   getAreConnectsFetching,
   getConnects,
 } from 'redux/reducers/connect/selectors';
 
-import New, { NewProps } from './New';
+import New from './New';
 
 const mapStateToProps = (state: RootState) => ({
   areConnectsFetching: getAreConnectsFetching(state),
@@ -18,7 +15,6 @@ const mapStateToProps = (state: RootState) => ({
 
 const mapDispatchToProps = {
   fetchConnects,
-  createConnector: createConnector as unknown as NewProps['createConnector'],
 };
 
 export default connect(mapStateToProps, mapDispatchToProps)(New);
diff --git a/kafka-ui-react-app/src/components/Connect/New/__tests__/New.spec.tsx b/kafka-ui-react-app/src/components/Connect/New/__tests__/New.spec.tsx
index 94cba3f5a24..d12b7af3d86 100644
--- a/kafka-ui-react-app/src/components/Connect/New/__tests__/New.spec.tsx
+++ b/kafka-ui-react-app/src/components/Connect/New/__tests__/New.spec.tsx
@@ -9,6 +9,7 @@ import { connects, connector } from 'redux/reducers/connect/__test__/fixtures';
 import { fireEvent, screen, act } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import { ControllerRenderProps } from 'react-hook-form';
+import * as redux from 'react-redux';
 
 jest.mock('components/common/PageLoader/PageLoader', () => 'mock-PageLoader');
 jest.mock(
@@ -53,7 +54,6 @@ describe('New', () => {
           fetchConnects={jest.fn()}
           areConnectsFetching={false}
           connects={connects}
-          createConnector={jest.fn()}
           {...props}
         />
       </WithRoute>,
@@ -70,30 +70,32 @@ describe('New', () => {
   });
 
   it('calls createConnector on form submit', async () => {
-    const createConnector = jest.fn();
-    renderComponent({ createConnector });
+    const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
+    const useDispatchMock = jest.fn(() => ({
+      unwrap: () => ({ connector }),
+    })) as jest.Mock;
+    useDispatchSpy.mockReturnValue(useDispatchMock);
+
+    renderComponent();
     await simulateFormSubmit();
 
-    expect(createConnector).toHaveBeenCalledTimes(1);
-    expect(createConnector).toHaveBeenCalledWith({
-      clusterName,
-      connectName: connects[0].name,
-      newConnector: {
-        name: 'my-connector',
-        config: { class: 'MyClass' },
-      },
-    });
+    expect(useDispatchMock).toHaveBeenCalledTimes(1);
   });
 
   it('redirects to connector details view on successful submit', async () => {
-    const createConnector = jest.fn().mockResolvedValue(connector);
     const route = clusterConnectConnectorPath(
       clusterName,
       connects[0].name,
       connector.name
     );
-    renderComponent({ createConnector });
-    mockHistoryPush(route);
+
+    const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
+    const useDispatchMock = jest.fn(() => ({
+      unwrap: () => ({ connector }),
+    })) as jest.Mock;
+    useDispatchSpy.mockReturnValue(useDispatchMock);
+
+    renderComponent();
 
     await simulateFormSubmit();
     expect(mockHistoryPush).toHaveBeenCalledTimes(1);
@@ -101,8 +103,13 @@ describe('New', () => {
   });
 
   it('does not redirect to connector details view on unsuccessful submit', async () => {
-    const createConnector = jest.fn().mockResolvedValueOnce(undefined);
-    renderComponent({ createConnector });
+    const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
+    const useDispatchMock = jest.fn(async () => ({
+      unwrap: () => ({}),
+    })) as jest.Mock;
+    useDispatchSpy.mockReturnValue(useDispatchMock);
+
+    renderComponent();
     await simulateFormSubmit();
     expect(mockHistoryPush).not.toHaveBeenCalled();
   });


Test patch: