import { describe, expect, it } from 'vitest'; import type { NormalizedRecord } from '@rareindex/shared'; import { ConnectorMetaSchema } from '@rareindex/connectors'; import { listFixtures, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing'; import metaJson from './meta.json' with { type: 'json' }; import createConnector, { backfillYears } from './index.js'; import { parseDrouotCatalogue, parseDrouotIndex, premiumFromNote } from '../_g8-auctions-eu-apac-lib/drouot-platform.js'; const meta = ConnectorMetaSchema.parse(metaJson); const connector = createConnector(meta); const attrsOf = (r: NormalizedRecord) => { if (!('attributes' in r)) throw new Error(`record kind ${r.kind} has no attributes`); return r.attributes; }; const HOUSE = { base: 'https://www.ader-paris.fr', currency: 'EUR' as const }; const INDEX = `

Art militaire et décorations

jeudi 23 juillet 2026 à 20h00
Art d’après-guerre et contemporain

Art d’après-guerre et contemporain

jeudi 09 juillet 2026 à 14h00
Salle 6 - Hôtel Drouot , 9, rue Drouot 75009 Paris
`; const CATALOGUE = `

Art d’après-guerre et contemporain

jeudi 09 juillet 2026 14:00
Salle 6 - Hôtel Drouot , 9, rue Drouot 75009 Paris
Lots 1 à 50 sur 230
Georges HUGNET...
Résultat : 593 EUR
Lot nº1
Estimation :
150 - 200 EUR
Résultat 593 EUR
Résultats avec frais
2
8 000 - 12 000 EUR
2
`; describe('ader', () => { runFixtureSuite(connector, it, expect); it('fixtures: EUR results labelled from the page note (Ader = avec frais)', async () => { let sales = 0; for (const name of listFixtures('ader')) { for (const r of await connector.normalize(loadFixture('ader', name).raw)) { if (!('attributes' in r)) continue; expect(r.attributes.identifiers.ader_lot).toMatch(/^\d+\/\S+$/); expect(r.sourceUrl).toMatch(/^https:\/\/www\.ader-paris\.fr\//); if (r.kind === 'sale') { sales++; expect(r.currency).toBe('EUR'); expect(r.buyerPremiumIncluded).toBe(true); expect(r.auctionHouse).toBe('Ader'); } } } expect(sales).toBeGreaterThan(10); }); it('parses the Drouot-platform index (skips sales without catalogue) and a catalogue page', async () => { const sales = parseDrouotIndex(INDEX, HOUSE); expect(sales).toHaveLength(1); expect(sales[0]).toMatchObject({ id: '182770', title: 'Art d’après-guerre et contemporain', url: 'https://www.ader-paris.fr/catalogue/182770-art-dapres-guerre-et-contemporain', date: '2026-07-09T00:00:00.000Z', location: 'Salle 6 - Hôtel Drouot, 9, rue Drouot 75009 Paris' }); const p = parseDrouotCatalogue(CATALOGUE, sales[0]!, HOUSE)!; expect(p.totalLots).toBe(230); expect(p.hasMore).toBe(true); expect(p.sale?.date).toBe('2026-07-09T00:00:00.000Z'); expect(p.lots).toHaveLength(2); expect(p.lots[0]).toMatchObject({ lotNo: '1', title: 'Georges HUGNET (1906-1974) et André BEAUDIN (1904-1974) Composition, collage, 1955', price: 593, currency: 'EUR', premiumIncluded: true, estimateLow: 150, estimateHigh: 200, sold: true, url: 'https://www.ader-paris.fr/lot/182770/34329776-georges-hugnet', image: 'https://cdn.drouot.com/d/image/lot?size=phare&path=97/182770/7672' }); expect(p.lots[0]!.description).toBeNull(); expect(p.lots[1]).toMatchObject({ lotNo: '2', price: null, sold: false, estimateLow: 8000, estimateHigh: 12000, premiumIncluded: true }); Object.assign(sales[0]!, p.sale, { extra: { ...sales[0]!.extra, ...p.sale!.extra } }); const out = await connector.normalize({ url: sales[0]!.url, kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { kind: 'sale_results', url: sales[0]!.url, sale: sales[0]!, page: 1, totalLots: 230, lots: p.lots } }); expect(out.map((r) => r.kind)).toEqual(['sale', 'auction_lot']); expect(attrsOf(out[0]!).categorySlug).toBe('contemporary_art'); expect(attrsOf(out[1]!).categorySlug).toBe('rolex'); expect(attrsOf(out[1]!).reference).toBe('5513'); expect(connector.salePageUrl(sales[0]!, 2)).toBe('https://www.ader-paris.fr/catalogue/182770?lang=fr&search=&offset=50&max=50'); expect(parseDrouotCatalogue('rien', sales[0]!, HOUSE)).toBeNull(); }); it('premium notes and backfill years', () => { expect(premiumFromNote('Résultats avec frais')).toBe(true); expect(premiumFromNote('Résultats sans frais')).toBe(false); expect(premiumFromNote(null)).toBeNull(); expect(premiumFromNote('Résultats')).toBeNull(); expect(backfillYears(2024)[0]).toBe(2024); expect(backfillYears(2024).at(-1)).toBe(new Date().getUTCFullYear()); }); });