import { readFileSync } from 'node:fs'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { getConnectorMeta } from '@rareindex/connectors'; import { fixtureDir, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing'; import createConnector, { searchUrl, toItem } from './index.js'; const connector = createConnector(getConnectorMeta('bunjang')); const sample = JSON.parse(readFileSync(path.join(fixtureDir('bunjang'), 'samples', 'find-v2.json'), 'utf8')) as { num_found: number; list: Record[] }; describe('bunjang', () => { runFixtureSuite(connector, it, expect); it('maps a raw find_v2 row (KRW price string, image template, status, category)', () => { const it0 = toItem(sample.list[0]!); expect(it0).not.toBeNull(); expect(it0!.pid).toBe('407596186'); expect(it0!.price).toBe(100000); expect(it0!.image).toBe('https://media.bunjang.co.kr/product/407596186_1_1778563857_w600.jpg'); expect(it0!.status).toBe('0'); expect(it0!.categoryId).toBe('940100001'); expect(it0!.used).toBe(2); expect(sample.num_found).toBeGreaterThan(100); expect(toItem({ ...sample.list[0]!, type: 'BANNER' })).toBeNull(); }); it('builds the 0-based search URL', () => { expect(searchUrl('포켓몬카드', 2)).toBe('https://api.bunjang.co.kr/api/1/find_v2.json?q=%ED%8F%AC%EC%BC%93%EB%AA%AC%EC%B9%B4%EB%93%9C&order=date&page=2&n=100&req_ref=search&stat_device=w&version=5'); }); it('normalises the fixture into KRW listings with grade, condition, language and metadata', async () => { const fx = loadFixture('bunjang', 'pokemon-psa10-search-p0'); const out = await connector.normalize(fx.raw); expect(out.length).toBeGreaterThan(5); const l = out[0]; if (l?.kind !== 'listing') throw new Error('expected listing'); expect(l.currency).toBe('KRW'); expect(l.price).toBe(100000); expect(l.attributes.categorySlug).toBe('pokemon'); expect(l.attributes.identifiers.bunjang_pid).toBe('407596186'); expect(l.attributes.language).toBe('English'); // 북미판 = North American print expect(l.grade.grader).toBe('psa'); expect(l.grade.grade).toBe('10'); expect(l.condition.conditionRaw).toBe('Used'); // used = 2 expect(l.availability).toBe('available'); expect(l.listedAt).toBeNull(); expect(typeof l.attributes.metadata.updated_at).toBe('string'); expect(l.sourceUrl).toBe('https://m.bunjang.co.kr/products/407596186'); expect(l.seller).toBeNull(); const jp = out.find((r) => r.kind === 'listing' && /일판/.test(r.rawTitle)); expect(jp && jp.kind === 'listing' ? jp.attributes.language : null).toBe('Japanese'); }); });