diff --git a/test/short-urls/ShortUrlsList.test.tsx b/test/short-urls/ShortUrlsList.test.tsx index fa314655..ab911250 100644 --- a/test/short-urls/ShortUrlsList.test.tsx +++ b/test/short-urls/ShortUrlsList.test.tsx @@ -1,26 +1,25 @@ -import { shallow, ShallowWrapper } from 'enzyme'; -import { ReactElement } from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { FC } from 'react'; import { Mock } from 'ts-mockery'; -import { useNavigate } from 'react-router-dom'; +import { MemoryRouter, useNavigate } from 'react-router-dom'; import { ShortUrlsList as createShortUrlsList } from '../../src/short-urls/ShortUrlsList'; -import { ShortUrlsOrderableFields, ShortUrl, ShortUrlsOrder } from '../../src/short-urls/data'; +import { ShortUrl, ShortUrlsOrder } from '../../src/short-urls/data'; import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub'; import { ShortUrlsList as ShortUrlsListModel } from '../../src/short-urls/reducers/shortUrlsList'; -import { Paginator } from '../../src/short-urls/Paginator'; import { ReachableServer } from '../../src/servers/data'; import { Settings } from '../../src/settings/reducers/settings'; +import { ShortUrlsTableProps } from '../../src/short-urls/ShortUrlsTable'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: jest.fn().mockReturnValue(jest.fn()), - useParams: jest.fn().mockReturnValue({}), useLocation: jest.fn().mockReturnValue({ search: '?tags=test%20tag&search=example.com' }), })); describe('', () => { - let wrapper: ShallowWrapper; - const ShortUrlsTable = () => null; - const ShortUrlsFilteringBar = () => null; + const ShortUrlsTable: FC = ({ onTagClick }) => onTagClick?.('foo')}>ShortUrlsTable; + const ShortUrlsFilteringBar = () => ShortUrlsFilteringBar; const listShortUrlsMock = jest.fn(); const navigate = jest.fn(); const shortUrlsList = Mock.of({ @@ -33,85 +32,65 @@ describe('', () => { tags: ['test tag'], }), ], - pagination: {}, + pagination: { pagesCount: 3 }, }, }); const ShortUrlsList = createShortUrlsList(ShortUrlsTable, ShortUrlsFilteringBar); - const createWrapper = (defaultOrdering: ShortUrlsOrder = {}) => shallow( - ({ mercureInfo: { loading: true } })} - listShortUrls={listShortUrlsMock} - shortUrlsList={shortUrlsList} - selectedServer={Mock.of({ id: '1' })} - settings={Mock.of({ shortUrlsList: { defaultOrdering } })} - />, - ).dive(); // Dive is needed as this component is wrapped in a HOC + const setUp = (defaultOrdering: ShortUrlsOrder = {}) => ({ + user: userEvent.setup(), + ...render( + + ({ mercureInfo: { loading: true } })} + listShortUrls={listShortUrlsMock} + shortUrlsList={shortUrlsList} + selectedServer={Mock.of({ id: '1' })} + settings={Mock.of({ shortUrlsList: { defaultOrdering } })} + /> + , + ), + }); beforeEach(() => { (useNavigate as any).mockReturnValue(navigate); - - wrapper = createWrapper(); }); afterEach(jest.clearAllMocks); - afterEach(() => wrapper?.unmount()); it('wraps expected components', () => { - expect(wrapper.find(ShortUrlsTable)).toHaveLength(1); - expect(wrapper.find(Paginator)).toHaveLength(1); - expect(wrapper.find(ShortUrlsFilteringBar)).toHaveLength(1); + setUp(); + + expect(screen.getByText('ShortUrlsTable')).toBeInTheDocument(); + expect(screen.getByText('ShortUrlsFilteringBar')).toBeInTheDocument(); }); it('passes current query to paginator', () => { - expect(wrapper.find(Paginator).prop('currentQueryString')).toEqual('?tags=test%20tag&search=example.com'); + setUp(); + + const links = screen.getAllByRole('link'); + + expect(links.length > 0).toEqual(true); + links.forEach( + (link) => expect(link).toHaveAttribute('href', expect.stringContaining('?tags=test%20tag&search=example.com')), + ); }); - it('gets list refreshed every time a tag is clicked', () => { - wrapper.find(ShortUrlsTable).simulate('tagClick', 'foo'); - wrapper.find(ShortUrlsTable).simulate('tagClick', 'bar'); - wrapper.find(ShortUrlsTable).simulate('tagClick', 'baz'); + it('gets list refreshed every time a tag is clicked', async () => { + const { user } = setUp(); - expect(navigate).toHaveBeenCalledTimes(3); - expect(navigate).toHaveBeenNthCalledWith(1, expect.stringContaining(`tags=${encodeURIComponent('test tag,foo')}`)); - expect(navigate).toHaveBeenNthCalledWith(2, expect.stringContaining(`tags=${encodeURIComponent('test tag,bar')}`)); - expect(navigate).toHaveBeenNthCalledWith(3, expect.stringContaining(`tags=${encodeURIComponent('test tag,baz')}`)); - }); - - it('invokes order icon rendering', () => { - const renderIcon = (field: ShortUrlsOrderableFields) => - (wrapper.find(ShortUrlsTable).prop('renderOrderIcon') as (field: ShortUrlsOrderableFields) => ReactElement)(field); - - expect(renderIcon('visits').props.currentOrder).toEqual({}); - - (wrapper.find(ShortUrlsFilteringBar).prop('handleOrderBy') as Function)('visits'); - expect(renderIcon('visits').props.currentOrder).toEqual({ field: 'visits' }); - - (wrapper.find(ShortUrlsFilteringBar).prop('handleOrderBy') as Function)('visits', 'ASC'); - expect(renderIcon('visits').props.currentOrder).toEqual({ field: 'visits', dir: 'ASC' }); - }); - - it('handles order through table', () => { - const orderByColumn: (field: ShortUrlsOrderableFields) => Function = wrapper.find(ShortUrlsTable).prop('orderByColumn'); - - expect(wrapper.find(ShortUrlsFilteringBar).prop('order')).toEqual({}); - - orderByColumn('visits')(); - expect(wrapper.find(ShortUrlsFilteringBar).prop('order')).toEqual({ field: 'visits', dir: 'ASC' }); - - orderByColumn('title')(); - expect(wrapper.find(ShortUrlsFilteringBar).prop('order')).toEqual({ field: 'title', dir: 'ASC' }); - - orderByColumn('shortCode')(); - expect(wrapper.find(ShortUrlsFilteringBar).prop('order')).toEqual({ field: 'shortCode', dir: 'ASC' }); + expect(navigate).not.toHaveBeenCalled(); + await user.click(screen.getByText('ShortUrlsTable')); + expect(navigate).toHaveBeenCalledWith(expect.stringContaining(`tags=${encodeURIComponent('test tag,foo')}`)); }); it.each([ [Mock.of({ field: 'visits', dir: 'ASC' }), 'visits', 'ASC'], [Mock.of({ field: 'title', dir: 'DESC' }), 'title', 'DESC'], [Mock.of(), undefined, undefined], - ])('has expected initial ordering', (initialOrderBy, field, dir) => { - const wrapper = createWrapper(initialOrderBy); - - expect(wrapper.find(ShortUrlsFilteringBar).prop('order')).toEqual({ field, dir }); + ])('has expected initial ordering based on settings', (initialOrderBy, field, dir) => { + setUp(initialOrderBy); + expect(listShortUrlsMock).toHaveBeenCalledWith(expect.objectContaining({ + orderBy: { field, dir }, + })); }); });