TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import { getConnectorMeta } from '@rareindex/connectors';3import { loadFixture, listFixtures, runFixtureSuite } from '@rareindex/connectors/testing';4import createConnector, { languageFromSetCode } from './index.js';56const connector = createConnector(getConnectorMeta('ygoprodeck'));78describe('ygoprodeck', () => {9 runFixtureSuite(connector, it, expect);1011 it('emits one catalog item per printing with set code / rarity / language', async () => {12 const name = listFixtures('ygoprodeck').find((n) => n === '46986414') ?? listFixtures('ygoprodeck')[0]!; // Dark Magician13 const fx = loadFixture('ygoprodeck', name);14 const out = await connector.normalize(fx.raw);15 const cats = out.filter((r) => r.kind === 'catalog_item');16 const payload = fx.raw.payload as { card: { card_sets: Array<{ set_code: string; set_rarity?: string }>; id: number } };17 const distinct = new Set(payload.card.card_sets.map((s) => `${s.set_code}|${s.set_rarity ?? ''}`)).size;18 expect(cats).toHaveLength(distinct);19 const first = cats[0]!;20 if (first.kind !== 'catalog_item') throw new Error('kind');21 expect(first.attributes.categorySlug).toBe('yugioh');22 expect(first.attributes.identifiers.ygo_id).toBe(String(payload.card.id));23 expect(first.attributes.identifiers.konami_id).toBeTruthy();24 expect(first.attributes.number).toMatch(/^[A-Z0-9]+-[A-Z]*\d+/);25 expect(first.attributes.setCode).toBe(first.attributes.number!.split('-')[0]);26 expect(first.attributes.year).toBeNull(); // per-printing year unknown → never guessed27 // unique external ids per printing28 expect(new Set(cats.map((c) => c.kind === 'catalog_item' && c.externalId)).size).toBe(cats.length);29 });3031 it('records set_price per printing and card-level prices once', async () => {32 const fx = loadFixture('ygoprodeck', listFixtures('ygoprodeck')[0]!);33 const out = await connector.normalize(fx.raw);34 const obs = out.filter((r) => r.kind === 'price_observation');35 const printingLevel = obs.filter((o) => o.kind === 'price_observation' && o.attributes.metadata.price_scope === 'printing');36 const cardLevel = obs.filter((o) => o.kind === 'price_observation' && o.attributes.metadata.price_scope === 'card');37 expect(printingLevel.length).toBeGreaterThan(0);38 expect(cardLevel.length).toBeGreaterThan(0);39 expect(cardLevel.length).toBeLessThanOrEqual(5);40 for (const o of printingLevel) if (o.kind === 'price_observation') expect(o.priceKind).toBe('guide_value');41 const eur = cardLevel.find((o) => o.kind === 'price_observation' && o.currency === 'EUR');42 expect(eur && eur.kind === 'price_observation' ? eur.attributes.metadata.priceSource : '').toBe('cardmarket');43 });4445 it('derives language from set codes', () => {46 expect(languageFromSetCode('LOB-EN001')).toBe('English');47 expect(languageFromSetCode('LOB-FR001')).toBe('French');48 expect(languageFromSetCode('LOB-001')).toBeNull();49 });50});51