mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 17:40:23 +03:00
Migrated Tag test to react testing library
This commit is contained in:
parent
498668929f
commit
91ee4a32cd
2 changed files with 44 additions and 26 deletions
|
@ -19,6 +19,6 @@ export const Tag: FC<TagProps> = ({ text, children, clearable, className = '', c
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{children ?? text}
|
{children ?? text}
|
||||||
{clearable && <span className="close tag__close-selected-tag" onClick={onClose}>×</span>}
|
{clearable && <span aria-label="Close" className="close tag__close-selected-tag" onClick={onClose}>×</span>}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,29 +1,40 @@
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { ColorGenerator } from '../../../src/utils/services/ColorGenerator';
|
import { ColorGenerator } from '../../../src/utils/services/ColorGenerator';
|
||||||
import { MAIN_COLOR } from '../../../src/utils/theme';
|
import { MAIN_COLOR } from '../../../src/utils/theme';
|
||||||
import { Tag } from '../../../src/tags/helpers/Tag';
|
import { Tag } from '../../../src/tags/helpers/Tag';
|
||||||
|
|
||||||
|
const hexToRgb = (hex: string) => {
|
||||||
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
if (!result) {
|
||||||
|
throw new Error((`Could not convert color ${hex} to RGB`));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
describe('<Tag />', () => {
|
describe('<Tag />', () => {
|
||||||
const onClick = jest.fn();
|
const onClick = jest.fn();
|
||||||
const onClose = jest.fn();
|
const onClose = jest.fn();
|
||||||
const isColorLightForKey = jest.fn(() => false);
|
const isColorLightForKey = jest.fn(() => false);
|
||||||
const getColorForKey = jest.fn(() => MAIN_COLOR);
|
const getColorForKey = jest.fn(() => MAIN_COLOR);
|
||||||
const colorGenerator = Mock.of<ColorGenerator>({ getColorForKey, isColorLightForKey });
|
const colorGenerator = Mock.of<ColorGenerator>({ getColorForKey, isColorLightForKey });
|
||||||
let wrapper: ShallowWrapper;
|
const setUp = (text: string, clearable?: boolean, children?: ReactNode) => ({
|
||||||
const createWrapper = (text: string, clearable?: boolean, children?: ReactNode) => {
|
user: userEvent.setup(),
|
||||||
wrapper = shallow(
|
...render(
|
||||||
<Tag text={text} clearable={clearable} colorGenerator={colorGenerator} onClick={onClick} onClose={onClose}>
|
<Tag text={text} clearable={clearable} colorGenerator={colorGenerator} onClick={onClick} onClose={onClose}>
|
||||||
{children}
|
{children}
|
||||||
</Tag>,
|
</Tag>,
|
||||||
);
|
),
|
||||||
|
});
|
||||||
return wrapper;
|
|
||||||
};
|
|
||||||
|
|
||||||
afterEach(jest.clearAllMocks);
|
afterEach(jest.clearAllMocks);
|
||||||
afterEach(() => wrapper?.unmount());
|
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
[true],
|
[true],
|
||||||
|
@ -31,9 +42,13 @@ describe('<Tag />', () => {
|
||||||
])('includes an extra class when the color is light', (isLight) => {
|
])('includes an extra class when the color is light', (isLight) => {
|
||||||
isColorLightForKey.mockReturnValue(isLight);
|
isColorLightForKey.mockReturnValue(isLight);
|
||||||
|
|
||||||
const wrapper = createWrapper('foo');
|
const { container } = setUp('foo');
|
||||||
|
|
||||||
expect((wrapper.prop('className') as string).includes('tag--light-bg')).toEqual(isLight);
|
if (isLight) {
|
||||||
|
expect(container.firstChild).toHaveClass('tag--light-bg');
|
||||||
|
} else {
|
||||||
|
expect(container.firstChild).not.toHaveClass('tag--light-bg');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
@ -45,21 +60,25 @@ describe('<Tag />', () => {
|
||||||
])('includes generated color as backgroundColor', (generatedColor) => {
|
])('includes generated color as backgroundColor', (generatedColor) => {
|
||||||
getColorForKey.mockReturnValue(generatedColor);
|
getColorForKey.mockReturnValue(generatedColor);
|
||||||
|
|
||||||
const wrapper = createWrapper('foo');
|
const { container } = setUp('foo');
|
||||||
|
const { r, g, b } = hexToRgb(generatedColor);
|
||||||
|
|
||||||
expect((wrapper.prop('style') as any).backgroundColor).toEqual(generatedColor);
|
expect(container.firstChild).toHaveAttribute(
|
||||||
|
'style',
|
||||||
|
expect.stringContaining(`background-color: rgb(${r}, ${g}, ${b})`),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invokes expected callbacks when appropriate events are triggered', () => {
|
it('invokes expected callbacks when appropriate events are triggered', async () => {
|
||||||
const wrapper = createWrapper('foo', true);
|
const { container, user } = setUp('foo', true);
|
||||||
|
|
||||||
expect(onClick).not.toBeCalled();
|
expect(onClick).not.toHaveBeenCalled();
|
||||||
expect(onClose).not.toBeCalled();
|
expect(onClose).not.toHaveBeenCalled();
|
||||||
|
|
||||||
wrapper.simulate('click');
|
container.firstElementChild && await user.click(container.firstElementChild);
|
||||||
expect(onClick).toHaveBeenCalledTimes(1);
|
expect(onClick).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
wrapper.find('.tag__close-selected-tag').simulate('click');
|
await user.click(screen.getByLabelText('Close'));
|
||||||
expect(onClose).toHaveBeenCalledTimes(1);
|
expect(onClose).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,18 +87,17 @@ describe('<Tag />', () => {
|
||||||
[false, 0, 'pointer'],
|
[false, 0, 'pointer'],
|
||||||
[undefined, 0, 'pointer'],
|
[undefined, 0, 'pointer'],
|
||||||
])('includes a close component when the tag is clearable', (clearable, expectedCloseBtnAmount, expectedCursor) => {
|
])('includes a close component when the tag is clearable', (clearable, expectedCloseBtnAmount, expectedCursor) => {
|
||||||
const wrapper = createWrapper('foo', clearable);
|
const { container } = setUp('foo', clearable);
|
||||||
|
|
||||||
expect(wrapper.find('.tag__close-selected-tag')).toHaveLength(expectedCloseBtnAmount);
|
expect(screen.queryAllByLabelText('Close')).toHaveLength(expectedCloseBtnAmount);
|
||||||
expect((wrapper.prop('style') as any).cursor).toEqual(expectedCursor);
|
expect(container.firstChild).toHaveAttribute('style', expect.stringContaining(`cursor: ${expectedCursor}`));
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
[undefined, 'foo'],
|
[undefined, 'foo'],
|
||||||
['bar', 'bar'],
|
['bar', 'bar'],
|
||||||
])('falls back to text as children when no children are provided', (children, expectedChildren) => {
|
])('falls back to text as children when no children are provided', (children, expectedChildren) => {
|
||||||
const wrapper = createWrapper('foo', false, children);
|
const { container } = setUp('foo', false, children);
|
||||||
|
expect(container.firstChild).toHaveTextContent(expectedChildren);
|
||||||
expect(wrapper.html()).toContain(`>${expectedChildren}</span>`);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue