95 lines
2.8 KiB
JavaScript
95 lines
2.8 KiB
JavaScript
|
|
// @vitest-environment jsdom
|
||
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||
|
|
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
||
|
|
|
||
|
|
import ScannerDestinationPicker from '../../components/ScannerDestinationPicker.js';
|
||
|
|
|
||
|
|
const COLLECTIONS = [
|
||
|
|
{ id: 1, name: 'Modern Staples', tcg: 'MTG' },
|
||
|
|
{ id: 2, name: 'Pokémon Binder', tcg: 'Pokemon' },
|
||
|
|
];
|
||
|
|
|
||
|
|
const DECKS = [
|
||
|
|
{ id: 10, name: 'Commander', game: 'mtg' },
|
||
|
|
{ id: 11, name: 'Standard', game: 'pokemon' },
|
||
|
|
];
|
||
|
|
|
||
|
|
describe('ScannerDestinationPicker', () => {
|
||
|
|
afterEach(() => cleanup());
|
||
|
|
|
||
|
|
it('shows the active destination type with aria-pressed', () => {
|
||
|
|
render(
|
||
|
|
<ScannerDestinationPicker
|
||
|
|
gameFilter="All"
|
||
|
|
onGameFilterChange={vi.fn()}
|
||
|
|
destination={{ type: 'owned', id: null, label: 'My owned cards' }}
|
||
|
|
onDestinationChange={vi.fn()}
|
||
|
|
collections={COLLECTIONS}
|
||
|
|
decks={DECKS}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
|
||
|
|
expect(screen.getByRole('button', { name: /owned/i }).getAttribute('aria-pressed')).toBe('true');
|
||
|
|
expect(screen.getByRole('button', { name: /collection/i }).getAttribute('aria-pressed')).toBe('false');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('calls onDestinationChange when switching to a collection', () => {
|
||
|
|
const onDestinationChange = vi.fn();
|
||
|
|
|
||
|
|
render(
|
||
|
|
<ScannerDestinationPicker
|
||
|
|
gameFilter="All"
|
||
|
|
onGameFilterChange={vi.fn()}
|
||
|
|
destination={{ type: 'owned', id: null, label: 'My owned cards' }}
|
||
|
|
onDestinationChange={onDestinationChange}
|
||
|
|
collections={COLLECTIONS}
|
||
|
|
decks={DECKS}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
|
||
|
|
fireEvent.click(screen.getByRole('button', { name: /collection/i }));
|
||
|
|
|
||
|
|
expect(onDestinationChange).toHaveBeenCalledWith({
|
||
|
|
type: 'collection',
|
||
|
|
id: 1,
|
||
|
|
label: 'Modern Staples',
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('filters decks by game and disables deck toggle when none match', () => {
|
||
|
|
render(
|
||
|
|
<ScannerDestinationPicker
|
||
|
|
gameFilter="MTG"
|
||
|
|
onGameFilterChange={vi.fn()}
|
||
|
|
destination={{ type: 'deck', id: 10, label: 'Commander' }}
|
||
|
|
onDestinationChange={vi.fn()}
|
||
|
|
collections={COLLECTIONS}
|
||
|
|
decks={DECKS}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
|
||
|
|
expect(screen.getByRole('button', { name: /deck/i }).disabled).toBe(false);
|
||
|
|
expect(screen.queryByText(/Standard/)).toBeNull();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('calls onGameFilterChange when the game select changes', () => {
|
||
|
|
const onGameFilterChange = vi.fn();
|
||
|
|
|
||
|
|
render(
|
||
|
|
<ScannerDestinationPicker
|
||
|
|
gameFilter="All"
|
||
|
|
onGameFilterChange={onGameFilterChange}
|
||
|
|
destination={{ type: 'owned', id: null, label: 'My owned cards' }}
|
||
|
|
onDestinationChange={vi.fn()}
|
||
|
|
collections={COLLECTIONS}
|
||
|
|
decks={DECKS}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
|
||
|
|
fireEvent.change(screen.getByRole('combobox', { name: /game filter/i }), {
|
||
|
|
target: { value: 'Lorcana' },
|
||
|
|
});
|
||
|
|
expect(onGameFilterChange).toHaveBeenCalledWith('Lorcana');
|
||
|
|
});
|
||
|
|
});
|