// @vitest-environment jsdom import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { cleanup, render, screen } from '@testing-library/react'; const mockRouterPush = vi.fn(); const mockRouterBack = vi.fn(); vi.mock('next/router', () => ({ useRouter: () => ({ push: mockRouterPush, back: mockRouterBack, pathname: '/scanner', asPath: '/scanner', query: {}, prefetch: vi.fn().mockResolvedValue(undefined), events: { on: vi.fn(), off: vi.fn(), emit: vi.fn() }, }), })); vi.mock('next/link', () => ({ __esModule: true, default: ({ href, children, ...rest }) => ( {children} ), })); vi.mock('../../lib/theme-context', () => ({ useTheme: () => ({ theme: 'light', toggleTheme: vi.fn() }), })); const layoutPropsRef = { current: null }; vi.mock('../../components/Layout', () => ({ default: ({ children, chrome, user }) => { layoutPropsRef.current = { chrome, user }; return (
{children}
); }, })); vi.mock('../../components/scanner/ScannerCamera', () => ({ default: ({ variant }) => (
), })); vi.mock('../../components/scanner/ScannerCheckoutSheet', () => ({ default: () =>
, })); vi.mock('../../components/scanner/ScannerResultPanel', () => ({ default: () =>
, })); vi.mock('../../components/scanner/ScannerHistoryStrip', () => ({ default: () =>
, TAB_RECENT: 'recent', TAB_QUEUE: 'queue', })); vi.mock('../../components/scanner/ScannerTips', () => ({ default: () => , })); vi.mock('../../components/scanner/ScannerToast', () => ({ default: () => null, })); const queueFixture = { scannedCards: [], collections: [], selectedCards: new Set(), isProcessing: false, addingCardIds: new Set(), ownershipMap: {}, unprocessedCount: 0, handleCardScanned: vi.fn(), updateCardMetadata: vi.fn(), addSingleCardToOwned: vi.fn(async () => true), addSingleCardToCollection: vi.fn(async () => true), commitSelectedToCollection: vi.fn(async () => []), commitSelectedToOwned: vi.fn(async () => []), clearScannedCards: vi.fn(), }; const cameraFixture = { videoRef: { current: null }, canvasRef: { current: null }, videoDevices: [{ deviceId: 'cam-1', label: 'FaceTime HD Camera' }], selectedDeviceId: 'cam-1', setSelectedDeviceId: vi.fn(), devicePickerStatus: 'ready', devicePickerMessage: '', }; const identificationFixture = { disambiguation: null, isIdentifying: false, identifyFromGalleryFile: vi.fn(async () => {}), }; vi.mock('../../lib/use-auth', () => ({ useAuth: () => ({ user: { email: 'scanner@test.com', role: 'user' }, loading: false, }), })); vi.mock('../../lib/use-scanner-session.js', () => ({ useScannerSession: () => ({ scanDefaults: { condition: 'NM', isFoil: false }, }), })); vi.mock('../../lib/use-scanner-queue.js', () => ({ useScannerQueue: () => queueFixture, })); vi.mock('../../lib/use-camera-scanner.js', () => ({ useCameraScanner: () => cameraFixture, })); vi.mock('../../lib/use-scanner-identification.js', () => ({ useScannerIdentification: () => identificationFixture, })); vi.mock('../../lib/scanner-session.js', () => ({ clearScannerCartStorage: vi.fn(), })); import Scanner from '../../pages/scanner.js'; function setMatchMedia(matches) { window.matchMedia = vi.fn((query) => ({ matches, media: query, addEventListener: vi.fn(), removeEventListener: vi.fn(), })); } describe('Scanner page viewport composition', () => { beforeEach(() => { layoutPropsRef.current = null; vi.clearAllMocks(); }); afterEach(() => cleanup()); it('uses immersive Layout chrome and hides workstation surfaces on mobile', () => { setMatchMedia(false); render(); expect(layoutPropsRef.current?.chrome).toBe('immersive'); expect(screen.getByTestId('scanner-camera').getAttribute('data-variant')).toBe('default'); expect(screen.queryByTestId('scanner-result-panel')).toBeNull(); expect(screen.queryByTestId('scanner-history-strip')).toBeNull(); expect(screen.queryByTestId('scanner-checkout-sheet')).toBeNull(); expect(screen.queryByRole('button', { name: 'Scanner Tips' })).toBeNull(); }); it('uses default Layout chrome and mounts workstation surfaces at md+', () => { setMatchMedia(true); render(); expect(layoutPropsRef.current?.chrome).toBe('default'); expect(screen.getByTestId('scanner-camera').getAttribute('data-variant')).toBe('workstation'); expect(screen.getByTestId('scanner-result-panel')).toBeTruthy(); expect(screen.getByTestId('scanner-history-strip')).toBeTruthy(); expect(screen.getByRole('button', { name: 'Scanner Tips' })).toBeTruthy(); expect(screen.getByLabelText('Camera')).toBeTruthy(); expect(screen.getByRole('button', { name: 'Upload Image' })).toBeTruthy(); expect(screen.getByRole('button', { name: 'Batch Scan' })).toBeTruthy(); expect(screen.getByRole('switch', { name: 'Auto-detect' })).toBeTruthy(); expect(screen.queryByTestId('scanner-checkout-sheet')).toBeNull(); }); });