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.0 KB · 57 lines typescript
Raw Blame History
1import { describe, expect, it } from 'vitest';2import { readFileSync } from 'node:fs';3import path from 'node:path';4import { fileURLToPath } from 'node:url';5import { ConnectorMetaSchema } from '@rareindex/connectors';6import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';7import createConnector, { parseCatalogPage, parsePastAuctions, swannCategory } from './index.js';89const dir = path.dirname(fileURLToPath(import.meta.url));10const meta = ConnectorMetaSchema.parse(JSON.parse(readFileSync(path.join(dir, 'meta.json'), 'utf8')));11const connector = createConnector(meta);1213const LIST = `<div class="event__content"><div class="event__date">Thursday, November 6, 2025</div><h2 class="event__title">Autographs</h2>14<div class="event__department"><a href="https://www.swanngalleries.com/books-manuscripts/autographs/">Autographs</a> - Sale 2719</div>15<ul><li><a class="btn btn-primary btn-cta--view_lots" href="https://www.swanngalleries.com/auction-catalog/autographs_JCJOCA54V5">View Lots</a></li></ul></div>`;1617const CATALOG = `<div data-lot-ref="C337D422B9"><a href="https://www.swanngalleries.com/auction-lot/marlon-brando_c337d422b9"><img src="https://image.invaluable.com/h.jpg"/></a>18<p class="lot-card_card-title__EEZRj">2<!-- -->: <!-- -->Marlon Brando Slip of paper Signed and Inscribed. Np, nd.</p>19<div class="lot-card_estimate-bid__8g2bA"><span>Estimate<!-- -->: </span><span>$600 - $900</span></div>20<div><div class="lot-card_bid-amount__Xp4jF"><strong class="lot-card_amount__WX83V"><span>Sold<!-- -->:</span><span>$1,188</span></strong></div><span>Sold price includes buyer's premium</span></div></div>21<div data-lot-ref="C3359DB2B8"><a href="https://www.swanngalleries.com/auction-lot/tony-bennett_c3359db2b8"><img src="https://image.invaluable.com/t.jpg"/></a>22<p class="lot-card_card-title__EEZRj">1<!-- -->: <!-- -->Tony Bennett. Group of 5 photographs.</p>23<div class="lot-card_estimate-bid__8g2bA"><span>Estimate: </span><span>$600 - $900</span></div><div><span>Passed</span></div></div>`;2425describe('swann', () => {26  runFixtureSuite(connector, it, expect);2728  it('parses the past-auction list and catalog cards', () => {29    const auctions = parsePastAuctions(LIST);30    expect(auctions).toEqual([{ slug: 'autographs_JCJOCA54V5', url: 'https://www.swanngalleries.com/auction-catalog/autographs_JCJOCA54V5', title: 'Autographs', dateText: 'Thursday, November 6, 2025', department: 'Autographs', saleNumber: '2719' }]);31    const page = parseCatalogPage(CATALOG, auctions[0]!, 1);32    expect(page.lots.length).toBe(2);33    expect(page.lots[0]).toMatchObject({ ref: 'C337D422B9', lotNumber: '2', soldText: '$1,188', premiumNote: true, passed: false, estimateText: '$600 - $900' });34    expect(page.lots[1]).toMatchObject({ lotNumber: '1', soldText: null, passed: true });35  });3637  it('normalises sold lots only, premium included, dated by the sale', async () => {38    const auction = parsePastAuctions(LIST)[0]!;39    const out = await connector.normalize({ url: 'x', externalId: 's', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-07T00:00:00Z'), payload: parseCatalogPage(CATALOG, auction, 1) });40    expect(out.length).toBe(1);41    const s = out[0]!;42    if (s.kind !== 'sale') throw new Error('sale');43    expect(s).toMatchObject({ price: 1188, currency: 'USD', buyerPremiumIncluded: true, lotNumber: '2', auctionHouse: 'Swann Auction Galleries' });44    expect(s.saleDate.toISOString()).toBe('2025-11-06T00:00:00.000Z');45    expect(s.attributes.categorySlug).toBe('autographs');46    expect(swannCategory('Photographs & Photobooks', 'Photographs', 'Ansel Adams')).toBe('photography');47    expect(swannCategory('Vintage Posters', 'Posters', 'Casablanca one sheet')).toBe('movie_posters');48    expect(swannCategory('Maps & Atlases', 'Maps', 'Blaeu, Americae')).toBe('maps');49  });5051  it('fixture sales are USD with lot refs', async () => {52    const out = await connector.normalize(loadFixture('swann', 'catalog-page').raw);53    expect(out.length).toBeGreaterThan(0);54    for (const r of out) if (r.kind === 'sale') expect(r.attributes.identifiers.swann_lot_ref).toBeTruthy();55  });56});57