[Issue 1508] Improve test coverage (#1527)
* component Utils test covered * component Topic test covered * Improved test coverage * edited ConfigListItem component * Resolve feedback's comment * made correct description in test case title
This commit is contained in:
parent
dd0f7038e3
commit
8a7399b093
6 changed files with 200 additions and 7 deletions
|
@ -31,7 +31,6 @@ export const getTimestampFromSeekToParam = (params: URLSearchParams) => {
|
|||
.get('seekTo')
|
||||
?.split(',')
|
||||
.map((item) => Number(item.split('::')[1]));
|
||||
|
||||
return new Date(Math.max(...(offsets || []), 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import { Option } from 'react-multi-select-component/dist/lib/interfaces';
|
||||
import { filterOptions } from 'components/Topics/Topic/Details/Messages/Filters/utils';
|
||||
import {
|
||||
filterOptions,
|
||||
getOffsetFromSeekToParam,
|
||||
getTimestampFromSeekToParam,
|
||||
getSelectedPartitionsFromSeekToParam,
|
||||
} from 'components/Topics/Topic/Details/Messages/Filters/utils';
|
||||
import { SeekType, Partition } from 'generated-sources';
|
||||
|
||||
const options: Option[] = [
|
||||
{
|
||||
|
@ -20,6 +26,9 @@ const options: Option[] = [
|
|||
},
|
||||
];
|
||||
|
||||
let paramsString;
|
||||
let searchParams = new URLSearchParams(paramsString);
|
||||
|
||||
describe('utils', () => {
|
||||
describe('filterOptions', () => {
|
||||
it('returns options if no filter is defined', () => {
|
||||
|
@ -30,4 +39,82 @@ describe('utils', () => {
|
|||
expect(filterOptions(options, '11')).toEqual([options[2]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOffsetFromSeekToParam', () => {
|
||||
beforeEach(() => {
|
||||
paramsString = 'seekTo=0::123,1::123,2::0';
|
||||
searchParams = new URLSearchParams(paramsString);
|
||||
});
|
||||
|
||||
it('returns nothing when param "seekType" is equal BEGGINING', () => {
|
||||
searchParams.set('seekType', SeekType.BEGINNING);
|
||||
expect(getOffsetFromSeekToParam(searchParams)).toEqual('');
|
||||
});
|
||||
|
||||
it('returns nothing when param "seekType" is equal TIMESTAMP', () => {
|
||||
searchParams.set('seekType', SeekType.TIMESTAMP);
|
||||
expect(getOffsetFromSeekToParam(searchParams)).toEqual('');
|
||||
});
|
||||
|
||||
it('returns correct messages list when param "seekType" is equal OFFSET', () => {
|
||||
searchParams.set('seekType', SeekType.OFFSET);
|
||||
expect(getOffsetFromSeekToParam(searchParams)).toEqual('123');
|
||||
});
|
||||
|
||||
it('returns 0 when param "seekTo" is not defined and param "seekType" is equal OFFSET', () => {
|
||||
searchParams.set('seekType', SeekType.OFFSET);
|
||||
searchParams.delete('seekTo');
|
||||
expect(getOffsetFromSeekToParam(searchParams)).toEqual('0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTimestampFromSeekToParam', () => {
|
||||
beforeEach(() => {
|
||||
paramsString = `seekTo=0::1627333200000,1::1627333200000`;
|
||||
searchParams = new URLSearchParams(paramsString);
|
||||
});
|
||||
|
||||
it('returns null when param "seekType" is equal BEGGINING', () => {
|
||||
searchParams.set('seekType', SeekType.BEGINNING);
|
||||
expect(getTimestampFromSeekToParam(searchParams)).toEqual(null);
|
||||
});
|
||||
it('returns null when param "seekType" is equal OFFSET', () => {
|
||||
searchParams.set('seekType', SeekType.OFFSET);
|
||||
expect(getTimestampFromSeekToParam(searchParams)).toEqual(null);
|
||||
});
|
||||
it('returns correct messages list when param "seekType" is equal TIMESTAMP', () => {
|
||||
searchParams.set('seekType', SeekType.TIMESTAMP);
|
||||
expect(getTimestampFromSeekToParam(searchParams)).toEqual(
|
||||
new Date(1627333200000)
|
||||
);
|
||||
});
|
||||
it('returns default timestamp when param "seekTo" is empty and param "seekType" is equal TIMESTAMP', () => {
|
||||
searchParams.set('seekType', SeekType.TIMESTAMP);
|
||||
searchParams.delete('seekTo');
|
||||
expect(getTimestampFromSeekToParam(searchParams)).toEqual(new Date(0));
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSelectedPartitionsFromSeekToParam', () => {
|
||||
const part: Partition[] = [{ partition: 42, offsetMin: 0, offsetMax: 100 }];
|
||||
|
||||
it('returns parsed partition from params when partition list includes selected partition', () => {
|
||||
searchParams.set('seekTo', '42::0');
|
||||
expect(getSelectedPartitionsFromSeekToParam(searchParams, part)).toEqual([
|
||||
{ label: '42', value: 42 },
|
||||
]);
|
||||
});
|
||||
it('returns parsed partition from params when partition list NOT includes selected partition', () => {
|
||||
searchParams.set('seekTo', '24::0');
|
||||
expect(getSelectedPartitionsFromSeekToParam(searchParams, part)).toEqual(
|
||||
[]
|
||||
);
|
||||
});
|
||||
it('returns partitions when param "seekTo" is not defined', () => {
|
||||
searchParams.delete('seekTo');
|
||||
expect(getSelectedPartitionsFromSeekToParam(searchParams, part)).toEqual([
|
||||
{ label: '42', value: 42 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,19 +3,23 @@ import React from 'react';
|
|||
|
||||
import * as S from './Settings.styled';
|
||||
|
||||
interface ListItemProps {
|
||||
export interface ListItemProps {
|
||||
config: TopicConfig;
|
||||
}
|
||||
|
||||
const ConfigListItem: React.FC<ListItemProps> = ({
|
||||
config: { name, value, defaultValue },
|
||||
}) => {
|
||||
const hasCustomValue = value !== defaultValue;
|
||||
const hasCustomValue = !!defaultValue && value !== defaultValue;
|
||||
|
||||
return (
|
||||
<S.ConfigList>
|
||||
<S.ConfigItemCell $hasCustomValue>{name}</S.ConfigItemCell>
|
||||
<S.ConfigItemCell $hasCustomValue>{value}</S.ConfigItemCell>
|
||||
<S.ConfigItemCell $hasCustomValue={hasCustomValue}>
|
||||
{name}
|
||||
</S.ConfigItemCell>
|
||||
<S.ConfigItemCell $hasCustomValue={hasCustomValue}>
|
||||
{value}
|
||||
</S.ConfigItemCell>
|
||||
<td className="has-text-grey" title="Default Value">
|
||||
{hasCustomValue && defaultValue}
|
||||
</td>
|
||||
|
|
|
@ -6,5 +6,5 @@ export const ConfigList = styled.tr`
|
|||
}
|
||||
`;
|
||||
export const ConfigItemCell = styled.td<{ $hasCustomValue: boolean }>`
|
||||
font-weight: ${(props) => (props.$hasCustomValue ? 500 : 400)};
|
||||
font-weight: ${(props) => (props.$hasCustomValue ? 500 : 400)} !important;
|
||||
`;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import React from 'react';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen } from '@testing-library/react';
|
||||
import ConfigListItem, {
|
||||
ListItemProps,
|
||||
} from 'components/Topics/Topic/Details/Settings/ConfigListItem';
|
||||
|
||||
const setupComponent = (props: ListItemProps) => {
|
||||
render(
|
||||
<table>
|
||||
<tbody>
|
||||
<ConfigListItem {...props} />
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
|
||||
it('renders with CustomValue', () => {
|
||||
setupComponent({
|
||||
config: {
|
||||
name: 'someName',
|
||||
value: 'someValue',
|
||||
defaultValue: 'someDefaultValue',
|
||||
},
|
||||
});
|
||||
expect(screen.getByText('someName')).toBeInTheDocument();
|
||||
expect(screen.getByText('someName')).toHaveStyle('font-weight: 500');
|
||||
expect(screen.getByText('someValue')).toBeInTheDocument();
|
||||
expect(screen.getByText('someValue')).toHaveStyle('font-weight: 500');
|
||||
expect(screen.getByText('someDefaultValue')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders without CustomValue', () => {
|
||||
setupComponent({
|
||||
config: { name: 'someName', value: 'someValue', defaultValue: 'someValue' },
|
||||
});
|
||||
expect(screen.getByText('someName')).toBeInTheDocument();
|
||||
expect(screen.getByText('someName')).toHaveStyle('font-weight: 400');
|
||||
expect(screen.getByText('someValue')).toBeInTheDocument();
|
||||
expect(screen.getByText('someValue')).toHaveStyle('font-weight: 400');
|
||||
expect(screen.getByTitle('Default Value')).toHaveTextContent('');
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
import React from 'react';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { render } from 'lib/testHelpers';
|
||||
import { screen } from '@testing-library/react';
|
||||
import Topic from 'components/Topics/Topic/Topic';
|
||||
import {
|
||||
clusterTopicPath,
|
||||
clusterTopicEditPath,
|
||||
clusterTopicSendMessagePath,
|
||||
} from 'lib/paths';
|
||||
|
||||
jest.mock('components/Topics/Topic/Edit/EditContainer', () => () => (
|
||||
<div>Edit Container</div>
|
||||
));
|
||||
jest.mock('components/Topics/Topic/SendMessage/SendMessage', () => () => (
|
||||
<div>Send Message</div>
|
||||
));
|
||||
jest.mock('components/Topics/Topic/Details/DetailsContainer', () => () => (
|
||||
<div>Details Container</div>
|
||||
));
|
||||
jest.mock('components/common/PageLoader/PageLoader', () => () => (
|
||||
<div>Loading</div>
|
||||
));
|
||||
|
||||
const fetchTopicDetailsMock = jest.fn();
|
||||
|
||||
const renderComponent = (pathname: string, topicFetching: boolean) =>
|
||||
render(
|
||||
<Route path={clusterTopicPath(':clusterName', ':topicName')}>
|
||||
<Topic
|
||||
isTopicFetching={topicFetching}
|
||||
fetchTopicDetails={fetchTopicDetailsMock}
|
||||
/>
|
||||
</Route>,
|
||||
{ pathname }
|
||||
);
|
||||
|
||||
it('renders Edit page', () => {
|
||||
renderComponent(clusterTopicEditPath('local', 'myTopicName'), false);
|
||||
expect(screen.getByText('Edit Container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders Send Message page', () => {
|
||||
renderComponent(clusterTopicSendMessagePath('local', 'myTopicName'), false);
|
||||
expect(screen.getByText('Send Message')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders Details Container page', () => {
|
||||
renderComponent(clusterTopicPath('local', 'myTopicName'), false);
|
||||
expect(screen.getByText('Details Container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders Page loader', () => {
|
||||
renderComponent(clusterTopicPath('local', 'myTopicName'), true);
|
||||
expect(screen.getByText('Loading')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('fetches topicDetails', () => {
|
||||
renderComponent(clusterTopicPath('local', 'myTopicName'), false);
|
||||
expect(fetchTopicDetailsMock).toHaveBeenCalledTimes(1);
|
||||
});
|
Loading…
Add table
Reference in a new issue