import { describe, expect, it } from 'vitest'; import { getConnectorMeta } from '@rareindex/connectors'; import { listFixtures, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing'; import createConnector, { parseLots, parsePastSales } from './index.js'; const connector = createConnector(getConnectorMeta('phillips-watches')); describe('phillips-watches', () => { runFixtureSuite(connector, it, expect); it('maps a sale page to auction sales with buyer premium included', async () => { const name = listFixtures('phillips-watches')[0]!; const out = await connector.normalize(loadFixture('phillips-watches', name).raw); const sales = out.filter((r) => r.kind === 'sale'); expect(sales.length).toBeGreaterThan(10); const s = sales[0]; if (s?.kind !== 'sale') throw new Error(); expect(s.saleType).toBe('auction'); expect(s.auctionHouse).toBe('Phillips'); expect(s.buyerPremiumIncluded).toBe(true); expect(['CHF', 'USD', 'HKD', 'GBP', 'EUR']).toContain(s.currency); expect(s.attributes.brand).toBeTruthy(); expect(s.lotNumber).toMatch(/^\d+/); const rolex = sales.find((r) => r.kind === 'sale' && r.attributes.categorySlug === 'rolex'); if (rolex?.kind === 'sale') expect(rolex.attributes.reference).toBeTruthy(); }); it('parses markdown lot cards', () => { const md = `## 2 Lots\n\n[![Brought to you by Phillips](https://dist.phillips.com/auction-assets/CH080125/214153_001.jpg?fit=cover&width=928)\\\\\nNo Reserve\\\\\n4\\\\\n\\\\\nRolex\\\\\nRef. 116509\\\\\nCosmograph Daytona\\\\\n\\\\\nEstimate\\\\\n\\\\\nCHF25,000–50,000\\\\\n\\\\\nSold For\\\\\n\\\\\nCHF48,260](https://www.phillips.com/detail/rolex/214153)\n\n[![Brought to you by Phillips](https://dist.phillips.com/x.jpg)\\\\\n\\\\\n5\\\\\n\\\\\nPatek Philippe\\\\\nRef. 5320G-001\\\\\n\\\\\nEstimate\\\\\n\\\\\nCHF40,000–80,000](https://www.phillips.com/detail/patek-philippe/214809)`; const lots = parseLots(md); expect(lots).toHaveLength(2); expect(lots[0]).toMatchObject({ lotNumber: '4', maker: 'Rolex', reference: '116509', model: 'Cosmograph Daytona', estimateLow: 25000, estimateHigh: 50000, soldFor: 48260, currency: 'CHF', noReserve: true }); expect(lots[1]).toMatchObject({ lotNumber: '5', maker: 'Patek Philippe', reference: '5320G-001', soldFor: null, estimateLow: 40000 }); }); it('extracts past watch sales from the embedded JSON', () => { const html = `x{"a":1,"departments":[{"departmentID":12,"departmentName":"Watches"}],"locationName":"GENEVA","startDateTimeOffset":"2025-03-05T12:00:00+01:00","endDateTimeOffset":"2025-03-12T16:00:00+01:00","saleNumber":"CH080125","auctionTitle":"Phillips Watches Online Auction: The Geneva Sessions Spring 2025"}y{"departments":[{"departmentName":"Contemporary"}],"saleNumber":"NY011126","auctionTitle":"Modern & Contemporary Art: Online Auction, New York"}`; const sales = parsePastSales(html, 'watch'); expect(sales).toEqual([{ saleNumber: 'CH080125', title: 'Phillips Watches Online Auction: The Geneva Sessions Spring 2025', location: 'GENEVA', startDate: '2025-03-05T12:00:00+01:00', endDate: '2025-03-12T16:00:00+01:00' }]); }); });