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.6 KB · 66 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, { parseAuctionPage, 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 = `<h2 class="title-border-risultati">Special Sales</h2> <div class="row "> <div class="col-left-table col-md-2 col-xs-2 tab-risultati-1"> <h3>07.05.2023</h3> </div> <div class="col-md-6 col-xs-4 tab-risultati"> <h3>Torino</h3> </div> <div class="col-md-2 col-xs-2 tab-risultati text-center"> <h3 class="cms-underline"><a href="https://www.astebolaffi.it/it/auction/1204">Catalogo</a> </h3> </div> <div class="col-right-table col-md-2 col-xs-2 tab-risultati-2"> <h3 class="cms-underline"><a href="https://www.astebolaffi.it/it/results/1204">Risultati</a> </h3> </div> </div>16<h2 class="title-border-risultati">Orologi</h2> <div class="row "> <div class="col-left-table col-md-2 col-xs-2 tab-risultati-1"> <h3>12.06.2026</h3> </div> <div class="col-md-6 col-xs-4 tab-risultati"> <h3>Milano</h3> </div> <div class="col-md-2"> <h3 class="cms-underline"><a href="https://www.astebolaffi.it/it/auction/3011">Catalogo</a> </h3> </div> </div>`;1718const AUCTION = `<title> Orologi da polso | Aste Bolaffi </title><script>$("#start_date").text(getLocationDate('2026-06-12 15:00:00'));</script>19<div class="row sezione-news lot-row"> <div class="col col-md-8 col-xs-12 "> <div class="news-left lot-description"> <div class="bg-dettaglio-asta img-wrapper"> <p class="thumb-lot"> <a href="https://www.astebolaffi.it/it/lot/3011/1/detail"> <img src="https://www.astebolaffi.it/storage/lots/3011/1.jpg" style="display: inline;"> </a> </p> </div> <div class="testo-right"> <h5 class="asta-title"> <a href="https://www.astebolaffi.it/it/lot/3011/1/detail">Lotto 1</a> </h5> <p class="lot-dida"> <strong>ROLEX SUBMARINER REF. 5513</strong> <br /> <p><strong>ROLEX SUBMARINER REF. 5513</strong> <br></p><p><em class="em_wide"><strong></strong> <br></em>Acciaio, anni '70, quadrante nero</p> </p> <p> Base asta: <span class="asta-euro">&euro; 5.000</span> <span class="cms-gold">|</span> Aggiudicato a : <span class="asta-euro">&euro; 12.500</span> </p> </div> </div> </div> </div>20<div class="row sezione-news lot-row"> <div class="testo-right"> <h5 class="asta-title"> <a href="https://www.astebolaffi.it/it/lot/3011/2/detail">Lotto 2</a> </h5> <p class="lot-dida"> <strong>OMEGA SPEEDMASTER</strong> <br /> </p> <p> Base asta: <span class="asta-euro">&euro; 2.000</span> </p> </div> </div>21<ul class="pagination"><li><a href="https://www.astebolaffi.it/it/auction/3011?page=2">2</a></li><li><a href="https://www.astebolaffi.it/it/auction/3011?page=9">9</a></li></ul>`;2223describe('aste-bolaffi', () => {24  runFixtureSuite(connector, it, expect);2526  it('fixtures: EUR results ("Aggiudicato a", premium basis unknown)', async () => {27    let sales = 0;28    for (const name of listFixtures('aste-bolaffi')) {29      for (const r of await connector.normalize(loadFixture('aste-bolaffi', name).raw)) {30        if (!('attributes' in r)) continue;31        expect(r.attributes.identifiers.bolaffi_lot).toMatch(/^\d+\/\S+$/);32        expect(r.sourceUrl).toMatch(/^https:\/\/www\.astebolaffi\.it\/it\/lot\/\d+\/\S+\/detail$/);33        if (r.kind === 'sale') {34          sales++;35          expect(r.currency).toBe('EUR');36          expect(r.buyerPremiumIncluded).toBeNull();37          expect(r.auctionHouse).toBe('Aste Bolaffi');38        }39      }40    }41    expect(sales).toBeGreaterThan(5);42  });4344  it('parses the results index (Italian dates, departments) and an auction page (Italian prices, pagination)', async () => {45    const sales = parseResultsIndex(INDEX);46    expect(sales.map((s) => s.id)).toEqual(['1204', '3011']);47    expect(sales[0]).toMatchObject({ date: '2023-05-07T00:00:00.000Z', location: 'Torino, Italy', url: 'https://www.astebolaffi.it/it/auction/1204' });48    expect(sales[0]!.extra.department).toBe('Special Sales');49    expect(sales[1]!.title).toBe('Orologi — Asta 3011');50    const p = parseAuctionPage(AUCTION, sales[1]!, 1)!;51    expect(p.hasMore).toBe(true);52    expect(parseAuctionPage(AUCTION, sales[1]!, 9)!.hasMore).toBe(false);53    expect(p.sale?.date).toBe('2026-06-12T00:00:00.000Z');54    expect(p.lots).toHaveLength(2);55    expect(p.lots[0]).toMatchObject({ lotNo: '1', title: 'ROLEX SUBMARINER REF. 5513', price: 12500, currency: 'EUR', premiumIncluded: null, estimateLow: 5000, sold: true, url: 'https://www.astebolaffi.it/it/lot/3011/1/detail', image: 'https://www.astebolaffi.it/storage/lots/3011/1.jpg' });56    expect(p.lots[0]!.description).toContain("Acciaio, anni '70");57    expect(p.lots[1]).toMatchObject({ lotNo: '2', price: null, sold: false, estimateLow: 2000 });58    const out = await connector.normalize({ url: sales[1]!.url, kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { kind: 'sale_results', url: sales[1]!.url, sale: { ...sales[1]!, ...p.sale, extra: sales[1]!.extra }, page: 1, totalLots: null, lots: p.lots } });59    expect(out.map((r) => r.kind)).toEqual(['sale', 'auction_lot']);60    expect(attrsOf(out[0]!).categorySlug).toBe('rolex');61    expect(attrsOf(out[0]!).reference).toBe('5513');62    expect(attrsOf(out[1]!).categorySlug).toBe('omega');63    expect(parseAuctionPage('<html>x</html>', sales[1]!, 1)).toBeNull();64  });65});66