|
| 1 | +import '@testing-library/jest-dom'; |
| 2 | +import { fireEvent, render } from '@testing-library/react'; |
| 3 | +import { Competition } from '@wca/helpers'; |
| 4 | +import { AnchorLink } from '@/lib/linkRenderer'; |
| 5 | +import { storybookCompetitionFixture } from '@/storybook/competitionFixtures'; |
| 6 | +import { CompetitionGroupContainer } from './CompetitionGroup'; |
| 7 | + |
| 8 | +const mockSetTitle = jest.fn(); |
| 9 | +const mockWcif = storybookCompetitionFixture as unknown as Competition; |
| 10 | + |
| 11 | +jest.mock('@/i18n', () => ({ |
| 12 | + __esModule: true, |
| 13 | + default: { |
| 14 | + t: (key: string, options?: Record<string, unknown>) => |
| 15 | + key === 'common.activityCodeToName.group' ? `Group ${options?.groupNumber}` : key, |
| 16 | + }, |
| 17 | +})); |
| 18 | + |
| 19 | +jest.mock('@/components', () => ({ |
| 20 | + ActivityRow: () => <div />, |
| 21 | +})); |
| 22 | + |
| 23 | +jest.mock('@/components/AssignmentCodeCell', () => ({ |
| 24 | + AssignmentCodeCell: ({ count }: { count: number }) => <div>{count}</div>, |
| 25 | +})); |
| 26 | + |
| 27 | +jest.mock('@/components/Breadcrumbs/Breadcrumbs', () => ({ |
| 28 | + Breadcrumbs: () => <div />, |
| 29 | +})); |
| 30 | + |
| 31 | +jest.mock('@/components/Container', () => ({ |
| 32 | + Container: ({ children }: { children: React.ReactNode }) => <div>{children}</div>, |
| 33 | +})); |
| 34 | + |
| 35 | +jest.mock('@/components/CutoffTimeLimitPanel', () => ({ |
| 36 | + CutoffTimeLimitPanel: () => <div />, |
| 37 | +})); |
| 38 | + |
| 39 | +jest.mock('@/providers/WCIFProvider', () => ({ |
| 40 | + useWCIF: () => ({ |
| 41 | + wcif: mockWcif, |
| 42 | + setTitle: mockSetTitle, |
| 43 | + }), |
| 44 | +})); |
| 45 | + |
| 46 | +jest.mock('react-i18next', () => ({ |
| 47 | + useTranslation: () => ({ |
| 48 | + t: (key: string) => key, |
| 49 | + }), |
| 50 | +})); |
| 51 | + |
| 52 | +describe('CompetitionGroupContainer', () => { |
| 53 | + beforeEach(() => { |
| 54 | + mockSetTitle.mockClear(); |
| 55 | + }); |
| 56 | + |
| 57 | + it('navigates between groups with arrow keys', () => { |
| 58 | + const onNavigate = jest.fn(); |
| 59 | + |
| 60 | + render( |
| 61 | + <CompetitionGroupContainer |
| 62 | + competitionId="SeattleSummerOpen2026" |
| 63 | + roundId="333-r1" |
| 64 | + groupNumber="1" |
| 65 | + LinkComponent={AnchorLink} |
| 66 | + onNavigate={onNavigate} |
| 67 | + />, |
| 68 | + ); |
| 69 | + |
| 70 | + fireEvent.keyDown(document, { key: 'ArrowRight' }); |
| 71 | + |
| 72 | + expect(onNavigate).toHaveBeenCalledWith('/competitions/SeattleSummerOpen2026/events/333-r1/2'); |
| 73 | + }); |
| 74 | + |
| 75 | + it('does not navigate past the first group with the left arrow key', () => { |
| 76 | + const onNavigate = jest.fn(); |
| 77 | + |
| 78 | + render( |
| 79 | + <CompetitionGroupContainer |
| 80 | + competitionId="SeattleSummerOpen2026" |
| 81 | + roundId="333-r1" |
| 82 | + groupNumber="1" |
| 83 | + LinkComponent={AnchorLink} |
| 84 | + onNavigate={onNavigate} |
| 85 | + />, |
| 86 | + ); |
| 87 | + |
| 88 | + fireEvent.keyDown(document, { key: 'ArrowLeft' }); |
| 89 | + |
| 90 | + expect(onNavigate).not.toHaveBeenCalled(); |
| 91 | + }); |
| 92 | +}); |
0 commit comments