import { describe, expect, it } from 'vitest'; import { getConnectorMeta } from '@rareindex/connectors'; import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing'; import createConnector, { brandCategory, parseBrowsePage } from './index.js'; const connector = createConnector(getConnectorMeta('novelship')); describe('novelship', () => { runFixtureSuite(connector, it, expect); it('maps browse products to catalog + last sale + lowest ask', async () => { const fx = loadFixture('novelship', 'jordan-browse-page1'); const out = await connector.normalize(fx.raw); const cats = out.filter((r) => r.kind === 'catalog_item'); expect(cats.length).toBeGreaterThanOrEqual(30); for (const c of cats) { if (c.kind !== 'catalog_item') throw new Error(); expect(c.attributes.categorySlug).toBe('nike_jordan'); expect(c.attributes.identifiers.style_code).toMatch(/^[A-Z0-9][A-Z0-9\/ -]{3,}$/i); expect(c.sourceUrl).toMatch(/^https:\/\/novelship\.com\/[a-z0-9-]+$/); } const sales = out.filter((r) => r.kind === 'price_observation' && r.priceKind === 'last_sale_reported'); const asks = out.filter((r) => r.kind === 'listing' && r.listingType === 'ask'); expect(sales.length).toBeGreaterThan(10); expect(asks.length).toBeGreaterThan(10); for (const s of sales) if (s.kind === 'price_observation') expect(s.currency).toBe('USD'); }); it('parses a product page and keeps only that product on lookup', async () => { const fx = loadFixture('novelship', 'aj1-low-midnight-navy-product'); const out = await connector.normalize(fx.raw); const cat = out.find((r) => r.kind === 'catalog_item'); if (cat?.kind !== 'catalog_item') throw new Error(); expect(cat.attributes.identifiers.style_code).toBe('553558-404'); expect(cat.attributes.color).toContain('Midnight Navy'); expect(cat.attributes.originalMsrp).toBe(120); }); it('helpers', () => { expect(brandCategory('Jordan', 'Air Jordan 1')).toBe('nike_jordan'); expect(brandCategory('adidas', 'Yeezy Boost 350')).toBe('adidas_yeezy'); expect(brandCategory('New Balance', '550')).toBe('new_balance_asics_other'); const html = `x {"cost_retail":100,"drop_date":"2024-01-02","id":7,"image":"https://i/x.jpg","last_sale_price":150.5,"lowest_listing_price":"120.000000","main_brand":"Nike","name":"Nike Dunk Low Panda DD1391-100","name_slug":"nike-dunk-low-panda-dd1391-100","sales_count_180":12,"sku":"DD1391-100","sub_brand":""} y`; const p = parseBrowsePage(html, 'u', 'nike', 1); expect(p.products).toHaveLength(1); expect(p.products[0]).toMatchObject({ id: 7, sku: 'DD1391-100', lastSalePrice: 150.5, lowestListingPrice: 120, costRetail: 100, salesCount180: 12, mainBrand: 'Nike' }); }); });