import { beforeEach, describe, expect, it, vi } from 'vitest'; import { buildFolioPriceIndex, getFolioFeedUrl, matchFolioPrice, parseFolioPriceEntry, } from '../../../lib/pricing/foolio-client.js'; describe('foolio-client', () => { beforeEach(() => { delete process.env.FOILIO_PRICES_FEED_URL; vi.restoreAllMocks(); }); it('uses default Foilio feed URL', () => { expect(getFolioFeedUrl()).toBe('https://foolio.net/api/prices/feed?game=lorcana'); }); it('prefers USD fields when parsing feed rows', () => { expect(parseFolioPriceEntry({ usd_low: 1, usd_market: 2 })).toEqual({ currentPrice: 1, marketPrice: 2, currency: 'USD', }); }); it('falls back to EUR with currency noted when USD is absent', () => { expect(parseFolioPriceEntry({ eur_low: 0.5, eur_market: 0.8 })).toEqual({ currentPrice: 0.5, marketPrice: 0.8, currency: 'EUR', }); }); it('indexes feed rows by card id and normalized name|set', () => { const index = buildFolioPriceIndex([ { card_id: 'TFC-001', name: 'Ariel - On Human Legs', set: 'TFC', usd_low: 1, usd_market: 1.5, }, ]); expect(index.byCardId.get('TFC-001')?.marketPrice).toBe(1.5); expect( matchFolioPrice(index, { scryfallId: 'OTHER', name: 'Ariel - On Human Legs', setCode: 'TFC', })?.currentPrice ).toBe(1); }); it('fetchFolioPriceFeed loads and indexes the feed once', async () => { const payload = [{ card_id: 'TFC-001', usd_market: 3 }]; vi.stubGlobal('fetch', vi.fn(async () => ({ ok: true, json: async () => payload, }))); const { fetchFolioPriceIndex } = await import('../../../lib/pricing/foolio-client.js'); const index = await fetchFolioPriceIndex(); expect(index.byCardId.get('TFC-001')?.marketPrice).toBe(3); expect(fetch).toHaveBeenCalledTimes(1); }); });