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%
5.9 KB · 74 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, { lotsFromJson, parseResultDetail, parseResultsIndex } 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 INDEX = `<div class="col-6 col-md-4 col-lg-3"><div class="catalogue-result-item"><div class="catalogue-result-item-img"><a href="/de/auktionen/ergebnisse/detail/1296-1-african-and-oceanic-art.html"><picture></picture></a></div><div class="catalogue-result-item-info"><div class="catalogue-result-item-info-auction">Auktion 1296</div><div class="catalogue-result-item-info-title"><a href="/de/auktionen/ergebnisse/detail/1296-1-african-and-oceanic-art.html"><h3>African and Oceanic Art</h3></a></div><div class="catalogue-result-item-info-date-location"><div><span class="catalogue-result-item-info-date-date">01.07.2026 14:00</span><span class="catalogue-result-item-info-date-location">, Brussels</span></div></div></div></div></div>16<div class="col-6"><div class="catalogue-result-item"><a href="/de/auktionen/ergebnisse/detail/1293-1-asiatische-kunst.html"></a><div class="catalogue-result-item-info-auction">Auktion 1293</div><h3>Asiatische Kunst</h3><span class="catalogue-result-item-info-date-date">12.06.2026 10:00</span><span class="catalogue-result-item-info-date-location">, Köln</span></div></div>`;1718const DETAIL = `<div class="catalogue-info"><span>27.11.2015, 18:00</span><span>|</span><span>Moderne Kunst</span><span>|</span><span>Köln</span></div><h1 class="catalogue-detail-title">Auktionsergebnisse zu Auktion 1059 - Moderne Kunst</h1><div id="catalogue-result-detail" catalogue_uid="245" catalogue_type="resultList" language="1" v-cloak><p>Alle Ergebnisse beinhalten den Zuschlagspreis und das Aufgeld (ohne Gewähr).</p></div>`;1920const JSON_LOTS = { lots: [21  { uid: 125134, number: 301, position: '', state: 'Z', hammerprice: 74400, hammerprice_type: 'B', estimate: 60000, estimate_to: 80000, title: 'Raoul Dufy', subtitle: "Le funiculaire à L'Estaque", description: 'Öl auf Leinwand 1908', link: 'https://www.lempertz.com/de/kataloge/lot/1059-1/301-raoul-dufy.html' },22  { uid: 125272, number: 300, position: '', state: 'K', hammerprice: 0, estimate: 90000, estimate_to: 110000, title: 'Kees van Dongen', subtitle: 'Femme nue au lierre', link: '/de/kataloge/lot/1059-1/300-kees-van-dongen.html' },23  { uid: 1, number: 12, position: 'A', state: 'V', hammerprice: 1200, estimate: 800, estimate_to: 1200, title: 'Rolex', subtitle: 'Datejust Ref. 16233, Stahl/Gold', link: '/x.html' },24] };2526describe('lempertz', () => {27  runFixtureSuite(connector, it, expect);2829  it('fixtures: premium-inclusive EUR sales, unsold → auction_lot', async () => {30    let sales = 0;31    let lots = 0;32    for (const name of listFixtures('lempertz')) {33      for (const r of await connector.normalize(loadFixture('lempertz', name).raw)) {34        if (r.kind === 'sale') {35          sales++;36          expect(r.currency).toBe('EUR');37          expect(r.buyerPremiumIncluded).toBe(true);38          expect(r.auctionHouse).toBe('Lempertz');39          expect(r.attributes.identifiers.lempertz_lot).toMatch(/^\d+-\d+-.+\/\S+$/);40          expect(r.sourceUrl).toMatch(/^https:\/\/www\.lempertz\.com\//);41        } else if (r.kind === 'auction_lot') lots++;42      }43    }44    expect(sales).toBeGreaterThan(20);45    expect(lots).toBeGreaterThanOrEqual(0);46  });4748  it('parses the results index (German dates, city)', () => {49    const sales = parseResultsIndex(INDEX);50    expect(sales).toHaveLength(2);51    expect(sales[0]).toMatchObject({ id: '1296-1-african-and-oceanic-art', title: 'African and Oceanic Art', url: 'https://www.lempertz.com/de/auktionen/ergebnisse/detail/1296-1-african-and-oceanic-art.html', date: '2026-07-01T00:00:00.000Z', location: 'Brussels' });52    expect(sales[0]!.extra.auction_no).toBe('1296');53    expect(sales[1]!.date).toBe('2026-06-12T00:00:00.000Z');54  });5556  it('parses the detail page header and the JSON lots', async () => {57    const d = parseResultDetail(DETAIL);58    expect(d).toMatchObject({ catalogueUid: '245', language: 'de', dateText: '27.11.2015, 18:00', location: 'Köln', premiumNote: true });59    const sale = { id: '1059-1-moderne-kunst', title: 'Moderne Kunst', url: 'https://www.lempertz.com/de/auktionen/ergebnisse/detail/1059-1-moderne-kunst.html', date: '2015-11-27T00:00:00.000Z', location: 'Köln', extra: {} };60    const lots = lotsFromJson(JSON_LOTS, sale);61    expect(lots).toHaveLength(3);62    expect(lots[0]).toMatchObject({ lotNo: '301', title: 'Raoul Dufy', subtitle: "Le funiculaire à L'Estaque", price: 74400, currency: 'EUR', premiumIncluded: true, estimateLow: 60000, estimateHigh: 80000, sold: true });63    expect(lots[1]).toMatchObject({ lotNo: '300', price: null, sold: false, url: 'https://www.lempertz.com/de/kataloge/lot/1059-1/300-kees-van-dongen.html' });64    expect(lots[2]).toMatchObject({ lotNo: '12A', extra: { under_reserve: true } });65    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: 3, lots } });66    expect(out.map((r) => r.kind)).toEqual(['sale', 'auction_lot', 'sale']);67    expect(attrsOf(out[0]!).categorySlug).toBe('contemporary_art');68    expect(attrsOf(out[2]!).categorySlug).toBe('rolex');69    expect(attrsOf(out[2]!).reference).toBe('16233');70    if (out[0]!.kind === 'sale') expect(out[0]!.saleDate.toISOString()).toBe('2015-11-27T00:00:00.000Z');71    expect(lotsFromJson({ error: true }, sale)).toEqual([]);72  });73});74