浏览代码

Adding Loader indicator to the TopicsConsumerGroups pages + migrating its test from Enzyme to react testing library (#1734)

Mgrdich 3 年之前
父节点
当前提交
ad628ed7ae

+ 8 - 1
kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups.tsx

@@ -8,11 +8,13 @@ import { Tag } from 'components/common/Tag/Tag.styled';
 import { TableKeyLink } from 'components/common/table/Table/TableKeyLink.styled';
 import { Link } from 'react-router-dom';
 import getTagColor from 'components/ConsumerGroups/Utils/TagColor';
+import PageLoader from 'components/common/PageLoader/PageLoader';
 
-interface Props extends Topic, TopicDetails {
+export interface Props extends Topic, TopicDetails {
   clusterName: ClusterName;
   topicName: TopicName;
   consumerGroups: ConsumerGroup[];
+  isFetched: boolean;
   fetchTopicConsumerGroups(
     clusterName: ClusterName,
     topicName: TopicName
@@ -24,11 +26,16 @@ const TopicConsumerGroups: React.FC<Props> = ({
   fetchTopicConsumerGroups,
   clusterName,
   topicName,
+  isFetched,
 }) => {
   React.useEffect(() => {
     fetchTopicConsumerGroups(clusterName, topicName);
   }, [clusterName, fetchTopicConsumerGroups, topicName]);
 
+  if (!isFetched) {
+    return <PageLoader />;
+  }
+
   return (
     <div>
       <Table isFullwidth>

+ 5 - 1
kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroupsContainer.ts

@@ -3,7 +3,10 @@ import { RootState, TopicName, ClusterName } from 'redux/interfaces';
 import { withRouter, RouteComponentProps } from 'react-router-dom';
 import { fetchTopicConsumerGroups } from 'redux/actions';
 import TopicConsumerGroups from 'components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups';
-import { getTopicConsumerGroups } from 'redux/reducers/topics/selectors';
+import {
+  getTopicConsumerGroups,
+  getTopicsConsumerGroupsFetched,
+} from 'redux/reducers/topics/selectors';
 
 interface RouteProps {
   clusterName: ClusterName;
@@ -23,6 +26,7 @@ const mapStateToProps = (
   consumerGroups: getTopicConsumerGroups(state, topicName),
   topicName,
   clusterName,
+  isFetched: getTopicsConsumerGroupsFetched(state),
 });
 
 const mapDispatchToProps = {

+ 36 - 23
kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/TopicConsumerGroups.spec.tsx

@@ -1,12 +1,14 @@
 import React from 'react';
-import { shallow } from 'enzyme';
-import ConsumerGroups from 'components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups';
+import { render } from 'lib/testHelpers';
+import { screen } from '@testing-library/react';
+import ConsumerGroups, {
+  Props,
+} from 'components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups';
 import { ConsumerGroupState } from 'generated-sources';
 
-describe('Details', () => {
-  const mockFn = jest.fn();
-  const mockClusterName = 'local';
-  const mockTopicName = 'local';
+describe('TopicConsumerGroups', () => {
+  const mockClusterName = 'localClusterName';
+  const mockTopicName = 'localTopicName';
   const mockWithConsumerGroup = [
     {
       groupId: 'amazon.msk.canary.group.broker-7',
@@ -30,29 +32,40 @@ describe('Details', () => {
     },
   ];
 
-  it("don't render ConsumerGroups in Topic", () => {
-    const component = shallow(
+  const setUpComponent = (props: Partial<Props> = {}) => {
+    const { name, topicName, consumerGroups, isFetched } = props;
+
+    return render(
       <ConsumerGroups
         clusterName={mockClusterName}
-        consumerGroups={[]}
-        name={mockTopicName}
-        fetchTopicConsumerGroups={mockFn}
-        topicName={mockTopicName}
+        consumerGroups={consumerGroups?.length ? consumerGroups : []}
+        name={name || mockTopicName}
+        fetchTopicConsumerGroups={jest.fn()}
+        topicName={topicName || mockTopicName}
+        isFetched={'isFetched' in props ? !!isFetched : false}
       />
     );
-    expect(component.find('td').text()).toEqual('No active consumer groups');
+  };
+
+  describe('Default Setup', () => {
+    beforeEach(() => {
+      setUpComponent();
+    });
+    it('should view the Page loader when it is fetching state', () => {
+      expect(screen.getByRole('progressbar')).toBeInTheDocument();
+    });
+  });
+
+  it("don't render ConsumerGroups in Topic", () => {
+    setUpComponent({ isFetched: true });
+    expect(screen.getByText(/No active consumer groups/i)).toBeInTheDocument();
   });
 
   it('render ConsumerGroups in Topic', () => {
-    const component = shallow(
-      <ConsumerGroups
-        clusterName={mockClusterName}
-        consumerGroups={mockWithConsumerGroup}
-        name={mockTopicName}
-        fetchTopicConsumerGroups={mockFn}
-        topicName={mockTopicName}
-      />
-    );
-    expect(component.exists('tbody')).toBeTruthy();
+    setUpComponent({
+      consumerGroups: mockWithConsumerGroup,
+      isFetched: true,
+    });
+    expect(screen.getAllByRole('rowgroup')).toHaveLength(2);
   });
 });

+ 9 - 0
kafka-ui-react-app/src/redux/reducers/topics/selectors.ts

@@ -33,6 +33,10 @@ const getReplicationFactorUpdateStatus = createLeagcyFetchingSelector(
 );
 const getTopicDeletingStatus = createLeagcyFetchingSelector('DELETE_TOPIC');
 
+const getTopicConsumerGroupsStatus = createLeagcyFetchingSelector(
+  'GET_TOPIC_CONSUMER_GROUPS'
+);
+
 export const getIsTopicDeleted = createSelector(
   getTopicDeletingStatus,
   (status) => status === 'fetched'
@@ -88,6 +92,11 @@ export const getTopicReplicationFactorUpdated = createSelector(
   (status) => status === 'fetched'
 );
 
+export const getTopicsConsumerGroupsFetched = createSelector(
+  getTopicConsumerGroupsStatus,
+  (status) => status === 'fetched'
+);
+
 export const getTopicList = createSelector(
   getAreTopicsFetched,
   getAllNames,