// @vitest-environment jsdom import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'; import ScannedCardItem from '../../components/ScannedCardItem.js'; const BASE_CARD = { id: 'scan-1', name: 'Lightning Bolt', set: 'Alpha', databaseId: 99, quantity: 1, condition: 'NM', isFoil: false, image_url: null, processed: false, }; function renderItem(overrides = {}, props = {}) { const card = { ...BASE_CARD, ...overrides }; const defaultProps = { card, collections: [{ id: 1, name: 'Trade Binder' }], decks: [{ id: 2, name: 'Burn', game: 'mtg' }], selected: false, onToggleSelect: vi.fn(), onIncrement: vi.fn(), onDecrement: vi.fn(), onUpdateMetadata: vi.fn(), onMarkOwned: vi.fn(), onAddToCollection: vi.fn(), onAddToDeck: vi.fn(), onRemove: vi.fn(), ...props, }; return render(); } describe('ScannedCardItem', () => { beforeEach(() => { vi.stubGlobal( 'fetch', vi.fn().mockResolvedValue({ ok: true, json: async () => ({ quantity: 2 }), }) ); }); afterEach(() => { cleanup(); vi.unstubAllGlobals(); }); it('announces ownership count with role=status', async () => { renderItem(); const badge = await screen.findByRole('status', { name: /you already own 2 copies/i, }); expect(badge.textContent).toContain('You own 2'); }); it('calls onUpdateMetadata when condition changes', () => { const onUpdateMetadata = vi.fn(); renderItem({}, { onUpdateMetadata }); fireEvent.change(screen.getByRole('combobox', { name: /condition/i }), { target: { value: 'LP' }, }); expect(onUpdateMetadata).toHaveBeenCalledWith({ condition: 'LP' }); }); it('calls onUpdateMetadata when foil is toggled', () => { const onUpdateMetadata = vi.fn(); renderItem({}, { onUpdateMetadata }); fireEvent.click(screen.getByRole('checkbox', { name: /foil/i })); expect(onUpdateMetadata).toHaveBeenCalledWith({ isFoil: true }); }); it('does not fetch ownership when the card is not in the catalog', async () => { renderItem({ databaseId: null }); await waitFor(() => { expect(fetch).not.toHaveBeenCalled(); }); expect(screen.queryByRole('status')).toBeNull(); }); });