TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import metaJson from './meta.json' with { type: 'json' };3import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';4import { localMeta } from '../_lib/local-meta.js';5import { makerFromTitle, yearOrDecade } from '../_g10-lib/index.js';6import createConnector, { pageUrl, parseCategoryHtml, parseStoreCurrency } from './index.js';78const connector = createConnector(localMeta(metaJson));910describe('pamono', () => {11 runFixtureSuite(connector, it, expect);1213 it('parses product cards (sku, price content, image) and the store currency', () => {14 const html = String((loadFixture('pamono', 'furniture-p1').raw.payload as { snapshot?: string }).snapshot ?? '');15 expect(parseStoreCurrency(html)).toBe('USD');16 const cards = parseCategoryHtml(html);17 expect(cards.length).toBeGreaterThanOrEqual(2);18 const c = cards[0]!;19 expect(c.sku).toMatch(/^[A-Z0-9]{2,4}-\d+$/);20 expect(c.productId).toMatch(/^\d+$/);21 expect(c.url).toMatch(/^https:\/\/www\.pamono\.com\//);22 expect(c.price).toBeGreaterThan(0);23 expect(c.currency).toBe('USD');24 expect(c.image).toMatch(/cdn20\.pamono\.com/);25 });2627 it('parses makers and decades from titles', () => {28 expect(makerFromTitle('Large Coffee Table by Maison Jansen, 1970s')).toBe('Maison Jansen');29 expect(makerFromTitle('Mid-Century Teak Tola Sideboard from Greaves & Thomas')).toBe('Greaves & Thomas');30 expect(makerFromTitle('Art Deco Ruby and Diamonds Brooch, 1920s')).toBeNull();31 expect(yearOrDecade('Large Coffee Table by Maison Jansen, 1970s')).toEqual({ year: null, decade: '1970s' });32 expect(yearOrDecade('Egg Chair by Arne Jacobsen for Fritz Hansen, 1965')).toEqual({ year: 1965, decade: null });33 expect(pageUrl('/furniture', 2)).toBe('https://www.pamono.com/furniture?p=2');34 });3536 it('normalises cards into USD listings with pamono identifiers', async () => {37 const fx = loadFixture('pamono', 'furniture-p1');38 const out = await connector.normalize(fx.raw);39 expect(out.length).toBeGreaterThan(0);40 for (const r of out) {41 if (r.kind !== 'listing') throw new Error('expected listing');42 expect(r.currency).toBe('USD');43 expect(r.price).toBeGreaterThan(0);44 expect(r.attributes.identifiers.pamono_sku).toBeTruthy();45 expect(['design_furniture', 'antiques', 'clocks', 'glass_crystal', 'porcelain', 'silver', 'art']).toContain(r.attributes.categorySlug);46 }47 const jw = loadFixture('pamono', 'jewelry-watches-p1');48 const jwOut = await connector.normalize(jw.raw);49 expect(jwOut.length).toBeGreaterThan(0);50 for (const r of jwOut) expect(['jewelry', 'gemstones', 'rolex', 'omega', 'patek_philippe', 'audemars_piguet', 'other_watches']).toContain((r as { attributes: { categorySlug: string } }).attributes.categorySlug);51 });52});53