TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import { readFileSync } from 'node:fs';3import path from 'node:path';4import { fileURLToPath } from 'node:url';5import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';6import { localMeta } from '../_lib/local-meta.js';7import { hibidCategory, isFirearm } from './categories.js';8import createConnector, { parseCatalog, parsePastAuctions, slugify } 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/** Trimmed REAL Apollo state captured from https://hibid.com/catalog/752746/auction-200-silver-and-paper-money on 2026-09-08 (3 lots, contact details removed). */15const STATE = readFileSync(path.join(dir, 'fixtures.state.json'), 'utf8');16const CATALOG_HTML = `<!doctype html><html><head><title>Auction 200 Silver and Paper Money | HiBid</title></head><body><app-root></app-root><script id="hibid-state" type="application/json">${STATE}</script></body></html>`;1718function withPage(pageNumber: number, results: string): string {19 return CATALOG_HTML.replace(/"pageNumber":1,"totalCount":3,"filteredCount":3,"results":\[[^\]]*\]/, `"pageNumber":${pageNumber},"totalCount":3,"filteredCount":3,"results":[${results}]`);20}2122describe('hibid', () => {23 runFixtureSuite(connector, it, expect);2425 it('parses the auction header and lots from the embedded Apollo state', () => {26 const cat = parseCatalog(CATALOG_HTML, 1)!;27 expect(cat.auction).toMatchObject({ id: '752746', eventName: 'Auction 200 Silver and Paper Money', currency: 'CAD', buyerPremium: 'Buyers Premium 18%', bidCloseDateTime: '2026-09-07T19:00:00' });28 expect(cat.auction.auctioneer).toMatchObject({ name: 'Legacy Auctions', city: 'Leamington', state: 'ON', country: 'Canada' });29 expect(cat.pageNumber).toBe(1);30 expect(cat.totalCount).toBe(3);31 expect(cat.lots.length).toBe(3);32 const sold = cat.lots.find((l) => l.lotNumber === '93')!;33 expect(sold).toMatchObject({ id: '308002776', title: '1-1954 DEVIL FACE 20 DOLLAR BILL C/E2791225', priceRealized: 48, quantitySold: 1, isClosed: true, categoryPath: 'Coins & Currency - Currency - World', mappable: true });34 expect(sold.url).toBe('https://hibid.com/lot/308002776/1-1954-devil-face-20-dollar-bill-c-e2791225');35 expect(cat.lots.find((l) => l.lotNumber === '91')!.priceRealized).toBeNull();36 expect(cat.lots[0]!.image).toMatch(/^https:\/\/cdn\.hibid\.com\/img\.axd/);37 });3839 it('detects the end of a catalog (page 2 with no results)', () => {40 const cat = parseCatalog(withPage(2, ''), 2)!;41 expect(cat.pageNumber).toBe(2);42 expect(cat.lots.length).toBe(0);43 });4445 it('maps HiBid categories to taxonomy slugs and filters non-collectibles and firearms', () => {46 expect(hibidCategory('Coins & Currency - Currency - Canada', '1-1937 BANK OF CANADA 1 DOLLAR BILL S/N3599211')).toBe('banknotes');47 expect(hibidCategory('Coins & Currency - Coins - Canada', '1967 Canada Silver Dollar')).toBe('coins');48 expect(hibidCategory('Sports Memorabilia & Cards - Cards', '1986 Fleer Michael Jordan Rookie PSA 8')).toBe('basketball_cards');49 expect(hibidCategory('Toys & Hobbies - Action Figures', 'Star Wars Kenner Luke Skywalker MOC')).toBe('action_figures');50 expect(hibidCategory('Jewelry, Watches & Gemstones - Watches', 'Rolex Submariner 16610 wristwatch')).toBe('rolex');51 expect(hibidCategory('Real Estate - Residential', '3 bedroom house')).toBeNull();52 expect(hibidCategory('Construction & Farm - Tractors', 'John Deere 4020')).toBeNull();53 expect(hibidCategory('Household - Kitchen', 'Kitchen aid mixer')).toBeNull();54 expect(hibidCategory('Firearms & Military - Rifles', 'Winchester Model 70')).toBeNull();55 // Liquidators file new merchandise under "Antiques & Collectibles" (seen live: ToyTexx wholesale sale) → filtered.56 expect(hibidCategory('Antiques & Collectibles - Collectibles - Bakeware', '15PCS Nonstick Roasting Pan with Removable Flat Rack')).toBeNull();57 expect(hibidCategory('Antiques & Collectibles - Collectibles - Decorative - Ornaments', '10PCS Christmas Tree Building Sets, 730PC')).toBeNull();58 expect(hibidCategory('Antiques & Collectibles - Collectibles - Advertising', 'INFORMATION ONLY - DO NOT BID')).toBeNull();59 expect(hibidCategory('Antiques & Collectibles - Collectibles - Advertising', 'Coca-Cola porcelain sign 1950s')).toBe('advertising');60 expect(hibidCategory('Antiques & Collectibles - Collectibles - Kitchen', 'Vintage Pyrex Gooseberry bowl 1958')).toBe('antiques');61 expect(hibidCategory('Antiques & Collectibles - Collectibles', 'Vintage 1960s Zippo lighter')).toBe('lighters');62 expect(isFirearm('Antiques & Collectibles - Collectibles Remington .22 caliber rifle')).toBe(true);63 expect(isFirearm('1-1954 DEVIL FACE 20 DOLLAR BILL')).toBe(false);64 expect(slugify('Elite Auction SALE – Fine Jewelry, Rolex Watches, Art & Coll')).toBe('elite-auction-sale-fine-jewelry-rolex-watches-art-coll');65 });6667 it('parses the past-auction list (archived auctions + paging)', () => {68 // Real page shape reduced to one auction entry.69 const past = `<script id="hibid-state" type="application/json">${JSON.stringify({70 'apollo.state': {71 ROOT_QUERY: { __typename: 'Query', 'auctionSearch({"input":{"category":null,"isArchive":true},"pageLength":25,"pageNumber":2})': { __typename: 'AuctionSearchResult', pagedResults: { __typename: 'AuctionMatchPagedResult', pageLength: 25, pageNumber: 2, totalCount: 1324, filteredCount: 1324, results: [{ __typename: 'AuctionMatchType', matchinglotcount: 0, auction: { __ref: 'Auction:770300' } }] } } },72 'Auction:770300': { __typename: 'Auction', id: 770300, eventName: '09/07/2026 @ 10am CT - Annual Labor Day: Fine Auction', bidCloseDateTime: '2026-09-07T23:00:00', eventDateEnd: '2026-09-07T00:00:00', lotCount: 455, auctionState: { __typename: 'AuctionStateType', auctionStatus: 'ARCHIVED' }, auctioneer: { __ref: 'Auctioneer:62991' } },73 'Auctioneer:62991': { __typename: 'Auctioneer', id: 62991, name: 'Luther Auctions' },74 },75 })}</script>`;76 const list = parsePastAuctions(past)!;77 expect(list).toMatchObject({ pageNumber: 2, totalCount: 1324, pageLength: 25 });78 expect(list.auctions).toEqual([{ id: '770300', eventName: '09/07/2026 @ 10am CT - Annual Labor Day: Fine Auction', url: 'https://hibid.com/catalog/770300/09-07-2026-10am-ct-annual-labor-day-fine-auction', bidCloseDateTime: '2026-09-07T23:00:00', eventDateEnd: '2026-09-07T00:00:00', lotCount: 455, status: 'ARCHIVED' }]);79 });8081 it('normalises only closed lots with a published price realized (hammer, CAD, premium not included)', async () => {82 const cat = parseCatalog(CATALOG_HTML, 1)!;83 const payload = { kind: 'hibid_catalog_page', auction: cat.auction, page: 1, totalCount: cat.totalCount, lots: cat.lots.filter((l) => l.mappable).map(({ mappable: _m, ...rest }) => rest) };84 const out = await connector.normalize({ url: 'https://hibid.com/catalog/752746/auction-200-silver-and-paper-money', externalId: 'catalog:752746:page:1', kind: 'sale', engine: 'api', fetchedAt: new Date('2026-09-08T08:00:00Z'), payload });85 expect(out.length).toBe(1);86 const s = out[0]!;87 if (s.kind !== 'sale') throw new Error('expected sale');88 expect(s).toMatchObject({ price: 48, currency: 'CAD', buyerPremiumIncluded: false, auctionHouse: 'Legacy Auctions (HiBid)', lotNumber: '93', location: 'Leamington, ON, Canada', quantity: 1, isBundle: false });89 expect(s.saleDate.toISOString()).toBe('2026-09-07T19:00:00.000Z');90 expect(s.attributes.categorySlug).toBe('banknotes');91 expect(s.attributes.identifiers).toEqual({ hibid_lot_id: '308002776', hibid_auction_id: '752746' });92 expect(s.attributes.metadata).toMatchObject({ buyer_premium_text: 'Buyers Premium 18%', category_path: 'Coins & Currency - Currency - World' });93 expect(s.attributes.year).toBe(1954);94 });9596 it('skips unsupported currencies and firearms at normalisation time', async () => {97 const cat = parseCatalog(CATALOG_HTML, 1)!;98 const lots = cat.lots.filter((l) => l.mappable).map(({ mappable: _m, ...rest }) => rest);99 const gun = { ...lots[1]!, id: '1', title: 'Winchester Model 94 rifle .30-30', categoryPath: 'Antiques & Collectibles - Collectibles', priceRealized: 500 };100 const mxn = await connector.normalize({ url: 'x', externalId: 'e', kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { kind: 'hibid_catalog_page', auction: { ...cat.auction, currency: 'MXN' }, page: 1, totalCount: 3, lots } });101 expect(mxn.length).toBe(0);102 const withGun = await connector.normalize({ url: 'x', externalId: 'e', kind: 'sale', engine: 'api', fetchedAt: new Date(), payload: { kind: 'hibid_catalog_page', auction: cat.auction, page: 1, totalCount: 3, lots: [...lots, gun] } });103 expect(withGun.map((r) => ('externalId' in r ? r.externalId : null))).toEqual(['308002776']);104 });105106 it('fixture sales are CAD/USD hammer prices dated by the auction close', async () => {107 const out = await connector.normalize(loadFixture('hibid', 'coins-1').raw);108 expect(out.length).toBeGreaterThan(0);109 for (const r of out) {110 if (r.kind !== 'sale') throw new Error('expected sale');111 expect(['CAD', 'USD']).toContain(r.currency);112 expect(r.buyerPremiumIncluded).toBe(false);113 }114 });115});116