Added test for consumer group offset hooks
This commit is contained in:
@@ -17,26 +17,17 @@
|
||||
import React from 'react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { ConsumerGroupOffsets } from './ConsumerGroupOffsets';
|
||||
import * as data from './__fixtures__/consumer-group-offsets.json';
|
||||
import { ConsumerGroupOffsetsResponse } from '../../api/types';
|
||||
|
||||
const consumerGroupOffsets = data as ConsumerGroupOffsetsResponse;
|
||||
|
||||
describe('ConsumerGroupOffsets', () => {
|
||||
it('should render consumer group table', async () => {
|
||||
const rendered = await renderInTestApp(
|
||||
<ConsumerGroupOffsets
|
||||
consumerGroup="consumer"
|
||||
topics={[
|
||||
{
|
||||
topic: 'topic1',
|
||||
partitionId: 1,
|
||||
topicOffset: '100',
|
||||
groupOffset: '50',
|
||||
},
|
||||
{
|
||||
topic: 'topic2',
|
||||
partitionId: 1,
|
||||
topicOffset: '2340',
|
||||
groupOffset: '1234',
|
||||
},
|
||||
]}
|
||||
consumerGroup={consumerGroupOffsets.consumerId}
|
||||
topics={consumerGroupOffsets.offsets}
|
||||
loading={false}
|
||||
retry={() => {}}
|
||||
/>,
|
||||
|
||||
@@ -18,8 +18,7 @@ import { Table, TableColumn } from '@backstage/core';
|
||||
import { Box, Typography } from '@material-ui/core';
|
||||
import RetryIcon from '@material-ui/icons/Replay';
|
||||
import React from 'react';
|
||||
import { useConsumerGroupFromEntity } from './useConsumerGroupsFromEntity';
|
||||
import { useConsumerGroupOffsets } from './useConsumerGroupOffsets';
|
||||
import { useConsumerGroupsOffsetsForEntity } from './useConsumerGroupsOffsetsForEntity';
|
||||
|
||||
export type TopicPartitionInfo = {
|
||||
topic: string;
|
||||
@@ -98,14 +97,7 @@ export const ConsumerGroupOffsets = ({
|
||||
};
|
||||
|
||||
export const KafkaTopicsForConsumer = () => {
|
||||
const consumerGroup = useConsumerGroupFromEntity();
|
||||
const [tableProps, { retry }] = useConsumerGroupOffsets(consumerGroup);
|
||||
const [tableProps, { retry }] = useConsumerGroupsOffsetsForEntity();
|
||||
|
||||
return (
|
||||
<ConsumerGroupOffsets
|
||||
{...tableProps}
|
||||
consumerGroup={consumerGroup}
|
||||
retry={retry}
|
||||
/>
|
||||
);
|
||||
return <ConsumerGroupOffsets {...tableProps} retry={retry} />;
|
||||
};
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"consumerId": "consumer",
|
||||
"offsets": [
|
||||
{
|
||||
"topic": "topic1",
|
||||
"partitionId": 1,
|
||||
"topicOffset": "100",
|
||||
"groupOffset": "50"
|
||||
},
|
||||
{
|
||||
"topic": "topic2",
|
||||
"partitionId": 1,
|
||||
"topicOffset": "2340",
|
||||
"groupOffset": "1234"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useConsumerGroupsForEntity } from './useConsumerGroupsForEntity';
|
||||
import { EntityContext } from '@backstage/plugin-catalog';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
|
||||
describe('useConsumerGroupOffsets', () => {
|
||||
const entity: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Component',
|
||||
metadata: {
|
||||
name: 'test',
|
||||
annotations: {
|
||||
'kafka.apache.org/consumer-groups': 'consumer',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
owner: 'guest',
|
||||
type: 'Website',
|
||||
lifecycle: 'development',
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper = ({ children }: PropsWithChildren<{}>) => {
|
||||
return (
|
||||
<EntityContext.Provider value={{ entity: entity, loading: false }}>
|
||||
{children}
|
||||
</EntityContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const subject = () => renderHook(useConsumerGroupsForEntity, { wrapper });
|
||||
|
||||
it('returns correct consumer group for annotation', async () => {
|
||||
const { result } = subject();
|
||||
expect(result.current).toBe('consumer');
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
import { useEntity } from '@backstage/plugin-catalog';
|
||||
import { KAFKA_CONSUMER_GROUP_ANNOTATION } from '../../constants';
|
||||
|
||||
export const useConsumerGroupFromEntity = () => {
|
||||
export const useConsumerGroupsForEntity = () => {
|
||||
const { entity } = useEntity();
|
||||
|
||||
return entity.metadata.annotations?.[KAFKA_CONSUMER_GROUP_ANNOTATION] ?? '';
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { EntityContext } from '@backstage/plugin-catalog';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import * as data from './__fixtures__/consumer-group-offsets.json';
|
||||
import {
|
||||
ConsumerGroupOffsetsResponse,
|
||||
KafkaApi,
|
||||
kafkaApiRef,
|
||||
} from '../../api/types';
|
||||
import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core';
|
||||
import { useConsumerGroupsOffsetsForEntity } from './useConsumerGroupsOffsetsForEntity';
|
||||
import { when } from 'jest-when';
|
||||
|
||||
const consumerGroupOffsets = data as ConsumerGroupOffsetsResponse;
|
||||
|
||||
const mockErrorApi: jest.Mocked<typeof errorApiRef.T> = {
|
||||
post: jest.fn(),
|
||||
error$: jest.fn(),
|
||||
};
|
||||
|
||||
const mockKafkaApi: jest.Mocked<KafkaApi> = {
|
||||
getConsumerGroupOffsets: jest.fn(),
|
||||
};
|
||||
|
||||
describe('useConsumerGroupOffsets', () => {
|
||||
const entity: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Component',
|
||||
metadata: {
|
||||
name: 'test',
|
||||
annotations: {
|
||||
'kafka.apache.org/consumer-groups': consumerGroupOffsets.consumerId,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
owner: 'guest',
|
||||
type: 'Website',
|
||||
lifecycle: 'development',
|
||||
},
|
||||
};
|
||||
|
||||
const wrapper = ({ children }: PropsWithChildren<{}>) => {
|
||||
return (
|
||||
<ApiProvider
|
||||
apis={ApiRegistry.with(errorApiRef, mockErrorApi).with(
|
||||
kafkaApiRef,
|
||||
mockKafkaApi,
|
||||
)}
|
||||
>
|
||||
<EntityContext.Provider value={{ entity: entity, loading: false }}>
|
||||
{children}
|
||||
</EntityContext.Provider>
|
||||
</ApiProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const subject = () =>
|
||||
renderHook(useConsumerGroupsOffsetsForEntity, { wrapper });
|
||||
|
||||
it('returns correct consumer group for annotation', async () => {
|
||||
when(mockKafkaApi.getConsumerGroupOffsets)
|
||||
.calledWith(consumerGroupOffsets.consumerId)
|
||||
.mockResolvedValue(consumerGroupOffsets);
|
||||
|
||||
const { result, waitForNextUpdate } = subject();
|
||||
await waitForNextUpdate();
|
||||
const [tableProps] = result.current;
|
||||
|
||||
expect(tableProps.consumerGroup).toBe(consumerGroupOffsets.consumerId);
|
||||
expect(tableProps.topics).toBe(consumerGroupOffsets.offsets);
|
||||
});
|
||||
|
||||
it('posts an error to the error api', async () => {
|
||||
const error = new Error('error!');
|
||||
mockKafkaApi.getConsumerGroupOffsets.mockRejectedValueOnce(error);
|
||||
|
||||
const { waitForNextUpdate } = subject();
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(mockErrorApi.post).toHaveBeenCalledWith(error);
|
||||
});
|
||||
});
|
||||
+7
-4
@@ -17,28 +17,31 @@
|
||||
import { errorApiRef, useApi } from '@backstage/core';
|
||||
import { useAsyncRetry } from 'react-use';
|
||||
import { kafkaApiRef } from '../../api/types';
|
||||
import { useConsumerGroupsForEntity } from './useConsumerGroupsForEntity';
|
||||
|
||||
export function useConsumerGroupOffsets(groupId: string) {
|
||||
export const useConsumerGroupsOffsetsForEntity = () => {
|
||||
const consumerGroup = useConsumerGroupsForEntity();
|
||||
const api = useApi(kafkaApiRef);
|
||||
const errorApi = useApi(errorApiRef);
|
||||
|
||||
const { loading, value: topics, retry } = useAsyncRetry(async () => {
|
||||
try {
|
||||
const response = await api.getConsumerGroupOffsets(groupId);
|
||||
const response = await api.getConsumerGroupOffsets(consumerGroup);
|
||||
return response.offsets;
|
||||
} catch (e) {
|
||||
errorApi.post(e);
|
||||
throw e;
|
||||
}
|
||||
}, [api, errorApi, groupId]);
|
||||
}, [api, errorApi, consumerGroup]);
|
||||
|
||||
return [
|
||||
{
|
||||
loading,
|
||||
consumerGroup,
|
||||
topics,
|
||||
},
|
||||
{
|
||||
retry,
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user