import { beforeEach, describe, expect, it, vi } from 'vitest'; import { buildTcgdexPriceIndex, getTcgdexBaseUrl, matchTcgdexCard, parseTcgdexPricing, } from '../../../lib/pricing/tcgdex-client.js'; describe('tcgdex-client', () => { beforeEach(() => { delete process.env.TCGDEX_BASE_URL; vi.restoreAllMocks(); }); it('uses default TCGdex base URL', () => { expect(getTcgdexBaseUrl()).toBe('https://api.tcgdex.net/v2/en'); }); it('parses TCGPlayer USD pricing into current and market prices', () => { const parsed = parseTcgdexPricing({ pricing: { tcgplayer: { normal: { lowPrice: 0.5, marketPrice: 1.25, }, }, }, }); expect(parsed).toEqual({ currentPrice: 0.5, marketPrice: 1.25, currency: 'USD', }); }); it('falls back to Cardmarket EUR for market_price when USD is missing', () => { const parsed = parseTcgdexPricing({ pricing: { cardmarket: { trend: 2.5, unit: 'EUR', }, }, }); expect(parsed.currentPrice).toBeNull(); expect(parsed.marketPrice).toBe(2.5); expect(parsed.currency).toBe('EUR'); }); it('matches cards by set card number with leading zero normalization', () => { const index = buildTcgdexPriceIndex([ { id: 'me3-18', localId: '18', name: 'Seel', set: { cardCount: { official: 88 } }, }, ]); const match = matchTcgdexCard(index, { name: 'Seel', cardNumber: '018/88', }); expect(match?.id).toBe('me3-18'); }); it('falls back to unique name match within a set index', () => { const index = buildTcgdexPriceIndex([ { id: 'sv1-001', localId: '1', name: 'Sprigatito' }, ]); const match = matchTcgdexCard(index, { name: 'Sprigatito', cardNumber: null, }); expect(match?.id).toBe('sv1-001'); }); it('fetchSetCards loads set summaries and full card details', async () => { const fetchMock = vi.fn(async (url) => { if (url.endsWith('/sets/me3')) { return { ok: true, json: async () => ({ cards: [{ id: 'me3-18', localId: '18', name: 'Seel' }], }), }; } if (url.endsWith('/cards/me3-18')) { return { ok: true, json: async () => ({ id: 'me3-18', localId: '18', name: 'Seel', pricing: { tcgplayer: { normal: { lowPrice: 0.1, marketPrice: 0.2 } }, }, }), }; } throw new Error(`unexpected url ${url}`); }); vi.stubGlobal('fetch', fetchMock); const { fetchSetCards } = await import('../../../lib/pricing/tcgdex-client.js'); const cards = await fetchSetCards('me3'); expect(cards).toHaveLength(1); expect(cards[0].pricing.tcgplayer.normal.marketPrice).toBe(0.2); expect(fetchMock).toHaveBeenCalledTimes(2); }); });