import assert from 'node:assert/strict' export interface ApiCallSnapshot { url?: string method?: string params?: Record data?: unknown } const ALLOWED_SECTIONS = ['url', 'method', 'params', 'data'] as const const apiModules = [ 'dedupe', 'split', 'convert', 'publish', 'similar-asin', 'appearance-patent', 'delete-brand', 'price-track', 'shop-match', 'query-asin', 'withdraw', 'collect-data', 'image-video', 'brand', 'permission', 'digital-human', ] as const export function isApiModule(name: string): boolean { return (apiModules as readonly string[]).includes(name) } export function assertApiCall(calls: ApiCallSnapshot[], index: number, expected: ApiCallSnapshot) { const actual = calls[index] assert.ok(actual, `第 ${index} 次请求不存在(共 ${calls.length} 次)`) const context = `第 ${index} 次请求实际=${JSON.stringify(actual)} 期望=${JSON.stringify(expected)}` for (const section of ALLOWED_SECTIONS) { assert.ok( !(section in expected) || section in actual, `快照缺少 section: ${section}。${context}`, ) } if (expected.url !== undefined) { assert.equal(actual.url, expected.url, `URL 快照不匹配。${context}`) } if (expected.method !== undefined) { assert.equal(actual.method, expected.method, `method 快照不匹配。${context}`) } if (expected.params !== undefined) { const actualParams = actual.params ?? {} for (const key of Object.keys(actualParams)) { assert.ok( key in expected.params, `params 出现白名单外字段: ${key}。${context}`, ) } assert.deepEqual(actualParams, expected.params, `params 快照不匹配。${context}`) } if (expected.data !== undefined) { const actualData = (actual.data ?? {}) as Record for (const key of Object.keys(actualData)) { assert.ok( key in expected.data, `data 出现白名单外字段: ${key}。${context}`, ) } assert.deepEqual(actualData, expected.data, `data 快照不匹配。${context}`) } }