Переглянути джерело

Improve tests coverage (#1864)

* improve tests coverage of topic details component

* improve tests coverage on topic details overview component
Arsen Simonyan 3 роки тому
батько
коміт
b2a04a202e

+ 45 - 34
kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx

@@ -6,6 +6,8 @@ import Overview, {
 } from 'components/Topics/Topic/Details/Overview/Overview';
 import theme from 'theme/theme';
 import { CleanUpPolicy } from 'generated-sources';
+import ClusterContext from 'components/contexts/ClusterContext';
+import userEvent from '@testing-library/user-event';
 
 describe('Overview', () => {
   const mockClusterName = 'local';
@@ -26,45 +28,52 @@ describe('Overview', () => {
       offsetMin: 0,
     },
   ];
+  const defaultContextValues = {
+    isReadOnly: false,
+    hasKafkaConnectConfigured: true,
+    hasSchemaRegistryConfigured: true,
+    isTopicDeletionAllowed: true,
+  };
+  const defaultProps: OverviewProps = {
+    name: mockTopicName,
+    partitions: [],
+    internal: true,
+    clusterName: mockClusterName,
+    topicName: mockTopicName,
+    clearTopicMessages: mockClearTopicMessages,
+  };
 
   const setupComponent = (
-    props: OverviewProps,
+    props = defaultProps,
+    contextValues = defaultContextValues,
     underReplicatedPartitions?: number,
     inSyncReplicas?: number,
     replicas?: number
   ) =>
     render(
-      <Overview
-        underReplicatedPartitions={underReplicatedPartitions}
-        inSyncReplicas={inSyncReplicas}
-        replicas={replicas}
-        {...props}
-      />
+      <ClusterContext.Provider value={contextValues}>
+        <Overview
+          underReplicatedPartitions={underReplicatedPartitions}
+          inSyncReplicas={inSyncReplicas}
+          replicas={replicas}
+          {...props}
+        />
+      </ClusterContext.Provider>
     );
 
   describe('when it has internal flag', () => {
     it('does not render the Action button a Topic', () => {
       setupComponent({
-        name: mockTopicName,
+        ...defaultProps,
         partitions: mockPartitions,
         internal: false,
-        clusterName: mockClusterName,
-        topicName: mockTopicName,
         cleanUpPolicy: CleanUpPolicy.DELETE,
-        clearTopicMessages: mockClearTopicMessages,
       });
-      expect(screen.getByRole('menu')).toBeInTheDocument();
+      expect(screen.getAllByRole('menu')[0]).toBeInTheDocument();
     });
 
     it('does not render Partitions', () => {
-      setupComponent({
-        name: mockTopicName,
-        partitions: [],
-        internal: true,
-        clusterName: mockClusterName,
-        topicName: mockTopicName,
-        clearTopicMessages: mockClearTopicMessages,
-      });
+      setupComponent();
 
       expect(screen.getByText('No Partitions found')).toBeInTheDocument();
     });
@@ -72,26 +81,14 @@ describe('Overview', () => {
 
   describe('should render circular alert', () => {
     it('should be in document', () => {
-      setupComponent({
-        name: mockTopicName,
-        partitions: [],
-        internal: true,
-        clusterName: mockClusterName,
-        topicName: mockTopicName,
-        clearTopicMessages: mockClearTopicMessages,
-      });
+      setupComponent();
       const circles = screen.getAllByRole('circle');
       expect(circles.length).toEqual(2);
     });
 
     it('should be the appropriate color', () => {
       setupComponent({
-        name: mockTopicName,
-        partitions: [],
-        internal: true,
-        clusterName: mockClusterName,
-        topicName: mockTopicName,
-        clearTopicMessages: mockClearTopicMessages,
+        ...defaultProps,
         underReplicatedPartitions: 0,
         inSyncReplicas: 1,
         replicas: 2,
@@ -105,4 +102,18 @@ describe('Overview', () => {
       );
     });
   });
+
+  describe('when Clear Messages is clicked', () => {
+    setupComponent({
+      ...defaultProps,
+      partitions: mockPartitions,
+      internal: false,
+      cleanUpPolicy: CleanUpPolicy.DELETE,
+    });
+
+    const clearMessagesButton = screen.getByText('Clear Messages');
+    userEvent.click(clearMessagesButton);
+
+    expect(mockClearTopicMessages).toHaveBeenCalledTimes(1);
+  });
 });

+ 113 - 25
kafka-ui-react-app/src/components/Topics/Topic/Details/__test__/Details.spec.tsx

@@ -5,7 +5,13 @@ import ClusterContext from 'components/contexts/ClusterContext';
 import Details from 'components/Topics/Topic/Details/Details';
 import { internalTopicPayload } from 'redux/reducers/topics/__test__/fixtures';
 import { render } from 'lib/testHelpers';
-import { clusterTopicPath } from 'lib/paths';
+import {
+  clusterTopicEditPath,
+  clusterTopicPath,
+  clusterTopicsPath,
+} from 'lib/paths';
+import { Router } from 'react-router-dom';
+import { createMemoryHistory } from 'history';
 
 describe('Details', () => {
   const mockDelete = jest.fn();
@@ -13,8 +19,20 @@ describe('Details', () => {
   const mockClearTopicMessages = jest.fn();
   const mockInternalTopicPayload = internalTopicPayload.internal;
   const mockRecreateTopic = jest.fn();
+  const defaultPathname = clusterTopicPath(
+    mockClusterName,
+    internalTopicPayload.name
+  );
+  const mockHistory = createMemoryHistory({
+    initialEntries: [defaultPathname],
+  });
+  jest.spyOn(mockHistory, 'push');
 
-  const setupComponent = (pathname: string) =>
+  const setupComponent = (
+    pathname = defaultPathname,
+    history = mockHistory,
+    props = {}
+  ) =>
     render(
       <ClusterContext.Provider
         value={{
@@ -24,17 +42,20 @@ describe('Details', () => {
           isTopicDeletionAllowed: true,
         }}
       >
-        <Details
-          clusterName={mockClusterName}
-          topicName={internalTopicPayload.name}
-          name={internalTopicPayload.name}
-          isInternal={false}
-          deleteTopic={mockDelete}
-          recreateTopic={mockRecreateTopic}
-          clearTopicMessages={mockClearTopicMessages}
-          isDeleted={false}
-          isDeletePolicy
-        />
+        <Router history={history}>
+          <Details
+            clusterName={mockClusterName}
+            topicName={internalTopicPayload.name}
+            name={internalTopicPayload.name}
+            isInternal={false}
+            deleteTopic={mockDelete}
+            recreateTopic={mockRecreateTopic}
+            clearTopicMessages={mockClearTopicMessages}
+            isDeleted={false}
+            isDeletePolicy
+            {...props}
+          />
+        </Router>
       </ClusterContext.Provider>,
       { pathname }
     );
@@ -68,10 +89,83 @@ describe('Details', () => {
     });
   });
 
+  describe('when remove topic modal is open', () => {
+    beforeEach(() => {
+      setupComponent();
+
+      const openModalButton = screen.getAllByText('Remove topic')[0];
+      userEvent.click(openModalButton);
+    });
+
+    it('calls deleteTopic on confirm', () => {
+      const submitButton = screen.getAllByText('Submit')[0];
+      userEvent.click(submitButton);
+
+      expect(mockDelete).toHaveBeenCalledWith(
+        mockClusterName,
+        internalTopicPayload.name
+      );
+    });
+
+    it('closes the modal when cancel button is clicked', () => {
+      const cancelButton = screen.getAllByText('Cancel')[0];
+      userEvent.click(cancelButton);
+
+      expect(cancelButton).not.toBeInTheDocument();
+    });
+  });
+
+  describe('when clear messages modal is open', () => {
+    beforeEach(() => {
+      setupComponent();
+
+      const confirmButton = screen.getAllByText('Clear messages')[0];
+      userEvent.click(confirmButton);
+    });
+
+    it('it calls clearTopicMessages on confirm', () => {
+      const submitButton = screen.getAllByText('Submit')[0];
+      userEvent.click(submitButton);
+
+      expect(mockClearTopicMessages).toHaveBeenCalledWith(
+        mockClusterName,
+        internalTopicPayload.name
+      );
+    });
+
+    it('closes the modal when cancel button is clicked', () => {
+      const cancelButton = screen.getAllByText('Cancel')[0];
+      userEvent.click(cancelButton);
+
+      expect(cancelButton).not.toBeInTheDocument();
+    });
+  });
+
+  describe('when edit settings is clicked', () => {
+    it('redirects to the edit page', () => {
+      setupComponent();
+
+      const button = screen.getAllByText('Edit settings')[0];
+      userEvent.click(button);
+
+      const redirectRoute = clusterTopicEditPath(
+        mockClusterName,
+        internalTopicPayload.name
+      );
+
+      expect(mockHistory.push).toHaveBeenCalledWith(redirectRoute);
+    });
+  });
+
+  it('redirects to the correct route if topic is deleted', () => {
+    setupComponent(defaultPathname, mockHistory, { isDeleted: true });
+    const redirectRoute = clusterTopicsPath(mockClusterName);
+
+    expect(mockHistory.push).toHaveBeenCalledWith(redirectRoute);
+  });
+
   it('shows a confirmation popup on deleting topic messages', () => {
-    setupComponent(
-      clusterTopicPath(mockClusterName, internalTopicPayload.name)
-    );
+    setupComponent();
     const { getByText } = screen;
     const clearMessagesButton = getByText(/Clear messages/i);
     userEvent.click(clearMessagesButton);
@@ -82,9 +176,7 @@ describe('Details', () => {
   });
 
   it('shows a confirmation popup on recreating topic', () => {
-    setupComponent(
-      clusterTopicPath(mockClusterName, internalTopicPayload.name)
-    );
+    setupComponent();
     const recreateTopicButton = screen.getByText(/Recreate topic/i);
     userEvent.click(recreateTopicButton);
 
@@ -94,9 +186,7 @@ describe('Details', () => {
   });
 
   it('calling recreation function after click on Submit button', () => {
-    setupComponent(
-      clusterTopicPath(mockClusterName, internalTopicPayload.name)
-    );
+    setupComponent();
     const recreateTopicButton = screen.getByText(/Recreate topic/i);
     userEvent.click(recreateTopicButton);
     const confirmBtn = screen.getByRole('button', { name: /submit/i });
@@ -105,9 +195,7 @@ describe('Details', () => {
   });
 
   it('close popup confirmation window after click on Cancel button', () => {
-    setupComponent(
-      clusterTopicPath(mockClusterName, internalTopicPayload.name)
-    );
+    setupComponent();
     const recreateTopicButton = screen.getByText(/Recreate topic/i);
     userEvent.click(recreateTopicButton);
     const cancelBtn = screen.getByRole('button', { name: /cancel/i });