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%
7.7 KB · 84 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 { runFixtureSuite } from '@rareindex/connectors/testing';6import { localMeta } from '../_lib/local-meta.js';7import { monthYearDate } from '../_g7-auctions-na-lib/index.js';8import createConnector, { cleanSweepCategory, isBundle, monthKey, parseLotPage, parseMonthPage, parsePastIndex } from './index.js';910const dir = path.dirname(fileURLToPath(import.meta.url));11const meta = localMeta(JSON.parse(readFileSync(path.join(dir, 'meta.json'), 'utf8')));12const connector = createConnector(meta);1314// Real fragments captured live from www.cleansweepauctions.com on 2026-09-08.15const INDEX = `<div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <a href="/past-auctions/may-2025"> <img src="http://marketplace.cleansweepauctions.com/images/main/entertainmentlot705986.jpg" alt="May 2025" /> </a> </div> <a href="/past-auctions/may-2025"> May 2025 </a> </div> </div>16<div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <a href="/past-auctions/april-2025"> <img src="http://marketplace.cleansweepauctions.com/images/main/flick678144b.jpg" alt="April 2025" /> </a> </div> <a href="/past-auctions/april-2025"> April 2025 </a> </div> </div>17<div class="col-md-3"> <div class="auction-list-item"> <a href="/past-auctions/december-2025"> December 2025 </a> </div> </div>18<div class="col-md-3"> <div class="auction-list-item"> <a href="/past-auctions/april-2008"> April 2008 </a> </div> </div>19<a href="/past-auctions">Past Auctions</a>`;2021const MONTH_PAGE = `<h1 style="font-weight:600;">April 2025</h1>22<div class="row"> <div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <img src="http://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg" alt="1971 Topps 556 Jim McClothlin 8 " /> </div> <!-- 🔥 CORRECT ROUTE --> <a href="/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8"> 1971 Topps 556 Jim McClothlin 8 </a> </div> </div>23<div class="col-md-3"> <div class="auction-list-item"> <div class="image-container"> <img src="http://marketplace.cleansweepauctions.com/images/main/dodgers713283.jpg" alt="1947 Exhibit 294 Dodgers Team 1956 PSA 3.5 " /> </div> <a href="/past-auctions/april-2025/1947-exhibit-294-dodgers-team-1956-psa-35"> 1947 Exhibit 294 Dodgers Team 1956 PSA 3.5 </a> </div> </div> </div>24<div class="pagination" style="text-align:center;"> <a href="?page=1&q=&category=&auction=&sort=" class="active"> 1 </a> <a href="?page=2&q=&category=&auction=&sort=" class=""> 2 </a> <a href="?page=3&q=&category=&auction=&sort=" class=""> 3 </a> <a href="?page=12&q=" class="">Next →</a> </div>`;2526const LOT_PAGE = `<section id="subheader"> <div class="container"> <h1 style="font-weight:600;">1971 Topps 556 Jim McClothlin 8 </h1> <ul class="crumb"> <li><a href="/">Home</a></li> <li class="sep">/</li> <li><a href="april-2025">April 2025</a></li> <li class="sep">/</li> <li>Auction Item Details</li> </ul> </div> </section>27<section> <div class="container"> <div class="row"> <div class="col-md-4"> <div class='card'> <img src='http://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg' /> </div> </div> <div class="col-md-8"> <h2 style="padding-top: 10px;"> 1971 Topps 556 Jim McClothlin 8 </h2> <div> </div> <div> <strong style="display:block; padding-top:10px; color: #993B34;">Winning bid: $70.00</strong> </div> </div> </div> <a href="/past-auctions/april-2025" class="back-to-auction">&lt; Back to April 2025</a> </div> </section>`;2829describe('clean-sweep', () => {30  runFixtureSuite(connector, it, expect);3132  it('parses the past-auction index newest first', () => {33    expect(parsePastIndex(INDEX)).toEqual(['december-2025', 'may-2025', 'april-2025', 'april-2008']);34    expect(monthKey('april-2025')).toBe(202504);35    expect(monthKey('not-a-month')).toBeNull();36  });3738  it('parses a month page (lots + page count)', () => {39    const mp = parseMonthPage(MONTH_PAGE, 'april-2025', 1);40    expect(mp.monthLabel).toBe('April 2025');41    expect(mp.totalPages).toBe(12);42    expect(mp.lots.length).toBe(2);43    expect(mp.lots[0]).toEqual({ slug: '1971-topps-556-jim-mcclothlin-8', url: 'https://www.cleansweepauctions.com/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8', title: '1971 Topps 556 Jim McClothlin 8', image: 'https://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg' });44  });4546  it('parses the lot page winning bid and month date', () => {47    const p = parseLotPage(LOT_PAGE, 'https://www.cleansweepauctions.com/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8', 'april-2025', '1971-topps-556-jim-mcclothlin-8', 'https://www.cleansweepauctions.com/past-auctions/april-2025')!;48    expect(p).toMatchObject({ title: '1971 Topps 556 Jim McClothlin 8', winningBidText: '$70.00', price: 70, monthLabel: 'April 2025' });49    expect(p.image).toBe('https://marketplace.cleansweepauctions.com/images/main/mcclothlin713341.jpg');50    expect(monthYearDate('april-2025')?.toISOString()).toBe('2025-04-01T00:00:00.000Z');51  });5253  it('normalises to a hammer sale with month precision and no inferred grader', async () => {54    const p = parseLotPage(LOT_PAGE, 'https://www.cleansweepauctions.com/past-auctions/april-2025/1971-topps-556-jim-mcclothlin-8', 'april-2025', '1971-topps-556-jim-mcclothlin-8', 'https://www.cleansweepauctions.com/past-auctions/april-2025')!;55    const out = await connector.normalize({ url: p.url, externalId: 'april-2025/1971-topps-556-jim-mcclothlin-8', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload: p });56    expect(out.length).toBe(1);57    const s = out[0]!;58    if (s.kind !== 'sale') throw new Error('expected sale');59    expect(s).toMatchObject({ price: 70, currency: 'USD', buyerPremiumIncluded: false, auctionHouse: 'Clean Sweep Auctions', confidence: 0.7, isBundle: false });60    expect(s.saleDate.toISOString()).toBe('2025-04-01T00:00:00.000Z');61    expect(s.attributes.categorySlug).toBe('baseball_cards');62    expect(s.attributes.metadata).toMatchObject({ sale_date_precision: 'month', buyers_premium_pct: 22, hammer_price: 70 });63    expect(s.attributes.identifiers.clean_sweep_lot_slug).toBe('april-2025/1971-topps-556-jim-mcclothlin-8');64    expect(s.grade.grader).toBeNull();65    expect(s.attributes.year).toBe(1971);66  });6768  it('keeps graders when the title names one and flags bundles', async () => {69    const graded = { ...parseLotPage(LOT_PAGE, 'https://www.cleansweepauctions.com/x', 'april-2025', 'x', 'y')!, title: '1947 Exhibit 294 Dodgers Team 1956 PSA 3.5', price: 120 };70    const [s] = await connector.normalize({ url: 'https://www.cleansweepauctions.com/x', externalId: 'x', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload: graded });71    if (!s || s.kind !== 'sale') throw new Error('expected sale');72    expect(s.grade).toMatchObject({ grader: 'psa', grade: '3.5' });73    expect(s.confidence).toBe(0.75);74    expect(isBundle('1970s Reds Signed Dinner Programs w/Bench, Rose (3 pcs) 9')).toBe(true);75    expect(isBundle('1971 Topps 556 Jim McClothlin 8')).toBe(false);76    expect(cleanSweepCategory('2018 Topps Update 285 Ohtani RC Ex')).toBe('baseball_cards');77    expect(cleanSweepCategory('1986 Fleer 57 Michael Jordan RC PSA 7')).toBe('basketball_cards');78    expect(cleanSweepCategory('1970 NLCS At Cincinnati Program NM')).toBe('sports_memorabilia');79    expect(cleanSweepCategory('Big Red Machine Single Signed Ball Lot (27 different) 8')).toBe('sports_memorabilia');80    const unsold = await connector.normalize({ url: 'https://www.cleansweepauctions.com/x', externalId: 'x', kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { ...graded, price: null, winningBidText: null } });81    expect(unsold).toEqual([]);82  });83});84