import assert from 'node:assert/strict'; import test from 'node:test'; import { adaptJdProductResponse } from '../src/modules/domestic-voc/adapters/jd-product.adapter.js'; import { GatewayPayloadError } from '../src/modules/domestic-voc/adapters/jd-response.js'; import { adaptJdReviewResponse } from '../src/modules/domestic-voc/adapters/jd-review.adapter.js'; test('JD product adapter unwraps the company gateway envelope', () => { const product = adaptJdProductResponse({ code: 200, data: { code: 200, data: { item: { itemId: '11266507445', itemName: 'Demashi commercial cooker', brandName: 'Demashi', model: '35P6-CM1', firstCategoryName: 'Commercial appliances', thirdCategoryName: 'Commercial cooker', }, }, }, }, '11266507445'); assert.equal(product.productId, '11266507445'); assert.equal(product.productKey, 'jd:11266507445'); assert.equal(product.title, 'Demashi commercial cooker'); assert.equal(product.brand, 'Demashi'); assert.equal(product.model, '35P6-CM1'); assert.equal(product.source, 'fmode_gateway'); }); test('JD review adapter maps evidence and pagination without reviewer identity', () => { const page = adaptJdReviewResponse({ code: 200, data: { code: 200, data: { comments: [{ commentId: 'comment-1', score: 5, content: 'Easy to clean and heats quickly.', creationTime: '2026-07-20T10:00:00+08:00', nickname: 'not-exposed-by-snapshot', }], pageCount: 2, }, }, }, '11266507445', 1); assert.equal(page.reviews.length, 1); assert.equal(page.reviews[0]?.reviewId, 'comment-1'); assert.equal(page.reviews[0]?.rating, 5); assert.equal(page.reviews[0]?.reviewDate, '2026-07-20T02:00:00.000Z'); assert.match(page.reviews[0]?.reviewKey ?? '', /^jd:11266507445:/); assert.equal(page.hasNextPage, true); }); test('JD adapters classify pending collection as retryable without raw body leakage', () => { assert.throws( () => adaptJdProductResponse({ code: 301, message: 'COLLECT FAILED, SEND REQUEST AGAIN', data: null }, '1'), (error: unknown) => { assert.ok(error instanceof GatewayPayloadError); assert.equal(error.retryable, true); assert.equal(error.message, 'Gateway data is not ready'); assert.doesNotMatch(error.message, /COLLECT FAILED/); return true; }, ); });