From fed0cfc53a594a5941684fd8ab78a6687bba8212 Mon Sep 17 00:00:00 2001 From: mbovtryuk Date: Tue, 11 May 2021 16:53:06 +0300 Subject: [PATCH 1/6] [issues#121] Topic Details: Display consumers --- .../Details/ConsumerGroups/ConsumerGroups.tsx | 55 +++++++++++++++++++ .../ConsumerGroupsContainer.tsx | 36 ++++++++++++ .../Topics/Topic/Details/Details.tsx | 15 +++++ kafka-ui-react-app/src/lib/paths.ts | 4 ++ .../src/redux/actions/actions.ts | 6 ++ .../src/redux/actions/thunks/topics.ts | 35 ++++++++++++ .../src/redux/interfaces/topic.ts | 2 + .../reducers/topics/__test__/reducer.spec.ts | 2 + .../src/redux/reducers/topics/reducer.ts | 2 + .../src/redux/reducers/topics/selectors.ts | 2 + 10 files changed, 159 insertions(+) create mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx create mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx new file mode 100644 index 00000000000..f976d731b64 --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Topic, TopicDetails, ConsumerGroup } from 'generated-sources'; +import { ClusterName, TopicName } from 'redux/interfaces'; +import ListItem from 'components/ConsumerGroups/List/ListItem'; + +interface Props extends Topic, TopicDetails { + clusterName: ClusterName; + topicName: TopicName; + consumerGroups: Array; + fetchTopicConsumerGroups( + clusterName: ClusterName, + topicName: TopicName + ): void; +} + +const TopicConsumerGroups: React.FC = ({ + consumerGroups, + fetchTopicConsumerGroups, + clusterName, + topicName, +}) => { + React.useEffect(() => { + fetchTopicConsumerGroups(clusterName, topicName); + }, []); + + return ( +
+ {consumerGroups.length > 0 ? ( +
+ + + + + + + + + + {consumerGroups.map((consumerGroup) => ( + + ))} + +
Consumer group IDNum of consumersNum of topics
+
+ ) : ( + 'No active consumer groups' + )} +
+ ); +}; + +export default TopicConsumerGroups; diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx new file mode 100644 index 00000000000..b10fe26998e --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx @@ -0,0 +1,36 @@ +import { connect } from 'react-redux'; +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/ConsumerGroups'; +import { getTopicConsumerGroups } from 'redux/reducers/topics/selectors'; + +interface RouteProps { + clusterName: ClusterName; + topicName: TopicName; +} + +type OwnProps = RouteComponentProps; + +const mapStateToProps = ( + state: RootState, + { + match: { + params: { topicName, clusterName }, + }, + }: OwnProps +) => { + return { + consumerGroups: { ...getTopicConsumerGroups(state) }, + topicName, + clusterName, + }; +}; + +const mapDispatchToProps = { + fetchTopicConsumerGroups, +}; + +export default withRouter( + connect(mapStateToProps, mapDispatchToProps)(TopicConsumerGroups) +); diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx index 379ffc53a69..7ca49a6e1fc 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx @@ -7,12 +7,14 @@ import { clusterTopicPath, clusterTopicMessagesPath, clusterTopicsPath, + clusterTopicConsumerGroupsPath, clusterTopicEditPath, } from 'lib/paths'; import ClusterContext from 'components/contexts/ClusterContext'; import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal'; import OverviewContainer from './Overview/OverviewContainer'; +import TopicConsumerGroupsContainer from './ConsumerGroups/ConsumerGroupsContainer'; import MessagesContainer from './Messages/MessagesContainer'; import SettingsContainer from './Settings/SettingsContainer'; @@ -64,6 +66,14 @@ const Details: React.FC = ({ > Messages + + Consumers + = ({ path="/ui/clusters/:clusterName/topics/:topicName" component={OverviewContainer} /> + ); diff --git a/kafka-ui-react-app/src/lib/paths.ts b/kafka-ui-react-app/src/lib/paths.ts index 550bf0101ad..02bcc6069e0 100644 --- a/kafka-ui-react-app/src/lib/paths.ts +++ b/kafka-ui-react-app/src/lib/paths.ts @@ -50,6 +50,10 @@ export const clusterTopicEditPath = ( clusterName: ClusterName, topicName: TopicName ) => `${clusterTopicsPath(clusterName)}/${topicName}/edit`; +export const clusterTopicConsumerGroupsPath = ( + clusterName: ClusterName, + topicName: TopicName +) => `${clusterTopicsPath(clusterName)}/${topicName}/consumergroups`; // Kafka Connect export const clusterConnectorsPath = (clusterName: ClusterName) => diff --git a/kafka-ui-react-app/src/redux/actions/actions.ts b/kafka-ui-react-app/src/redux/actions/actions.ts index 9b9649e2199..30f4f557271 100644 --- a/kafka-ui-react-app/src/redux/actions/actions.ts +++ b/kafka-ui-react-app/src/redux/actions/actions.ts @@ -180,3 +180,9 @@ export const deleteConnectorAction = createAsyncAction( 'DELETE_CONNECTOR__SUCCESS', 'DELETE_CONNECTOR__FAILURE' )(); + +export const fetchTopicConsumerGroupsAction = createAsyncAction( + 'GET_TOPIC_CONSUMER_GROUPS__REQUEST', + 'GET_TOPIC_CONSUMER_GROUPS__SUCCESS', + 'GET_TOPIC_CONSUMER_GROUPS__FAILURE' +)(); diff --git a/kafka-ui-react-app/src/redux/actions/thunks/topics.ts b/kafka-ui-react-app/src/redux/actions/thunks/topics.ts index 7ce6bbe6a9c..1083f0c928b 100644 --- a/kafka-ui-react-app/src/redux/actions/thunks/topics.ts +++ b/kafka-ui-react-app/src/redux/actions/thunks/topics.ts @@ -7,6 +7,7 @@ import { TopicCreation, TopicUpdate, TopicConfig, + ConsumerGroupsApi, } from 'generated-sources'; import { PromiseThunkResult, @@ -25,6 +26,9 @@ import { getResponse } from 'lib/errorHandling'; const apiClientConf = new Configuration(BASE_PARAMS); export const topicsApiClient = new TopicsApi(apiClientConf); export const messagesApiClient = new MessagesApi(apiClientConf); +export const topicConsumerGroupsApiClient = new ConsumerGroupsApi( + apiClientConf +); export interface FetchTopicsListParams { clusterName: ClusterName; @@ -310,3 +314,34 @@ export const deleteTopic = ( dispatch(actions.deleteTopicAction.failure()); } }; + +export const fetchTopicConsumerGroups = ( + clusterName: ClusterName, + topicName: TopicName +): PromiseThunkResult => async (dispatch, getState) => { + dispatch(actions.fetchTopicConsumerGroupsAction.request()); + try { + const topicDetails = await topicConsumerGroupsApiClient.getTopicConsumerGroups( + { + clusterName, + topicName, + } + ); + const state = getState().topics; + const newState = { + ...state, + byName: { + ...state.byName, + [topicName]: { + ...state.byName[topicName], + consumerGroups: { + ...topicDetails, + }, + }, + }, + }; + dispatch(actions.fetchTopicConsumerGroupsAction.success(newState)); + } catch (e) { + dispatch(actions.fetchTopicConsumerGroupsAction.failure()); + } +}; diff --git a/kafka-ui-react-app/src/redux/interfaces/topic.ts b/kafka-ui-react-app/src/redux/interfaces/topic.ts index e2835c4b5d3..e9def15da59 100644 --- a/kafka-ui-react-app/src/redux/interfaces/topic.ts +++ b/kafka-ui-react-app/src/redux/interfaces/topic.ts @@ -5,6 +5,7 @@ import { TopicConfig, TopicCreation, GetTopicMessagesRequest, + ConsumerGroup, } from 'generated-sources'; export type TopicName = Topic['name']; @@ -45,6 +46,7 @@ export interface TopicsState { allNames: TopicName[]; totalPages: number; messages: TopicMessage[]; + consumerGroups: ConsumerGroup[]; } export type TopicFormFormattedParams = TopicCreation['configs']; diff --git a/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts b/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts index d4841b137b2..22ba1a77f48 100644 --- a/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts +++ b/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts @@ -13,6 +13,7 @@ const state = { allNames: [topic.name], messages: [], totalPages: 1, + consumerGroups: [], }; describe('topics reducer', () => { @@ -22,6 +23,7 @@ describe('topics reducer', () => { allNames: [], messages: [], totalPages: 1, + consumerGroups: [], }); }); diff --git a/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts b/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts index 0e3f7366e3c..0f94082a69e 100644 --- a/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts +++ b/kafka-ui-react-app/src/redux/reducers/topics/reducer.ts @@ -8,6 +8,7 @@ export const initialState: TopicsState = { allNames: [], totalPages: 1, messages: [], + consumerGroups: [], }; const transformTopicMessages = ( @@ -41,6 +42,7 @@ const reducer = (state = initialState, action: Action): TopicsState => { case getType(actions.fetchTopicDetailsAction.success): case getType(actions.fetchTopicConfigAction.success): case getType(actions.createTopicAction.success): + case getType(actions.fetchTopicConsumerGroupsAction.success): case getType(actions.updateTopicAction.success): return action.payload; case getType(actions.fetchTopicMessagesAction.success): diff --git a/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts b/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts index 1da0cf9110a..4f7c223c68d 100644 --- a/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts +++ b/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts @@ -16,6 +16,8 @@ export const getTopicMessages = (state: RootState) => topicsState(state).messages; export const getTopicListTotalPages = (state: RootState) => topicsState(state).totalPages; +export const getTopicConsumerGroups = (state: RootState) => + topicsState(state).consumerGroups; const getTopicListFetchingStatus = createFetchingSelector('GET_TOPICS'); const getTopicDetailsFetchingStatus = createFetchingSelector( From eece90795411835a964fb99884c236ebd76a7f3a Mon Sep 17 00:00:00 2001 From: mbovtryuk Date: Wed, 12 May 2021 12:37:45 +0300 Subject: [PATCH 2/6] [issues#121] Topic Details: Display consumers --- .../Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx | 2 +- kafka-ui-react-app/src/redux/actions/thunks/topics.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx index b10fe26998e..e9c456c090b 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx @@ -21,7 +21,7 @@ const mapStateToProps = ( }: OwnProps ) => { return { - consumerGroups: { ...getTopicConsumerGroups(state) }, + consumerGroups: getTopicConsumerGroups(state), topicName, clusterName, }; diff --git a/kafka-ui-react-app/src/redux/actions/thunks/topics.ts b/kafka-ui-react-app/src/redux/actions/thunks/topics.ts index ed1a99ac3ae..ab2f16b708c 100644 --- a/kafka-ui-react-app/src/redux/actions/thunks/topics.ts +++ b/kafka-ui-react-app/src/redux/actions/thunks/topics.ts @@ -322,7 +322,7 @@ export const fetchTopicConsumerGroups = async (dispatch, getState) => { dispatch(actions.fetchTopicConsumerGroupsAction.request()); try { - const topicDetails = + const consumerGroups = await topicConsumerGroupsApiClient.getTopicConsumerGroups({ clusterName, topicName, @@ -335,7 +335,7 @@ export const fetchTopicConsumerGroups = [topicName]: { ...state.byName[topicName], consumerGroups: { - ...topicDetails, + ...consumerGroups, }, }, }, From d027ad4eaf23b86343617c7fa7d2790629a78a39 Mon Sep 17 00:00:00 2001 From: mbovtryuk Date: Wed, 12 May 2021 16:50:03 +0300 Subject: [PATCH 3/6] [issues#121] Topic Details: Display consumers --- .../Details/ConsumerGroups/ConsumerGroups.tsx | 36 ++++++++-------- .../__test__/ConsumerGroups.spec.tsx | 43 +++++++++++++++++++ 2 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/ConsumerGroups.spec.tsx diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx index f976d731b64..ec65254113e 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups.tsx @@ -26,25 +26,23 @@ const TopicConsumerGroups: React.FC = ({ return (
{consumerGroups.length > 0 ? ( -
- - - - - - - - - - {consumerGroups.map((consumerGroup) => ( - - ))} - -
Consumer group IDNum of consumersNum of topics
-
+ + + + + + + + + + {consumerGroups.map((consumerGroup) => ( + + ))} + +
Consumer group IDNum of consumersNum of topics
) : ( 'No active consumer groups' )} diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/ConsumerGroups.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/ConsumerGroups.spec.tsx new file mode 100644 index 00000000000..42ee3185887 --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/ConsumerGroups.spec.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import ConsumerGroups from 'components/Topics/Topic/Details/ConsumerGroups/ConsumerGroups'; + +describe('Details', () => { + const mockFn = jest.fn(); + const mockClusterName = 'local'; + const mockTopicName = 'local'; + const mockWithConsumerGroup = [ + { + clusterId: '1', + consumerGroupId: '1', + }, + ]; + + it("don't render ConsumerGroups in Topic", () => { + const component = shallow( + + ); + + expect(component.exists('.table')).toBeFalsy(); + }); + + it('render ConsumerGroups in Topic', () => { + const component = shallow( + + ); + + expect(component.exists('.table')).toBeTruthy(); + }); +}); From d592f15877f42a2f694732b370394ee2ea823b15 Mon Sep 17 00:00:00 2001 From: mbovtryuk Date: Thu, 13 May 2021 13:38:32 +0300 Subject: [PATCH 4/6] [issues#121] Topic Details: Display consumers --- .../redux/actions/__test__/actions.spec.ts | 25 ++++++++++++ .../src/redux/actions/__test__/fixtures.ts | 10 +++++ .../actions/__test__/thunks/topics.spec.ts | 39 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/kafka-ui-react-app/src/redux/actions/__test__/actions.spec.ts b/kafka-ui-react-app/src/redux/actions/__test__/actions.spec.ts index 4b23d249b30..6b947bf6d9e 100644 --- a/kafka-ui-react-app/src/redux/actions/__test__/actions.spec.ts +++ b/kafka-ui-react-app/src/redux/actions/__test__/actions.spec.ts @@ -5,6 +5,8 @@ import { import * as actions from 'redux/actions'; import { TopicColumnsToSort } from 'generated-sources'; +import { mockTopicsState } from './fixtures'; + describe('Actions', () => { describe('fetchClusterStatsAction', () => { it('creates a REQUEST action', () => { @@ -133,6 +135,29 @@ describe('Actions', () => { }); }); + describe('fetchTopicConsumerGroups', () => { + it('creates a REQUEST action', () => { + expect(actions.fetchTopicConsumerGroupsAction.request()).toEqual({ + type: 'GET_TOPIC_CONSUMER_GROUPS__REQUEST', + }); + }); + + it('creates a SUCCESS action', () => { + expect( + actions.fetchTopicConsumerGroupsAction.success(mockTopicsState) + ).toEqual({ + type: 'GET_TOPIC_CONSUMER_GROUPS__SUCCESS', + payload: mockTopicsState, + }); + }); + + it('creates a FAILURE action', () => { + expect(actions.fetchTopicConsumerGroupsAction.failure()).toEqual({ + type: 'GET_TOPIC_CONSUMER_GROUPS__FAILURE', + }); + }); + }); + describe('setTopicsSearchAction', () => { it('creartes SET_TOPICS_SEARCH', () => { expect(actions.setTopicsSearchAction('test')).toEqual({ diff --git a/kafka-ui-react-app/src/redux/actions/__test__/fixtures.ts b/kafka-ui-react-app/src/redux/actions/__test__/fixtures.ts index 927ac3510a3..d2617f2301f 100644 --- a/kafka-ui-react-app/src/redux/actions/__test__/fixtures.ts +++ b/kafka-ui-react-app/src/redux/actions/__test__/fixtures.ts @@ -34,3 +34,13 @@ export const schema: SchemaSubject = { id: 1, compatibilityLevel: CompatibilityLevelCompatibilityEnum.BACKWARD, }; + +export const mockTopicsState = { + byName: {}, + allNames: [], + totalPages: 1, + messages: [], + search: '', + orderBy: null, + consumerGroups: [], +}; diff --git a/kafka-ui-react-app/src/redux/actions/__test__/thunks/topics.spec.ts b/kafka-ui-react-app/src/redux/actions/__test__/thunks/topics.spec.ts index fc47c4b1ae4..4b81d22a61b 100644 --- a/kafka-ui-react-app/src/redux/actions/__test__/thunks/topics.spec.ts +++ b/kafka-ui-react-app/src/redux/actions/__test__/thunks/topics.spec.ts @@ -2,6 +2,7 @@ import fetchMock from 'fetch-mock-jest'; import * as actions from 'redux/actions/actions'; import * as thunks from 'redux/actions/thunks'; import mockStoreCreator from 'redux/store/configureStore/mockStoreCreator'; +import { mockTopicsState } from 'redux/actions/__test__/fixtures'; const store = mockStoreCreator; @@ -93,4 +94,42 @@ describe('Thunks', () => { } }); }); + + describe('fetchTopicConsumerGroups', () => { + it('GET_TOPIC_CONSUMER_GROUPS__FAILURE', async () => { + fetchMock.getOnce( + `api/clusters/${clusterName}/topics/${topicName}/consumergroups`, + 404 + ); + try { + await store.dispatch( + thunks.fetchTopicConsumerGroups(clusterName, topicName) + ); + } catch (error) { + expect(error.status).toEqual(404); + expect(store.getActions()).toEqual([ + actions.fetchTopicConsumerGroupsAction.request(), + actions.fetchTopicConsumerGroupsAction.failure(), + ]); + } + }); + + it('GET_TOPIC_CONSUMER_GROUPS__SUCCESS', async () => { + fetchMock.getOnce( + `api/clusters/${clusterName}/topics/${topicName}/consumergroups`, + 200 + ); + try { + await store.dispatch( + thunks.fetchTopicConsumerGroups(clusterName, topicName) + ); + } catch (error) { + expect(error.status).toEqual(200); + expect(store.getActions()).toEqual([ + actions.fetchTopicConsumerGroupsAction.request(), + actions.fetchTopicConsumerGroupsAction.success(mockTopicsState), + ]); + } + }); + }); }); From 0d83ae7a8f70b28346875ff00fc0f9b2d72a012b Mon Sep 17 00:00:00 2001 From: mbovtryuk Date: Thu, 13 May 2021 13:49:27 +0300 Subject: [PATCH 5/6] [issues#121] Topic Details: Display consumers --- .../ConsumerGroups/ConsumerGroupsContainer.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx index e9c456c090b..a97c4b6b783 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/ConsumerGroupsContainer.tsx @@ -19,13 +19,11 @@ const mapStateToProps = ( params: { topicName, clusterName }, }, }: OwnProps -) => { - return { - consumerGroups: getTopicConsumerGroups(state), - topicName, - clusterName, - }; -}; +) => ({ + consumerGroups: getTopicConsumerGroups(state), + topicName, + clusterName, +}); const mapDispatchToProps = { fetchTopicConsumerGroups, From d1823011cee25906210529c9e0e8511bb28ad686 Mon Sep 17 00:00:00 2001 From: mbovtryuk Date: Thu, 13 May 2021 14:18:16 +0300 Subject: [PATCH 6/6] [issues#121] Topic Details: Display consumers --- .../src/redux/reducers/topics/__test__/reducer.spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts b/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts index cc2dcc87b83..167a0216503 100644 --- a/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts +++ b/kafka-ui-react-app/src/redux/reducers/topics/__test__/reducer.spec.ts @@ -4,6 +4,7 @@ import { clearMessagesTopicAction, setTopicsSearchAction, setTopicsOrderByAction, + fetchTopicConsumerGroupsAction, } from 'redux/actions'; import reducer from 'redux/reducers/topics/reducer'; @@ -61,4 +62,12 @@ describe('topics reducer', () => { }); }); }); + + describe('topic consumer groups', () => { + it('GET_TOPIC_CONSUMER_GROUPS__SUCCESS', () => { + expect( + reducer(state, fetchTopicConsumerGroupsAction.success(state)) + ).toEqual(state); + }); + }); });