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, { parseLotsJson, parseSaleId, parseSalePageHeader, parseSitemapSales } from './index.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 SITEMAP = `
A PAIR OF ROMAN EARRINGS
CIRCA 3RD CENTURY AD
gold with garnets
Minor wear.
' }, { Id: 538257, LotNumber: '2', Title: 'A ROLEX OYSTER PERPETUAL DATEJUST REF. 1601', FullDescription: 'steel, 1972
', HammerPrice: null, HammerPriceFormatted: '', LowerEstimate: 2000, UpperEstimate: 3000, ViewUrl: '/departments/x/tr200826/view-lot/2/' }, ] }; describe('woolley-wallis', () => { runFixtureSuite(connector, it, expect); it('fixtures: GBP hammer prices from the public lot-search API', async () => { let sales = 0; for (const name of listFixtures('woolley-wallis')) { for (const r of await connector.normalize(loadFixture('woolley-wallis', name).raw)) { if (!('attributes' in r)) continue; expect(r.attributes.identifiers.woolley_wallis_lot).toMatch(/^[a-z0-9-]+\/\S+$/); expect(r.sourceUrl).toMatch(/^https:\/\/www\.woolleyandwallis\.co\.uk\/departments\//); if (r.kind === 'sale') { sales++; expect(r.currency).toBe('GBP'); expect(r.buyerPremiumIncluded).toBe(false); expect(r.auctionHouse).toBe('Woolley & Wallis'); } } } expect(sales).toBeGreaterThan(10); }); it('enumerates sales from the sitemap and reads sale-id / header from HTML', () => { const sales = parseSitemapSales(SITEMAP); expect(sales.map((s) => s.id)).toEqual(['pg010306', 'tr200826']); expect(sales[1]!.extra.department).toBe('african oceanic art'); expect(parseSaleId('none
')).toBeNull(); expect(parseSalePageHeader('20th August 2026. Starts at 10:00am
')).toEqual({ title: 'Arts of Africa, Oceania and the Americas', date: '2026-08-20T00:00:00.000Z' }); }); it('parses the lot-search JSON (HammerPrice = hammer, TotalPages pagination)', async () => { const sale = { id: 'tr200826', title: 'Arts of Africa', url: 'https://www.woolleyandwallis.co.uk/departments/african-oceanic-art/tr200826/', date: '2026-08-20T00:00:00.000Z', location: 'Salisbury, United Kingdom', extra: { sale_id: '37594' } }; const p = parseLotsJson(API, sale, 0)!; expect(p.totalLots).toBe(328); expect(p.hasMore).toBe(true); expect(parseLotsJson(API, sale, 3)!.hasMore).toBe(false); expect(p.lots[0]).toMatchObject({ lotNo: '1', title: 'A PAIR OF ROMAN EARRINGS', price: 952.5, currency: 'GBP', premiumIncluded: false, estimateLow: 800, estimateHigh: 1200, sold: true, image: 'https://dp0wuijufr9x2.cloudfront.net/ww/TR200826/1.jpg?v=6', url: 'https://www.woolleyandwallis.co.uk/departments/african-oceanic-art/tr200826/view-lot/1/' }); expect(p.lots[0]!.description).toBe('A PAIR OF ROMAN EARRINGS CIRCA 3RD CENTURY AD gold with garnets'); expect(p.lots[1]).toMatchObject({ lotNo: '2', price: null, sold: false }); const out = await connector.normalize({ url: sale.url, kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { kind: 'sale_results', url: sale.url, sale, page: 1, totalLots: 328, lots: p.lots } }); expect(out.map((r) => r.kind)).toEqual(['sale', 'auction_lot']); expect(attrsOf(out[0]!).categorySlug).toBe('jewelry'); expect(attrsOf(out[1]!).categorySlug).toBe('rolex'); expect(attrsOf(out[1]!).reference).toBe('1601'); expect(connector.salePageUrl(sale, 2)).toBe('https://www.woolleyandwallis.co.uk/api/lots/search?pageIndex=1&filter=&saleId=37594&pageSize=100'); expect(parseLotsJson({ nope: 1 }, sale, 0)).toBeNull(); }); });