deckhearth/test/lib/pricing/foolio-client.test.js

71 lines
1.9 KiB
JavaScript
Raw Normal View History

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);
});
});