import { describe, expect, it, vi, beforeEach } from 'vitest'; import { buildCatalogSyncQueue, runUnifiedCatalogSync } from '../../lib/card-import/sync-catalog.js'; import { runBulkMtgSync } from '../../lib/card-import/bulk-sync.js'; import { runBulkPokemonSync } from '../../lib/card-import/pokemon-bulk.js'; import { runBulkLorcanaSync } from '../../lib/card-import/lorcana-bulk.js'; vi.mock('../../lib/card-import/bulk-sync.js', () => ({ runBulkMtgSync: vi.fn(), })); vi.mock('../../lib/card-import/pokemon-bulk.js', () => ({ runBulkPokemonSync: vi.fn(), })); vi.mock('../../lib/card-import/lorcana-bulk.js', () => ({ runBulkLorcanaSync: vi.fn(), })); vi.mock('@vercel/postgres', () => ({ sql: vi.fn(() => Promise.resolve({ rows: [] })), })); describe('buildCatalogSyncQueue', () => { it('merges MTG and Pokémon missing sets by release date, newest first', () => { const queue = buildCatalogSyncQueue( [ { code: 'fin', name: 'Final Fantasy', releasedAt: '2026-05-01' }, { code: 'dsk', name: 'Duskmourn', releasedAt: '2024-09-27' }, ], [ { id: 'sv10', name: 'Perfect Order', releasedAt: '2026-03-27' }, { id: 'sv9', name: 'Journey Together', releasedAt: '2025-03-28' }, ], 3 ); expect(queue).toEqual([ { game: 'mtg', setCode: 'fin', name: 'Final Fantasy', releasedAt: '2026-05-01', }, { game: 'pokemon', setCode: 'sv10', name: 'Perfect Order', releasedAt: '2026-03-27', }, { game: 'pokemon', setCode: 'sv9', name: 'Journey Together', releasedAt: '2025-03-28', }, ]); }); }); describe('runUnifiedCatalogSync', () => { beforeEach(() => { vi.clearAllMocks(); }); it('runs all three games and isolates per-game failures', async () => { runBulkMtgSync.mockResolvedValue({ mode: 'bulk', upserted: 36000, errors: 0 }); runBulkPokemonSync.mockRejectedValue(new Error('Pokemon API down')); runBulkLorcanaSync.mockResolvedValue({ mode: 'bulk', upserted: 2283, errors: 0 }); const summary = await runUnifiedCatalogSync(); expect(summary.mode).toBe('unified'); expect(summary.mtg.upserted).toBe(36000); expect(summary.pokemon.error).toBe('Pokemon API down'); expect(summary.lorcana.upserted).toBe(2283); expect(summary.errors).toEqual([{ game: 'pokemon', message: 'Pokemon API down' }]); expect(summary.durationMs).toBeGreaterThanOrEqual(0); expect(runBulkMtgSync).toHaveBeenCalledOnce(); expect(runBulkPokemonSync).toHaveBeenCalledOnce(); expect(runBulkLorcanaSync).toHaveBeenCalledOnce(); }); });