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%
4.9 KB · 63 lines typescript
Raw Blame History
1import { describe, expect, it } from 'vitest';2import type { NormalizedRecord } from '@rareindex/shared';3import { ConnectorMetaSchema } from '@rareindex/connectors';4import { listFixtures, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';5import metaJson from './meta.json' with { type: 'json' };6import createConnector, { parseLotsPage, parsePastAuctions, parseViewVars } from './index.js';78const meta = ConnectorMetaSchema.parse(metaJson);9const connector = createConnector(meta);10const attrsOf = (r: NormalizedRecord) => {11  if (!('attributes' in r)) throw new Error(`record kind ${r.kind} has no attributes`);12  return r.attributes;13};1415const PAST = `<script type="text/javascript" nonce="x"> viewVars = ${JSON.stringify({ auctions: { result_page: [{ row_id: '4-KD099X', title: 'Modern vs. Classic (Lot 100-402)', auction_type: 'timed_then_live', time_start: '2026-03-13T13:30:00Z', time_start_live_auction: '2026-03-31T12:00:00Z', effective_end_time: '2026-03-31T17:00:00Z', location_name: 'Antwerp, Belgium', lot_count: 298, sold_lot_count: 242, currency_code: 'EUR', _detail_url: '/auctions/4-KD099X/modern-vs-classic-lot-100-402', publication_status: 'full', total_hammer_price: '411000.00', total_sold_value: '407800.00' }], query_info: { page_size: 20, page_start_offset: 0, total_num_results: 319 } } })};</script>`;16const LOTS = `<script> viewVars = ${JSON.stringify({ auction: { row_id: '4-KD099X', title: 'Modern vs. Classic (Lot 100-402)', time_start_live_auction: '2026-03-31T12:00:00Z', effective_end_time: '2026-03-31T17:00:00Z', location_name: 'Antwerp, Belgium', total_hammer_price: '411000.00' }, lots: { result_page: [17  { row_id: '4-KDZAWS', lot_number: 100, title: 'A Shang Dynasty (1600-1100 BC) wine jug, Gu. China.', sold_price: '7000.00', estimate_low: '3000.00', estimate_high: '4000.00', currency_code: 'EUR', status: 'sold', cover_thumbnail: 'https://images4-cdn.auctionmobility.com/x/0100.jpg', _detail_url: '/lots/view/4-KDZAWS/a-shang-dynasty-wine-jug', truncated_description: 'Bronze, H 28 cm.' },18  { row_id: '4-KDZAWT', lot_number: 101, lot_number_extension: 'A', title: 'Rolex Submariner ref. 5513, steel, 1970s', sold_price: null, estimate_low: '8000.00', estimate_high: '12000.00', currency_code: 'EUR', status: 'unsold', _detail_url: '/lots/view/4-KDZAWT/rolex' },19], query_info: { page_size: 36, page_start_offset: 0, total_num_results: 298, next_page: 'https://production4-server.auctionmobility.com/v1/auction/4-KD099X/lots?o=36' } } })};</script>`;2021describe('bernaerts', () => {22  runFixtureSuite(connector, it, expect);2324  it('fixtures: EUR hammer sales from the embedded AuctionMobility JSON', async () => {25    let sales = 0;26    for (const name of listFixtures('bernaerts')) {27      for (const r of await connector.normalize(loadFixture('bernaerts', name).raw)) {28        if (!('attributes' in r)) continue;29        expect(r.attributes.identifiers.bernaerts_lot).toMatch(/^4-[A-Z0-9]+\/\S+$/);30        expect(r.sourceUrl).toMatch(/^https:\/\/live\.bernaerts\.eu\//);31        if (r.kind === 'sale') {32          sales++;33          expect(r.currency).toBe('EUR');34          expect(r.buyerPremiumIncluded).toBe(false);35          expect(r.auctionHouse).toBe('Bernaerts');36        }37      }38    }39    expect(sales).toBeGreaterThan(10);40  });4142  it('parses viewVars, the past-auction list and a lots page (pagination from query_info)', async () => {43    expect(parseViewVars('<p>no</p>')).toBeNull();44    const sales = parsePastAuctions(PAST);45    expect(sales).toHaveLength(1);46    expect(sales[0]).toMatchObject({ id: '4-KD099X', title: 'Modern vs. Classic (Lot 100-402)', url: 'https://live.bernaerts.eu/auctions/4-KD099X/modern-vs-classic-lot-100-402', date: '2026-03-31T12:00:00Z', location: 'Antwerp, Belgium' });47    expect(sales[0]!.extra.total_hammer_price).toBe(411000);48    const p = parseLotsPage(LOTS, sales[0]!)!;49    expect(p.totalLots).toBe(298);50    expect(p.hasMore).toBe(true);51    expect(p.lots).toHaveLength(2);52    expect(p.lots[0]).toMatchObject({ lotNo: '100', price: 7000, currency: 'EUR', premiumIncluded: false, estimateLow: 3000, estimateHigh: 4000, sold: true, url: 'https://live.bernaerts.eu/lots/view/4-KDZAWS/a-shang-dynasty-wine-jug', image: 'https://images4-cdn.auctionmobility.com/x/0100.jpg', description: 'Bronze, H 28 cm.' });53    expect(p.lots[1]).toMatchObject({ lotNo: '101A', price: null, sold: false });54    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: 298, lots: p.lots } });55    expect(out.map((r) => r.kind)).toEqual(['sale', 'auction_lot']);56    expect(attrsOf(out[0]!).categorySlug).toBe('antiques');57    expect(attrsOf(out[1]!).categorySlug).toBe('rolex');58    expect(attrsOf(out[1]!).reference).toBe('5513');59    if (out[0]!.kind === 'sale') expect(out[0]!.saleDate.toISOString()).toBe('2026-03-31T12:00:00.000Z');60    expect(parseLotsPage('<html></html>', sales[0]!)).toBeNull();61  });62});63