Skip to content

Commit ee25761

Browse files
committed
Add VisitsComparisonCollector test
1 parent be0543c commit ee25761

File tree

3 files changed

+90
-11
lines changed

3 files changed

+90
-11
lines changed

src/visits/visits-comparison/VisitsComparisonCollector.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import { useRoutesPrefix } from '../../utils/routesPrefix';
1111
import { useVisitsToCompare } from './VisitsComparisonContext';
1212

1313
type VisitsComparisonCollectorProps = {
14-
className?: string;
1514
type: 'short-urls' | 'tags' | 'domains';
15+
className?: string;
1616
};
1717

1818
export const VisitsComparisonCollector: FC<VisitsComparisonCollectorProps> = ({ className, type }) => {
1919
const routesPrefix = useRoutesPrefix();
2020
const context = useVisitsToCompare();
2121
const query = useMemo(
22-
() => (!context ? '' : encodeURIComponent(context.itemsToCompare.map((visit) => visit.query).join(','))),
22+
() => (!context ? '' : encodeURIComponent(context.itemsToCompare.map((item) => item.query).join(','))),
2323
[context],
2424
);
2525

@@ -30,9 +30,9 @@ export const VisitsComparisonCollector: FC<VisitsComparisonCollectorProps> = ({
3030
return (
3131
<div className={clsx('top-sticky', className)}>
3232
<SimpleCard bodyClassName="d-flex gap-3 align-items-center">
33-
<div className="d-flex flex-wrap gap-1 flex-grow-1">
33+
<ul className="d-flex flex-wrap gap-1 flex-grow-1 p-0 m-0">
3434
{context.itemsToCompare.map((item, index) => (
35-
<span key={`${item.name}_${index}`} className="badge bg-secondary pe-1">
35+
<li key={`${item.name}_${index}`} className="badge bg-secondary pe-1">
3636
{item.name}
3737
<UnstyledButton
3838
aria-label={`Remove ${item.name}`}
@@ -41,10 +41,10 @@ export const VisitsComparisonCollector: FC<VisitsComparisonCollectorProps> = ({
4141
>
4242
&times;
4343
</UnstyledButton>
44-
</span>
44+
</li>
4545
))}
46-
</div>
47-
<div>
46+
</ul>
47+
<div className="indivisible">
4848
<Button
4949
outline
5050
color="primary"

src/visits/visits-comparison/VisitsComparisonContext.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ export const useVisitsToCompare = (): VisitsComparison | undefined => {
2222
};
2323

2424
export const useVisitsComparison = (): VisitsComparison => {
25-
const [itemsToCompare, setItemToCompare] = useState<VisitsComparisonItem[]>([]);
25+
const [itemsToCompare, setItemsToCompare] = useState<VisitsComparisonItem[]>([]);
2626
const addItemToCompare = useCallback(
27-
(item: VisitsComparisonItem) => setItemToCompare((prev) => [...prev, item]),
27+
(item: VisitsComparisonItem) => setItemsToCompare((prev) => [...prev, item]),
2828
[],
2929
);
3030
const removeItemToCompare = useCallback(
31-
(item: VisitsComparisonItem) => setItemToCompare((prev) => prev.filter((i) => i !== item)),
31+
(item: VisitsComparisonItem) => setItemsToCompare((prev) => prev.filter((i) => i !== item)),
3232
[],
3333
);
34-
const clearItemsToCompare = useCallback(() => setItemToCompare([]), []);
34+
const clearItemsToCompare = useCallback(() => setItemsToCompare([]), []);
3535

3636
return { itemsToCompare, addItemToCompare, removeItemToCompare, clearItemsToCompare };
3737
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { screen, waitFor } from '@testing-library/react';
2+
import { fromPartial } from '@total-typescript/shoehorn';
3+
import { MemoryRouter } from 'react-router-dom';
4+
import { rangeOf } from '../../../src/utils/helpers';
5+
import { VisitsComparisonCollector } from '../../../src/visits/visits-comparison/VisitsComparisonCollector';
6+
import type { VisitsComparison } from '../../../src/visits/visits-comparison/VisitsComparisonContext';
7+
import { VisitsComparisonProvider } from '../../../src/visits/visits-comparison/VisitsComparisonContext';
8+
import { checkAccessibility } from '../../__helpers__/accessibility';
9+
import { renderWithEvents } from '../../__helpers__/setUpTest';
10+
11+
describe('<VisitsComparisonCollector />', () => {
12+
const clearItemsToCompare = vi.fn();
13+
const removeItemToCompare = vi.fn();
14+
const createVisitsComparison = (itemsAmount = 1): VisitsComparison => fromPartial({
15+
itemsToCompare: rangeOf(itemsAmount, (index) => ({ name: `foo${index}`, query: `bar${index}` })),
16+
clearItemsToCompare,
17+
removeItemToCompare,
18+
});
19+
const setUp = (visitsComparison?: VisitsComparison, type: 'short-urls' | 'tags' | 'domains' = 'short-urls') =>
20+
renderWithEvents(
21+
<MemoryRouter>
22+
<VisitsComparisonProvider value={visitsComparison}>
23+
<VisitsComparisonCollector type={type} />
24+
</VisitsComparisonProvider>
25+
</MemoryRouter>,
26+
);
27+
28+
it('passes a11y checks', () => checkAccessibility(setUp(createVisitsComparison())));
29+
30+
it.each([
31+
[undefined],
32+
[fromPartial<VisitsComparison>({ itemsToCompare: [] })],
33+
])('does not render when no context or no items are defined', (visitsComparison) => {
34+
const { container } = setUp(visitsComparison);
35+
expect(container).toBeEmptyDOMElement();
36+
});
37+
38+
it.each([
39+
[1, true],
40+
[2, false],
41+
[5, false],
42+
])('disables compare button when there is only one selected item', (itemsAmount, isDisabled) => {
43+
setUp(createVisitsComparison(itemsAmount));
44+
const compareButton = screen.getByText(/^Compare/);
45+
46+
expect(screen.getAllByRole('listitem')).toHaveLength(itemsAmount);
47+
if (isDisabled) {
48+
expect(compareButton).toHaveAttribute('disabled');
49+
} else {
50+
expect(compareButton).not.toHaveAttribute('disabled');
51+
}
52+
});
53+
54+
it('can clear selected items', async () => {
55+
const { user } = setUp(createVisitsComparison(5));
56+
57+
await user.click(screen.getByLabelText('Close compare'));
58+
expect(clearItemsToCompare).toHaveBeenCalled();
59+
});
60+
61+
it.each([[1], [2], [4]])('can remove individual items', async (index) => {
62+
const { user } = setUp(createVisitsComparison(5));
63+
64+
await user.click(screen.getByLabelText(`Remove foo${index}`));
65+
expect(removeItemToCompare).toHaveBeenCalledWith({ name: `foo${index}`, query: `bar${index}` });
66+
});
67+
68+
it.each([
69+
['short-urls' as const],
70+
['tags' as const],
71+
['domains' as const],
72+
])('redirects comparison to expected location', (type) => {
73+
setUp(createVisitsComparison(3), type);
74+
expect(screen.getByText(/^Compare/)).toHaveAttribute(
75+
'href',
76+
`/${type}/compare-visits?${type}=${encodeURIComponent('bar1,bar2,bar3')}`,
77+
);
78+
});
79+
});

0 commit comments

Comments
 (0)