diff --git a/src/tags/TagsList.tsx b/src/tags/TagsList.tsx index 6b5656fc..4aae2063 100644 --- a/src/tags/TagsList.tsx +++ b/src/tags/TagsList.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect, useMemo, useState } from 'react'; +import { FC, useEffect, useState } from 'react'; import { Row } from 'reactstrap'; import { pipe } from 'ramda'; import Message from '../utils/Message'; @@ -30,16 +30,13 @@ const TagsList = (TagsCards: FC, TagsTable: FC { const [ mode, setMode ] = useState(settings.ui?.tagsMode ?? 'cards'); const [ order, setOrder ] = useState({}); - const sortedTags = useMemo( - pipe( - () => tagsList.filteredTags.map((tag): NormalizedTag => ({ - tag, - shortUrls: tagsList.stats[tag]?.shortUrlsCount ?? 0, - visits: tagsList.stats[tag]?.visitsCount ?? 0, - })), - (normalizedTags) => sortList(normalizedTags, order), - ), - [ tagsList.filteredTags, order ], + const resolveSortedTags = pipe( + () => tagsList.filteredTags.map((tag): NormalizedTag => ({ + tag, + shortUrls: tagsList.stats[tag]?.shortUrlsCount ?? 0, + visits: tagsList.stats[tag]?.visitsCount ?? 0, + })), + (normalizedTags) => sortList(normalizedTags, order), ); useEffect(() => { @@ -50,22 +47,24 @@ const TagsList = (TagsCards: FC, TagsTable: FC; } + if (tagsList.error) { + return ( + + + + ); + } + const orderByColumn = (field: OrderableFields) => () => setOrder({ field, dir: determineOrderDir(field, order.field, order.dir) }); const renderContent = () => { - if (tagsList.error) { - return ( - - - - ); - } - if (tagsList.filteredTags.length < 1) { return No tags found; } + const sortedTags = resolveSortedTags(); + return mode === 'cards' ? : ( diff --git a/test/tags/TagCard.test.tsx b/test/tags/TagCard.test.tsx index 8bdd6c6c..a3c96b75 100644 --- a/test/tags/TagCard.test.tsx +++ b/test/tags/TagCard.test.tsx @@ -8,19 +8,14 @@ import { ReachableServer } from '../../src/servers/data'; describe('', () => { let wrapper: ShallowWrapper; - const tagStats = { - shortUrlsCount: 48, - visitsCount: 23257, - }; const DeleteTagConfirmModal = jest.fn(); const EditTagModal = jest.fn(); const TagCard = createTagCard(DeleteTagConfirmModal, EditTagModal, Mock.all()); const createWrapper = (tag = 'ssr') => { wrapper = shallow( ({ id: '1' })} - tagStats={tagStats} displayed={true} toggle={() => {}} />, diff --git a/test/tags/TagsCards.test.tsx b/test/tags/TagsCards.test.tsx index 8b5d8db3..e41e7d5e 100644 --- a/test/tags/TagsCards.test.tsx +++ b/test/tags/TagsCards.test.tsx @@ -1,19 +1,19 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { Mock } from 'ts-mockery'; import { TagsCards as createTagsCards } from '../../src/tags/TagsCards'; -import { TagsList } from '../../src/tags/reducers/tagsList'; import { SelectedServer } from '../../src/servers/data'; import { rangeOf } from '../../src/utils/utils'; +import { NormalizedTag } from '../../src/tags/data'; describe('', () => { const amountOfTags = 10; - const tagsList = Mock.of({ filteredTags: rangeOf(amountOfTags, (i) => `tag_${i}`), stats: {} }); + const sortedTags = rangeOf(amountOfTags, (i) => Mock.of({ tag: `tag_${i}` })); const TagCard = () => null; const TagsCards = createTagsCards(TagCard); let wrapper: ShallowWrapper; beforeEach(() => { - wrapper = shallow(()} />); + wrapper = shallow(()} />); }); afterEach(() => wrapper?.unmount()); diff --git a/test/tags/TagsList.test.tsx b/test/tags/TagsList.test.tsx index 85932fb6..47618322 100644 --- a/test/tags/TagsList.test.tsx +++ b/test/tags/TagsList.test.tsx @@ -37,17 +37,21 @@ describe('', () => { 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); expect(loadingMsg).toHaveLength(1); expect(loadingMsg.html()).toContain('Loading...'); + expect(searchField).toHaveLength(0); }); 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); expect(errorMsg).toHaveLength(1); expect(errorMsg.html()).toContain('Error loading tags :('); + expect(searchField).toHaveLength(0); }); it('shows a message when the list of tags is empty', () => { diff --git a/test/tags/TagsTable.test.tsx b/test/tags/TagsTable.test.tsx index a1a2e52c..4d5dc344 100644 --- a/test/tags/TagsTable.test.tsx +++ b/test/tags/TagsTable.test.tsx @@ -4,24 +4,26 @@ import { match } from 'react-router'; import { Location, History } from 'history'; import { TagsTable as createTagsTable } from '../../src/tags/TagsTable'; import { SelectedServer } from '../../src/servers/data'; -import { TagsList } from '../../src/tags/reducers/tagsList'; import { rangeOf } from '../../src/utils/utils'; import SimplePaginator from '../../src/common/SimplePaginator'; import { NormalizedTag } from '../../src/tags/data'; describe('', () => { const TagsTableRow = () => null; + const orderByColumn = jest.fn(); const TagsTable = createTagsTable(TagsTableRow); const tags = (amount: number) => rangeOf(amount, (i) => `tag_${i}`); let wrapper: ShallowWrapper; - const createWrapper = (filteredTags: string[] = [], search = '') => { + const createWrapper = (sortedTags: string[] = [], search = '') => { wrapper = shallow( ({ stats: {}, filteredTags })} + sortedTags={sortedTags.map((tag) => Mock.of({ tag }))} selectedServer={Mock.all()} + currentOrder={{}} history={Mock.all()} location={Mock.of({ search })} match={Mock.all()} + orderByColumn={() => orderByColumn} />, ); @@ -33,6 +35,7 @@ describe('', () => { (global as any).history = { pushState: jest.fn() }; }); + afterEach(jest.clearAllMocks); afterEach(() => wrapper?.unmount()); it('renders empty result if there are no tags', () => { @@ -99,22 +102,11 @@ describe('', () => { it('orders tags when column is clicked', () => { const wrapper = createWrapper(tags(100)); - const firstRowText = () => (wrapper.find('tbody').find(TagsTableRow).first().prop('tag') as NormalizedTag).tag; - expect(firstRowText()).toEqual('tag_1'); - wrapper.find('thead').find('th').first().simulate('click'); // Tag column ASC - expect(firstRowText()).toEqual('tag_1'); - wrapper.find('thead').find('th').first().simulate('click'); // Tag column DESC - expect(firstRowText()).toEqual('tag_99'); - wrapper.find('thead').find('th').at(2).simulate('click'); // Visits column - ASC - expect(firstRowText()).toEqual('tag_100'); - wrapper.find('thead').find('th').at(2).simulate('click'); // Visits column - DESC - expect(firstRowText()).toEqual('tag_1'); - wrapper.find('thead').find('th').at(2).simulate('click'); // Visits column - reset - expect(firstRowText()).toEqual('tag_1'); - wrapper.find('thead').find('th').at(1).simulate('click'); // Short URLs column - ASC - expect(firstRowText()).toEqual('tag_100'); - wrapper.find('thead').find('th').at(1).simulate('click'); // Short URLs column - DESC - expect(firstRowText()).toEqual('tag_1'); + expect(orderByColumn).not.toHaveBeenCalled(); + wrapper.find('thead').find('th').first().simulate('click'); + wrapper.find('thead').find('th').at(2).simulate('click'); + wrapper.find('thead').find('th').at(1).simulate('click'); + expect(orderByColumn).toHaveBeenCalledTimes(3); }); });