import { describe, expect, it } from 'vitest'; import { readFileSync } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing'; import { localMeta } from '../_lib/local-meta.js'; import createConnector, { parseLotLinks, parseLotPage, parseSalesDropdown, spinkDepartment } from './index.js'; import { parseCoinGrade } from '../../firecrawl/_g5-numismatics-lib/index.js'; const dir = path.dirname(fileURLToPath(import.meta.url)); const connector = createConnector(localMeta(JSON.parse(readFileSync(path.join(dir, 'meta.json'), 'utf8')))); const DROPDOWN = ``; const LIST = `
# 1 - NGC Choice VF | Gaul »
# 338 - Edward VII »
2`; const LOT = `Auction: 25005 - The Carrington and Pallas Collections of Exceptional English and Anglo-Gallic Gold Coins and Proof Sets
Lot: 338

(g) Edward VII (1901-1910), Coronation Matte Proof 'Short' Set, 1902, Sovereign to Sixpence (S.PS12), including NGC PF64 MATTE | Matte Proof Crown, 1902, in NGC holder (Cert. #8464067-021); much as issued (11)

Subject to 20% VAT on Buyer’s Premium. For more information please view Terms and Conditions for Buyers.

Sold for
£1,900

Starting price
£1600

`; const UNSOLD = LOT.replace(/

Sold for[\s\S]*?<\/p>/, ''); describe('spink', () => { runFixtureSuite(connector, it, expect); it('parses the sales dropdown, classifies departments and extracts lot links', () => { const sales = parseSalesDropdown(DROPDOWN); expect(sales.length).toBe(4); expect(sales[2]).toEqual({ code: '25005', title: 'The Carrington and Pallas Collections of Exceptional English and Anglo-Gallic Gold Coins and Proof Sets', dateText: '30 Sept 2025' }); expect(sales[3]!.dateText).toBe('11 Dec 2002'); expect(spinkDepartment('Boozing with Spirits - e-Auction')).toBeNull(); expect(spinkDepartment('World & British Banknotes - e-Auction')).toBe('banknotes'); expect(spinkDepartment('Stamps - Rhodesia Double Head & Admiral Issues')).toBe('stamps'); expect(spinkDepartment('Orders, Decorations and Medals')).toBe('medals'); expect(spinkDepartment(sales[2]!.title)).toBe('coins'); expect(parseLotLinks(LIST, '25005')).toEqual(['https://www.spink.com/lot/25005000001', 'https://www.spink.com/lot/25005000338']); }); it('parses a lot page and normalises "Sold for" with premium unknown; unsold pages yield nothing', async () => { const sale = { code: '25005', title: 'x', dateText: '30 Sept 2025' }; const p = parseLotPage(LOT, 'https://www.spink.com/lot/25005000338', sale)!; expect(p).toMatchObject({ lotNumber: '338', headline: 'Edward VII', soldText: '£1,900', startingText: '£1600' }); expect(p.sale.title).toMatch(/^The Carrington/); expect(p.description).not.toMatch(/VAT/); expect(p.images).toEqual(['https://d3ums4016ncdkp.cloudfront.net/auction/main/25005/25005_338_1.jpg', 'https://d3ums4016ncdkp.cloudfront.net/auction/main/25005/25005_338_2.jpg']); const out = await connector.normalize({ url: p.url, externalId: '25005000338', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload: p }); expect(out.length).toBe(1); const s = out[0]!; if (s.kind !== 'sale') throw new Error('sale'); expect(s).toMatchObject({ price: 1900, currency: 'GBP', buyerPremiumIncluded: null, lotNumber: '338', auctionHouse: 'Spink', isBundle: true, location: 'GB' }); expect(s.saleDate.toISOString()).toBe('2025-09-30T00:00:00.000Z'); expect(s.grade).toMatchObject({ grader: 'ngc', grade: 'PF64', certificationNumber: '8464067-021' }); expect(s.attributes).toMatchObject({ categorySlug: 'coins', year: 1902, country: 'GB' }); expect(s.attributes.identifiers).toEqual({ spink_lot: '25005-338', ngc_cert: '8464067-021' }); expect(s.attributes.metadata).toMatchObject({ starting_price: 1600, spink_reference: 'S.PS12' }); expect(await connector.normalize({ url: p.url, externalId: 'u', kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: parseLotPage(UNSOLD, p.url, sale) })).toEqual([]); }); it('parses adjectival NGC Ancients grades and HK$ prices', () => { expect(parseCoinGrade('NGC Choice VF | Gaul, Aulerci Eburovices, Electrum Hemistater')).toMatchObject({ grader: 'ngc', grade: 'Choice VF' }); expect(parseCoinGrade('NGC Ch XF Strike 5/5 Surface 4/5 Athens tetradrachm')).toMatchObject({ grader: 'ngc', grade: 'Choice XF' }); }); it('fixtures: coins, ancients and banknotes lots normalise to GBP sales', async () => { for (const name of ['lot-25005-338-proof-set', 'lot-25005-1-celtic-ngc', 'lot-26300-10-banknotes']) { const out = await connector.normalize(loadFixture('spink', name).raw); expect(out.length).toBe(1); if (out[0]!.kind === 'sale') expect(out[0]).toMatchObject({ currency: 'GBP', buyerPremiumIncluded: null, auctionHouse: 'Spink' }); } const notes = await connector.normalize(loadFixture('spink', 'lot-26300-10-banknotes').raw); if (notes[0]!.kind === 'sale') expect(notes[0]!.attributes.categorySlug).toBe('banknotes'); }); });