[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:
Zorii4 2022-02-03 14:06:13 +03:00 committed by GitHub
parent dd0f7038e3
commit 8a7399b093
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 200 additions and 7 deletions

View file

@ -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));
}

View file

@ -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 },
]);
});
});
});

View file

@ -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>

View file

@ -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;
`;

View file

@ -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('');
});

View file

@ -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);
});