TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import { getConnectorMeta, missingRequirements } from '@rareindex/connectors';3import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';4import createConnector, { buildUrl, redact, toHit } from './index.js';56const connector = createConnector(getConnectorMeta('yahoo-shopping-jp'));78/** Verbatim hit from the official itemSearch V3 documentation sample (query=nike). */9const DOC_HIT = { index: 1, name: '<NIKE(ナイキ)>WOMENS AIR RIFT エアリフト', description: 'ZOZO問い合わせ番号:53582864…', headLine: '', url: 'https://store.shopping.yahoo.co.jp/zozo/52582864.html', inStock: true, code: 'zozo_52582864', condition: 'new', imageId: 'zozo_52582864', image: { small: 'https://item-shopping.c.yimg.jp/i/c/zozo_52582864', medium: 'https://item-shopping.c.yimg.jp/i/g/zozo_52582864' }, review: { rate: 0, count: 0, url: 'https://shopping.yahoo.co.jp/review/item/list?store_id=zozo&page_key=52582864' }, affiliateRate: 1, price: 10450, premiumPrice: 10450, priceLabel: { taxable: null, defaultPrice: 10450 }, shipping: { code: 1, name: '設定なし' }, genreCategory: { id: 23699, name: 'レディーススニーカー', depth: 4 }, brand: { id: 1319, name: 'NIKE' }, janCode: '', releaseDate: null, seller: { sellerId: 'zozo', name: 'ZOZOTOWN', url: 'https://paypaymall.yahoo.co.jp/store/zozo/top/', isBestSeller: false }, payment: '1 4 16 4096' };1011describe('yahoo-shopping-jp (gated)', () => {12 runFixtureSuite(connector, it, expect);1314 it('is reported as gated on YAHOO_JP_APP_ID', () => {15 expect(missingRequirements(connector.meta, {})).toEqual(['YAHOO_JP_APP_ID']);16 expect(missingRequirements(connector.meta, { YAHOO_JP_APP_ID: 'x' })).toEqual([]);17 });1819 it('maps a documented hit (nested brand/seller/genre/image, empty JAN → null)', () => {20 const h = toHit(DOC_HIT);21 expect(h).toMatchObject({ code: 'zozo_52582864', price: 10450, condition: 'new', inStock: true, janCode: null, brand: 'NIKE', sellerId: 'zozo', sellerName: 'ZOZOTOWN', genreCategory: 'レディーススニーカー', genreCategoryId: 23699, image: 'https://item-shopping.c.yimg.jp/i/g/zozo_52582864', reviewCount: 0 });22 expect(toHit({ ...DOC_HIT, janCode: '4905524535815' })?.janCode).toBe('4905524535815');23 expect(toHit({ ...DOC_HIT, price: 0 })).toBeNull();24 });2526 it('builds the documented request and redacts the app id', () => {27 const u = buildUrl({ appId: 'CLIENT', query: 'ロレックス', start: 51, condition: 'used' });28 expect(u.startsWith('https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?')).toBe(true);29 expect(u).toContain('results=50');30 expect(u).toContain('start=51');31 expect(u).toContain('condition=used');32 expect(u).toContain('image_size=600');33 expect(redact(u)).toContain('appid=***');34 expect(redact(u)).not.toContain('CLIENT');35 });3637 it('normalises the documentation sample into a JPY store listing with JAN/EAN identifiers when present', async () => {38 const fx = loadFixture('yahoo-shopping-jp', 'docs-sample-nike');39 const out = await connector.normalize(fx.raw);40 const l = out[0];41 if (l?.kind !== 'listing') throw new Error('expected listing');42 expect(l.price).toBe(10450);43 expect(l.currency).toBe('JPY');44 expect(l.attributes.categorySlug).toBe('nike_jordan');45 expect(l.attributes.identifiers).toEqual({ yahoo_shopping_code: 'zozo_52582864' });46 const withJan = await connector.normalize({ ...fx.raw, payload: { ...(fx.raw.payload as object), hits: [{ ...toHit(DOC_HIT)!, janCode: '4905524535815', condition: 'used' }] } });47 const j = withJan[0];48 if (j?.kind !== 'listing') throw new Error('expected listing');49 expect(j.attributes.identifiers.jan).toBe('4905524535815');50 expect(j.attributes.identifiers.ean).toBe('4905524535815');51 expect(j.condition.conditionRaw).toBe('Used');52 expect(j.confidence).toBeGreaterThan(l.confidence);53 });54});55