import { readFileSync } from 'node:fs'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { getConnectorMeta } from '@rareindex/connectors'; import { fixtureDir, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing'; import createConnector, { parseInventoryPage, parseProductPage } from './index.js'; const connector = createConnector(getConnectorMeta('european-watch-company')); const sample = (name: string) => readFileSync(path.join(fixtureDir('european-watch-company'), name), 'utf8'); describe('european-watch-company', () => { runFixtureSuite(connector, it, expect); it('parses inventory cards (title, USD price, badge, image, product url) and dedupes desktop/mobile layouts', () => { const p = parseInventoryPage(sample('inventory-cards.sample.html'), 'https://www.europeanwatch.com/all'); expect(p.cards.length).toBeGreaterThanOrEqual(1); const c = p.cards[0]!; expect(c.id).toBe('71732'); expect(c.title).toBe('Patek Philippe 7010R-013 Nautilus Luce Diamonds 18K Rose Gold Purple Wave Dial'); expect(c.price).toBe(79900); expect(c.currency).toBe('USD'); expect(c.badge).toBe('Sale Pending'); expect(c.href).toBe('https://www.europeanwatch.com/watch/patek-philippe-7010r-013-7010r-013-nautilus-luce-diamonds-18k-ros-71732'); expect(c.image).toBe('https://images.europeanwatch.com/images/71/71732-1.jpg'); expect(new Set(p.cards.map((x) => x.id)).size).toBe(p.cards.length); }); it('parses the product page JSON-LD (sku, mpn = reference, offer)', async () => { const p = parseProductPage(sample('product-jsonld.sample.html'), 'https://www.europeanwatch.com/watch/patek-philippe-7010r-013-7010r-013-nautilus-luce-diamonds-18k-ros-71732'); expect(p?.kind).toBe('product_page'); if (p?.kind !== 'product_page') throw new Error(); expect(p.product.sku).toBe('71732'); expect(p.product.mpn).toBe('7010R-013'); expect(p.product.price).toBe(79900); expect(p.product.currency).toBe('USD'); expect(p.product.availability).toBe('OutOfStock'); expect(p.product.condition).toBe('UsedCondition'); const out = await connector.normalize({ url: p.url, externalId: null, kind: 'listing', engine: 'api', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload: p }); const l = out[0]; if (l?.kind !== 'listing') throw new Error('expected listing'); expect(l.attributes.reference).toBe('7010R-013'); expect(l.attributes.brand).toBe('Patek Philippe'); expect(l.attributes.categorySlug).toBe('patek_philippe'); expect(l.attributes.identifiers).toEqual({ ewc_sku: '71732', reference: '7010R-013' }); expect(l.availability).toBe('ended'); expect(l.price).toBe(79900); }); it('inventory fixture normalises to USD dealer listings with brand-based categories', async () => { const fx = loadFixture('european-watch-company', 'inventory-all'); const out = await connector.normalize(fx.raw); expect(out.length).toBeGreaterThan(5); for (const r of out) { if (r.kind !== 'listing') throw new Error('expected listing'); expect(r.currency).toBe('USD'); expect(r.seller).toBe('European Watch Company'); expect(r.listingType).toBe('fixed_price'); } expect(out.some((r) => r.kind === 'listing' && r.attributes.categorySlug === 'patek_philippe')).toBe(true); const gs = out.find((r) => r.kind === 'listing' && /SBGE201G/.test(r.rawTitle)); expect(gs && gs.kind === 'listing' ? gs.attributes.reference : null).toBe('SBGE201G'); }); });