Migrated TagsSelector test to react testing library

This commit is contained in:
Alejandro Celaya 2022-07-17 10:01:35 +02:00
parent fc4fdb4fc7
commit d627de8e83
3 changed files with 57 additions and 51 deletions

View file

@ -19,6 +19,8 @@ export const Tag: FC<TagProps> = ({ text, children, clearable, className = '', c
onClick={onClick} onClick={onClick}
> >
{children ?? text} {children ?? text}
{clearable && <span aria-label="Close" className="close tag__close-selected-tag" onClick={onClose}>&times;</span>} {clearable && (
<span aria-label={`Remove ${text}`} className="close tag__close-selected-tag" onClick={onClose}>&times;</span>
)}
</span> </span>
); );

View file

@ -2,15 +2,15 @@ import { screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { TagCard as createTagCard } from '../../src/tags/TagCard'; import { TagCard as createTagCard } from '../../src/tags/TagCard';
import { ColorGenerator } from '../../src/utils/services/ColorGenerator';
import { ReachableServer } from '../../src/servers/data'; import { ReachableServer } from '../../src/servers/data';
import { renderWithEvents } from '../__helpers__/setUpTest'; import { renderWithEvents } from '../__helpers__/setUpTest';
import { colorGeneratorMock } from '../utils/services/__mocks__/ColorGenerator.mock';
describe('<TagCard />', () => { describe('<TagCard />', () => {
const TagCard = createTagCard( const TagCard = createTagCard(
({ isOpen }) => <span>DeleteTagConfirmModal {isOpen ? '[Open]' : '[Closed]'}</span>, ({ isOpen }) => <span>DeleteTagConfirmModal {isOpen ? '[Open]' : '[Closed]'}</span>,
({ isOpen }) => <span>EditTagModal {isOpen ? '[Open]' : '[Closed]'}</span>, ({ isOpen }) => <span>EditTagModal {isOpen ? '[Open]' : '[Closed]'}</span>,
Mock.of<ColorGenerator>({ getColorForKey: () => '' }), colorGeneratorMock,
); );
const setUp = (tag = 'ssr') => renderWithEvents( const setUp = (tag = 'ssr') => renderWithEvents(
<MemoryRouter> <MemoryRouter>

View file

@ -1,77 +1,81 @@
import { shallow, ShallowWrapper } from 'enzyme'; import { screen } from '@testing-library/react';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { TagsSelector as createTagsSelector } from '../../../src/tags/helpers/TagsSelector'; import { TagsSelector as createTagsSelector } from '../../../src/tags/helpers/TagsSelector';
import { ColorGenerator } from '../../../src/utils/services/ColorGenerator';
import { TagsList } from '../../../src/tags/reducers/tagsList'; import { TagsList } from '../../../src/tags/reducers/tagsList';
import { Settings } from '../../../src/settings/reducers/settings'; import { Settings } from '../../../src/settings/reducers/settings';
import { renderWithEvents } from '../../__helpers__/setUpTest';
import { colorGeneratorMock } from '../../utils/services/__mocks__/ColorGenerator.mock';
describe('<TagsSelector />', () => { describe('<TagsSelector />', () => {
const onChange = jest.fn(); const onChange = jest.fn();
const TagsSelector = createTagsSelector(Mock.all<ColorGenerator>()); const TagsSelector = createTagsSelector(colorGeneratorMock);
const tags = ['foo', 'bar']; const tags = ['foo', 'bar'];
const tagsList = Mock.of<TagsList>({ tags: [...tags, 'baz'] }); const tagsList = Mock.of<TagsList>({ tags: [...tags, 'baz'] });
let wrapper: ShallowWrapper; const setUp = () => renderWithEvents(
<TagsSelector
selectedTags={tags}
tagsList={tagsList}
settings={Mock.all<Settings>()}
listTags={jest.fn()}
onChange={onChange}
/>,
);
beforeEach(jest.clearAllMocks); afterEach(jest.clearAllMocks);
beforeEach(() => {
wrapper = shallow(
<TagsSelector
selectedTags={tags}
tagsList={tagsList}
settings={Mock.all<Settings>()}
listTags={jest.fn()}
onChange={onChange}
/>,
);
});
afterEach(() => wrapper?.unmount()); it('has an input for tags', () => {
setUp();
it('has expected props', () => { expect(screen.getByPlaceholderText('Add tags to the URL')).toBeInTheDocument();
expect(wrapper.prop('placeholderText')).toEqual('Add tags to the URL');
expect(wrapper.prop('allowNew')).toEqual(true);
expect(wrapper.prop('addOnBlur')).toEqual(true);
expect(wrapper.prop('minQueryLength')).toEqual(1);
}); });
it('contains expected tags', () => { it('contains expected tags', () => {
expect(wrapper.prop('tags')).toEqual([ setUp();
{
id: 'foo', expect(screen.getByText('foo')).toBeInTheDocument();
name: 'foo', expect(screen.getByText('bar')).toBeInTheDocument();
},
{
id: 'bar',
name: 'bar',
},
]);
}); });
it('contains expected suggestions', () => { it('contains expected suggestions', async () => {
expect(wrapper.prop('suggestions')).toEqual([ const { container, user } = setUp();
{
id: 'baz', expect(container.querySelector('.react-tags__suggestions')).not.toBeInTheDocument();
name: 'baz', expect(screen.queryByText('baz')).not.toBeInTheDocument();
},
]); await user.type(screen.getByPlaceholderText('Add tags to the URL'), 'ba');
expect(container.querySelector('.react-tags__suggestions')).toBeInTheDocument();
expect(screen.getByText('baz')).toBeInTheDocument();
}); });
it.each([ it.each([
['The-New-Tag', [...tags, 'the-new-tag']], ['The-New-Tag', [...tags, 'the-new-tag']],
['comma,separated,tags', [...tags, 'comma', 'separated', 'tags']],
['foo', tags], ['foo', tags],
])('invokes onChange when new tags are added', (newTag, expectedTags) => { ])('invokes onChange when new tags are added', async (newTag, expectedTags) => {
wrapper.simulate('addition', { name: newTag }); const { user } = setUp();
expect(onChange).not.toHaveBeenCalled();
await user.type(screen.getByPlaceholderText('Add tags to the URL'), newTag);
await user.type(screen.getByPlaceholderText('Add tags to the URL'), '{Enter}');
expect(onChange).toHaveBeenCalledWith(expectedTags); expect(onChange).toHaveBeenCalledWith(expectedTags);
}); });
it.each([ it('splits tags when several comma-separated ones are pasted', async () => {
[0, 'bar'], const { user } = setUp();
[1, 'foo'],
])('invokes onChange when tags are deleted', (index, expected) => {
wrapper.simulate('delete', index);
expect(onChange).not.toHaveBeenCalled();
await user.click(screen.getByPlaceholderText('Add tags to the URL'));
await user.paste('comma,separated,tags');
await user.type(screen.getByPlaceholderText('Add tags to the URL'), '{Enter}');
expect(onChange).toHaveBeenCalledWith([...tags, 'comma', 'separated', 'tags']);
});
it.each([
['foo', 'bar'],
['bar', 'foo'],
])('invokes onChange when tags are deleted', async (removedLabel, expected) => {
const { user } = setUp();
await user.click(screen.getByLabelText(`Remove ${removedLabel}`));
expect(onChange).toHaveBeenCalledWith([expected]); expect(onChange).toHaveBeenCalledWith([expected]);
}); });
}); });