SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
3.1 KB · 42 lines typescript
Raw Blame History
1import { describe, expect, it } from 'vitest';2import { getConnectorMeta } from '@rareindex/connectors';3import { listFixtures, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';4import createConnector, { parseLots, parsePastSales } from './index.js';56const connector = createConnector(getConnectorMeta('phillips-watches'));78describe('phillips-watches', () => {9  runFixtureSuite(connector, it, expect);1011  it('maps a sale page to auction sales with buyer premium included', async () => {12    const name = listFixtures('phillips-watches')[0]!;13    const out = await connector.normalize(loadFixture('phillips-watches', name).raw);14    const sales = out.filter((r) => r.kind === 'sale');15    expect(sales.length).toBeGreaterThan(10);16    const s = sales[0];17    if (s?.kind !== 'sale') throw new Error();18    expect(s.saleType).toBe('auction');19    expect(s.auctionHouse).toBe('Phillips');20    expect(s.buyerPremiumIncluded).toBe(true);21    expect(['CHF', 'USD', 'HKD', 'GBP', 'EUR']).toContain(s.currency);22    expect(s.attributes.brand).toBeTruthy();23    expect(s.lotNumber).toMatch(/^\d+/);24    const rolex = sales.find((r) => r.kind === 'sale' && r.attributes.categorySlug === 'rolex');25    if (rolex?.kind === 'sale') expect(rolex.attributes.reference).toBeTruthy();26  });2728  it('parses markdown lot cards', () => {29    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)`;30    const lots = parseLots(md);31    expect(lots).toHaveLength(2);32    expect(lots[0]).toMatchObject({ lotNumber: '4', maker: 'Rolex', reference: '116509', model: 'Cosmograph Daytona', estimateLow: 25000, estimateHigh: 50000, soldFor: 48260, currency: 'CHF', noReserve: true });33    expect(lots[1]).toMatchObject({ lotNumber: '5', maker: 'Patek Philippe', reference: '5320G-001', soldFor: null, estimateLow: 40000 });34  });3536  it('extracts past watch sales from the embedded JSON', () => {37    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"}`;38    const sales = parsePastSales(html, 'watch');39    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' }]);40  });41});42