mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 09:47:28 +03:00
Migrated TagsList to react testing library
This commit is contained in:
parent
744cea1f11
commit
27a05e55c9
3 changed files with 33 additions and 80 deletions
|
@ -30,7 +30,7 @@ export interface TagsListProps {
|
|||
settings: Settings;
|
||||
}
|
||||
|
||||
const TagsList = (TagsCards: FC<TagsListChildrenProps>, TagsTable: FC<TagsTableProps>) => boundToMercureHub((
|
||||
export const TagsList = (TagsCards: FC<TagsListChildrenProps>, TagsTable: FC<TagsTableProps>) => boundToMercureHub((
|
||||
{ filterTags, forceListTags, tagsList, selectedServer, settings }: TagsListProps,
|
||||
) => {
|
||||
const [mode, setMode] = useState<TagsMode>(settings.tags?.defaultMode ?? 'cards');
|
||||
|
@ -104,5 +104,3 @@ const TagsList = (TagsCards: FC<TagsListChildrenProps>, TagsTable: FC<TagsTableP
|
|||
</>
|
||||
);
|
||||
}, () => [Topics.visits]);
|
||||
|
||||
export default TagsList;
|
||||
|
|
|
@ -3,7 +3,7 @@ import TagsSelector from '../helpers/TagsSelector';
|
|||
import TagCard from '../TagCard';
|
||||
import DeleteTagConfirmModal from '../helpers/DeleteTagConfirmModal';
|
||||
import EditTagModal from '../helpers/EditTagModal';
|
||||
import TagsList from '../TagsList';
|
||||
import { TagsList } from '../TagsList';
|
||||
import { filterTags, listTags } from '../reducers/tagsList';
|
||||
import { deleteTag, tagDeleted } from '../reducers/tagDelete';
|
||||
import { editTag, tagEdited } from '../reducers/tagEdit';
|
||||
|
|
|
@ -1,25 +1,18 @@
|
|||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { identity } from 'ramda';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import createTagsList, { TagsListProps } from '../../src/tags/TagsList';
|
||||
import Message from '../../src/utils/Message';
|
||||
import { TagsList as createTagsList, TagsListProps } from '../../src/tags/TagsList';
|
||||
import { TagsList } from '../../src/tags/reducers/tagsList';
|
||||
import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub';
|
||||
import { Result } from '../../src/utils/Result';
|
||||
import { TagsModeDropdown } from '../../src/tags/TagsModeDropdown';
|
||||
import { SearchField } from '../../src/utils/SearchField';
|
||||
import { Settings } from '../../src/settings/reducers/settings';
|
||||
import { TagsOrderableFields } from '../../src/tags/data/TagsListChildrenProps';
|
||||
import { OrderingDropdown } from '../../src/utils/OrderingDropdown';
|
||||
|
||||
describe('<TagsList />', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
const filterTags = jest.fn();
|
||||
const TagsCards = () => null;
|
||||
const TagsTable = () => null;
|
||||
const TagsListComp = createTagsList(TagsCards, TagsTable);
|
||||
const createWrapper = (tagsList: Partial<TagsList>) => {
|
||||
wrapper = shallow(
|
||||
const TagsListComp = createTagsList(() => <>TagsCards</>, () => <>TagsTable</>);
|
||||
const setUp = (tagsList: Partial<TagsList>) => ({
|
||||
user: userEvent.setup(),
|
||||
...render(
|
||||
<TagsListComp
|
||||
{...Mock.all<TagsListProps>()}
|
||||
{...Mock.of<MercureBoundProps>({ mercureInfo: {} })}
|
||||
|
@ -28,89 +21,51 @@ describe('<TagsList />', () => {
|
|||
tagsList={Mock.of<TagsList>(tagsList)}
|
||||
settings={Mock.all<Settings>()}
|
||||
/>,
|
||||
).dive(); // Dive is needed as this component is wrapped in a HOC
|
||||
),
|
||||
});
|
||||
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
afterEach(() => wrapper?.unmount());
|
||||
afterEach(jest.clearAllMocks);
|
||||
|
||||
it('shows a loading message when tags are being loaded', () => {
|
||||
const wrapper = createWrapper({ loading: true });
|
||||
const loadingMsg = wrapper.find(Message);
|
||||
const searchField = wrapper.find(SearchField);
|
||||
setUp({ loading: true });
|
||||
|
||||
expect(loadingMsg).toHaveLength(1);
|
||||
expect(loadingMsg.html()).toContain('Loading...');
|
||||
expect(searchField).toHaveLength(0);
|
||||
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Error loading tags :(')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows an error when tags failed to be loaded', () => {
|
||||
const wrapper = createWrapper({ error: true });
|
||||
const errorMsg = wrapper.find(Result).filterWhere((result) => result.prop('type') === 'error');
|
||||
const searchField = wrapper.find(SearchField);
|
||||
setUp({ error: true });
|
||||
|
||||
expect(errorMsg).toHaveLength(1);
|
||||
expect(errorMsg.html()).toContain('Error loading tags :(');
|
||||
expect(searchField).toHaveLength(0);
|
||||
expect(screen.getByText('Error loading tags :(')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Loading')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows a message when the list of tags is empty', () => {
|
||||
const wrapper = createWrapper({ filteredTags: [] });
|
||||
const msg = wrapper.find(Message);
|
||||
setUp({ filteredTags: [] });
|
||||
|
||||
expect(msg).toHaveLength(1);
|
||||
expect(msg.html()).toContain('No tags found');
|
||||
expect(screen.getByText('No tags found')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Error loading tags :(')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Loading')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders proper component based on the display mode', () => {
|
||||
const wrapper = createWrapper({ filteredTags: ['foo', 'bar'], stats: {} });
|
||||
it('renders proper component based on the display mode', async () => {
|
||||
const { user } = setUp({ filteredTags: ['foo', 'bar'], stats: {} });
|
||||
|
||||
expect(wrapper.find(TagsCards)).toHaveLength(1);
|
||||
expect(wrapper.find(TagsTable)).toHaveLength(0);
|
||||
expect(screen.getByText('TagsCards')).toBeInTheDocument();
|
||||
expect(screen.queryByText('TagsTable')).not.toBeInTheDocument();
|
||||
|
||||
wrapper.find(TagsModeDropdown).simulate('change');
|
||||
await user.click(screen.getByRole('button', { name: /^Display mode/ }));
|
||||
await user.click(screen.getByRole('menuitem', { name: /List/ }));
|
||||
|
||||
expect(wrapper.find(TagsCards)).toHaveLength(0);
|
||||
expect(wrapper.find(TagsTable)).toHaveLength(1);
|
||||
expect(screen.queryByText('TagsCards')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('TagsTable')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('triggers tags filtering when search field changes', () => {
|
||||
const wrapper = createWrapper({ filteredTags: [] });
|
||||
const searchField = wrapper.find(SearchField);
|
||||
it('triggers tags filtering when search field changes', async () => {
|
||||
const { user } = setUp({ filteredTags: [] });
|
||||
|
||||
expect(searchField).toHaveLength(1);
|
||||
expect(filterTags).not.toHaveBeenCalled();
|
||||
searchField.simulate('change');
|
||||
expect(filterTags).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('triggers ordering when sorting dropdown changes', () => {
|
||||
const wrapper = createWrapper({ filteredTags: [] });
|
||||
|
||||
expect(wrapper.find(OrderingDropdown).prop('order')).toEqual({});
|
||||
wrapper.find(OrderingDropdown).simulate('change', 'tag', 'DESC');
|
||||
expect(wrapper.find(OrderingDropdown).prop('order')).toEqual({ field: 'tag', dir: 'DESC' });
|
||||
wrapper.find(OrderingDropdown).simulate('change', 'visits', 'ASC');
|
||||
expect(wrapper.find(OrderingDropdown).prop('order')).toEqual({ field: 'visits', dir: 'ASC' });
|
||||
});
|
||||
|
||||
it('can update current order via orderByColumn from table component', () => {
|
||||
const wrapper = createWrapper({ filteredTags: ['foo', 'bar'], stats: {} });
|
||||
const callOrderBy = (field: TagsOrderableFields) => {
|
||||
((wrapper.find(TagsTable).prop('orderByColumn') as Function)(field) as Function)();
|
||||
};
|
||||
|
||||
wrapper.find(TagsModeDropdown).simulate('change'); // Make sure table is rendered
|
||||
|
||||
callOrderBy('visits');
|
||||
expect(wrapper.find(TagsTable).prop('currentOrder')).toEqual({ field: 'visits', dir: 'ASC' });
|
||||
callOrderBy('visits');
|
||||
expect(wrapper.find(TagsTable).prop('currentOrder')).toEqual({ field: 'visits', dir: 'DESC' });
|
||||
callOrderBy('tag');
|
||||
expect(wrapper.find(TagsTable).prop('currentOrder')).toEqual({ field: 'tag', dir: 'ASC' });
|
||||
callOrderBy('shortUrls');
|
||||
expect(wrapper.find(TagsTable).prop('currentOrder')).toEqual({ field: 'shortUrls', dir: 'ASC' });
|
||||
await user.type(screen.getByPlaceholderText('Search...'), 'Hello');
|
||||
await waitFor(() => expect(filterTags).toHaveBeenCalledTimes(1));
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue