TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import { ConnectorMetaSchema } from '@rareindex/connectors';3import { listFixtures, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';4import metaJson from './meta.json' with { type: 'json' };5import createConnector, { categoryFor, leafCategoryIds, normalizeItem, parseItemsPage, trimItem } from './index.js';6import { isBundleMultilingual, parenCount, parseEuDate, parseEuMoney, yearFromTitle } from '../_g8-auctions-eu-apac-lib/index.js';78const meta = ConnectorMetaSchema.parse(metaJson);9const connector = createConnector(meta);1011const API_ITEM = {12 id: 5224154,13 catalog_number: null,14 auction_id: 9524392,15 currency: 'EUR',16 reserve_met: true,17 reserve_amount: 200,18 estimate: 450,19 upper_estimate: null,20 starting_bid_amount: 25,21 hammered: false,22 state: 'sold',23 title: 'CORTÉBERT, WALTHAM, IMMERFORT ETC., Armbanduhren Konvolut, 20. Jahrhundert. (4).',24 description: '<p>Konvolut bestehend aus vier Armbanduhren: </p>\n\n<p>Cortébert, Handaufzug, 1950er Jahre.</p>',25 condition: '<p>Altersgemäße Gebrauchsspuren.</p>',26 company_id: 237,27 category_id: 15,28 ends_at: 1788854835,29 published_at: 1788164174,30 type: 'online',31 location: 'Cologne',32 house: 'Stockholms Auktionsverk Köln',33 placement: 'auf Anfrage',34 url: 'https://auctionet.com/en/5224154-cortebert-waltham-immerfort-etc-wristwatch-collection-20th-century-4',35 images: [{ thumb: 't.jpg', mini: 'm.jpg', w640: 'https://images.auctionet.com/thumbs/w640_item_5224154_x.jpg', hd: 'hd.jpg' }],36 bids: [37 { id: 42504089, bidder: 7, amount: 220, your_bid: false, reserve_met: true, auto: false, timestamp: 1788854655 },38 { id: 42502618, bidder: 4, amount: 200, your_bid: false, reserve_met: true, auto: false, timestamp: 1788846567 },39 ],40};4142describe('auctionet', () => {43 runFixtureSuite(connector, it, expect);4445 it('fixtures: sold lots become hammer-basis sales in native currency, unsold lots become ended auction_lots', async () => {46 let sales = 0;47 let lots = 0;48 for (const name of listFixtures('auctionet')) {49 const fx = loadFixture('auctionet', name);50 const out = await connector.normalize(fx.raw);51 for (const r of out) {52 if (!('attributes' in r)) continue;53 expect(r.attributes.identifiers.auctionet_item_id).toMatch(/^\d+$/);54 expect(r.sourceUrl).toMatch(/^https:\/\/auctionet\.com\/en\/(events\/[^/]+\/)?\d+-/);55 if (r.kind === 'sale') {56 sales++;57 expect(['SEK', 'EUR', 'DKK', 'GBP']).toContain(r.currency);58 expect(r.buyerPremiumIncluded).toBe(false);59 expect(r.attributes.metadata.price_basis).toBe('winning_bid_excl_buyer_fee');60 expect(r.auctionHouse).toBeTruthy();61 expect(r.saleDate.getUTCFullYear()).toBeGreaterThanOrEqual(2011);62 } else if (r.kind === 'auction_lot') {63 lots++;64 expect(r.status).toBe('ended');65 }66 }67 }68 expect(sales).toBeGreaterThan(20);69 expect(lots).toBeGreaterThan(0);70 });7172 it('trims the API item and normalises it (winning bid = hammer, EUR, bundle of 4)', () => {73 const item = trimItem(API_ITEM);74 expect(item).toMatchObject({ id: 5224154, currency: 'EUR', state: 'sold', winningBid: 220, winningBidAt: 1788854655, bidCount: 2, house: 'Stockholms Auktionsverk Köln', location: 'Cologne', categoryId: 15 });75 expect(item.images).toEqual(['https://images.auctionet.com/thumbs/w640_item_5224154_x.jpg']);76 expect(item.description).toBe('Konvolut bestehend aus vier Armbanduhren: Cortébert, Handaufzug, 1950er Jahre.');77 const rec = normalizeItem(meta, item, new Date('2026-09-08T10:00:00Z'));78 expect(rec?.kind).toBe('sale');79 if (rec?.kind !== 'sale') return;80 expect(rec.price).toBe(220);81 expect(rec.currency).toBe('EUR');82 expect(rec.saleDate.toISOString()).toBe('2026-09-08T08:07:15.000Z');83 expect(rec.isBundle).toBe(true);84 expect(rec.attributes.categorySlug).toBe('other_watches');85 expect(rec.attributes.year).toBeNull(); // "20. Jahrhundert", "(4)" — no year86 expect(rec.buyerPremiumIncluded).toBe(false);87 expect(rec.lotNumber).toBeNull();88 expect(rec.condition.conditionRaw).toBe('Altersgemäße Gebrauchsspuren.');89 });9091 it('unsold and out-of-taxonomy items', () => {92 const unsold = trimItem({ ...API_ITEM, id: 1, state: 'unsold', bids: [], category_id: 128, title: 'MYNT, 5 kronor, Sverige 1955.' });93 const rec = normalizeItem(meta, unsold, new Date());94 expect(rec?.kind).toBe('auction_lot');95 if (rec?.kind === 'auction_lot') {96 expect(rec.status).toBe('ended');97 expect(rec.currentBid).toBeNull();98 expect(rec.estimateLow).toBe(450);99 expect(rec.attributes.categorySlug).toBe('coins');100 expect(rec.attributes.year).toBe(1955);101 }102 const weapon = trimItem({ ...API_ITEM, id: 2, category_id: 61, title: 'GEVÄR, Husqvarna.' });103 expect(normalizeItem(meta, weapon, new Date())).toBeNull();104 const unknownCurrency = trimItem({ ...API_ITEM, id: 3, currency: 'XXX' });105 expect(normalizeItem(meta, unknownCurrency, new Date())).toBeNull();106 });107108 it('parses a page and pagination metadata', () => {109 const p = parseItemsPage({ items: [API_ITEM], pagination: { current_page: 1, total_pages: 50, total_entries: 3917226 } }, 'https://auctionet.com/api/v2/items.json?is=ended', 1, { categoryId: null, countryCode: null });110 expect(p?.items).toHaveLength(1);111 expect(p?.totalEntries).toBe(3917226);112 expect(parseItemsPage({ error: 'x' }, 'u', 1, { categoryId: null, countryCode: null })).toBeNull();113 });114115 it('maps Auctionet categories + multilingual titles to taxonomy slugs', () => {116 expect(categoryFor(15, 'ARMBANDSUR, Rolex, Datejust, ref 16233, stål och guld.').slug).toBe('rolex');117 expect(categoryFor(15, 'ARMBANDSUR, Omega, Seamaster, stål, dam, manuell.').slug).toBe('omega');118 expect(categoryFor(110, 'FICKUR, silver, 1800-talets slut.').slug).toBe('other_watches');119 expect(categoryFor(128, 'ÄLDRE SVENSKA SEDLAR, 49 st, 1960-80-tal.').slug).toBe('banknotes');120 expect(categoryFor(128, 'MYNT, 1 riksdaler 1776.').slug).toBe('coins');121 expect(categoryFor(135, 'ORDEN, Vasaorden, riddartecken, guld.').slug).toBe('medals');122 expect(categoryFor(136, 'FRIMÄRKEN, samling i album.').slug).toBe('stamps');123 expect(categoryFor(19, 'SOFFBORD, Bruno Mathsson, Karl Mathsson, 1960-tal.').slug).toBe('antiques');124 expect(categoryFor(18, 'HANS J. WEGNER, armchair "The Chair", Johannes Hansen, Denmark.').slug).toBe('design_furniture');125 expect(categoryFor(28, 'OLJEMÅLNING, signerad, landskap.').slug).toBe('art');126 expect(categoryFor(26, 'FOTOGRAFI, gelatin silver print.').slug).toBe('photography');127 expect(categoryFor(170, 'MACALLAN 18 Years Old Sherry Oak, 70 cl.').slug).toBe('whisky');128 expect(categoryFor(170, 'CHÂTEAU MARGAUX 1990, 1 flaska.').slug).toBe('wine');129 expect(categoryFor(49, 'HERMÈS, handväska "Birkin 35", Togo.').slug).toBe('luxury_handbags');130 expect(categoryFor(268, 'POKÉMON, Charizard, Base Set, holo.').slug).toBe('pokemon');131 expect(categoryFor(211, 'SERIETIDNINGAR, Kalle Anka & Co, 1950-tal, 12 st.').slug).toBe('independent_comics');132 expect(categoryFor(275, 'MODELLBILAR, Dinky Toys, 5 st.').slug).toBe('model_cars');133 expect(categoryFor(215, 'VOLVO P1800 S, 1966.').slug).toBe('automobiles');134 expect(categoryFor(61, 'GEVÄR').slug).toBeNull();135 expect(categoryFor(253, 'MOTOR').slug).toBeNull();136 expect(categoryFor(999, 'Random unknown thing').slug).toBeNull();137 expect(categoryFor(999, 'LEICA M3 camera body').slug).toBe('cameras');138 expect(leafCategoryIds()).not.toContain(16); // parent "Furniture"139 expect(leafCategoryIds()).toContain(19);140 expect(leafCategoryIds()).toContain(42); // Mirrors (childless root)141 expect(leafCategoryIds()).not.toContain(61); // licence weapons142 });143144 it('shared multilingual helpers', () => {145 expect(parseEuDate('12 juin 2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');146 expect(parseEuDate('jeudi 09 juillet 2026 14:00')?.toISOString()).toBe('2026-07-09T00:00:00.000Z');147 expect(parseEuDate('12. Juni 2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');148 expect(parseEuDate('1. März 2025')?.toISOString()).toBe('2025-03-01T00:00:00.000Z');149 expect(parseEuDate('12 giugno 2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');150 expect(parseEuDate('12 de junio de 2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');151 expect(parseEuDate('den 12 juni 2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');152 expect(parseEuDate('22–23 juin 2026')?.toISOString()).toBe('2026-06-22T00:00:00.000Z');153 expect(parseEuDate('June 12, 2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');154 expect(parseEuDate('12.06.2026')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');155 expect(parseEuDate('2026-06-12T14:00:00Z')?.toISOString()).toBe('2026-06-12T00:00:00.000Z');156 expect(parseEuDate('12 joulukuuta 2025')?.toISOString()).toBe('2025-12-12T00:00:00.000Z');157 expect(parseEuDate('nonsense')).toBeNull();158159 expect(parseEuMoney('1.250,00 €', 'EUR')).toMatchObject({ amount: 1250, currency: 'EUR' });160 expect(parseEuMoney('1 250 €', 'EUR')).toMatchObject({ amount: 1250, currency: 'EUR' });161 expect(parseEuMoney('1 081 EUR', 'EUR')).toMatchObject({ amount: 1081, currency: 'EUR' });162 expect(parseEuMoney('593EUR', 'EUR')).toMatchObject({ amount: 593, currency: 'EUR' });163 expect(parseEuMoney('€ 12.500', 'EUR')).toMatchObject({ amount: 12500, currency: 'EUR' });164 expect(parseEuMoney("CHF 1'250", 'CHF', 'ch')).toMatchObject({ amount: 1250, currency: 'CHF' });165 expect(parseEuMoney('12 000 SEK', 'SEK')).toMatchObject({ amount: 12000, currency: 'SEK' });166 expect(parseEuMoney('4 000 kr', 'SEK')).toMatchObject({ amount: 4000, currency: 'SEK' });167 expect(parseEuMoney('£1,250', 'GBP', 'en')).toMatchObject({ amount: 1250, currency: 'GBP' });168 expect(parseEuMoney('HK$1,250,000', 'HKD', 'en')).toMatchObject({ amount: 1_250_000, currency: 'HKD' });169 expect(parseEuMoney('¥1,250,000', 'JPY', 'en')).toMatchObject({ amount: 1_250_000, currency: 'JPY' });170 expect(parseEuMoney('AU$2,400', 'AUD', 'en')).toMatchObject({ amount: 2400, currency: 'AUD' });171 expect(parseEuMoney('1.250', 'EUR')).toMatchObject({ amount: 1250 });172 expect(parseEuMoney('1.25', 'EUR')).toMatchObject({ amount: 1.25 });173 expect(parseEuMoney('n/a', 'EUR')).toBeNull();174 expect(parseEuMoney('1 250', null)).toBeNull();175176 expect(isBundleMultilingual('Armbanduhren Konvolut (4)')).toBe(true);177 expect(isBundleMultilingual('SEDLAR, 49 st')).toBe(true);178 expect(isBundleMultilingual('Lot de trois montres')).toBe(true);179 expect(isBundleMultilingual('Lotto di sei tazze')).toBe(true);180 expect(isBundleMultilingual('SÄNGBORD, ett par')).toBe(false);181 expect(isBundleMultilingual('ARMBANDSUR, Rolex, Datejust')).toBe(false);182 expect(parenCount('LJUSSTAKAR, ett par, silver. (2).')).toBe(2);183 expect(parenCount('12 st glas')).toBe(12);184185 expect(yearFromTitle('SÄNGBORD, ett par, 1900/2000-tal')).toBeNull();186 expect(yearFromTitle('SOFFBORD, 1960-tal')).toBeNull();187 expect(yearFromTitle('Cortébert, 1950er Jahre')).toBeNull();188 expect(yearFromTitle('Rolex Datejust, 1980s')).toBeNull();189 expect(yearFromTitle('VOLVO P1800 S, 1966.')).toBe(1966);190 expect(yearFromTitle('MYNT, 1 riksdaler 1776.')).toBe(1776);191 expect(yearFromTitle('CHÂTEAU MARGAUX 1990')).toBe(1990);192 });193});194