import test from 'node:test' import assert from 'node:assert/strict' import { readSource } from './helpers.ts' import { asinForCountry, queryAsinDisplayRows, queryAsinRowEntries, type QueryAsinItem, } from '../src/pages/asin/query-asin-model.ts' /** 对齐 admin.js:5525-5559 renderQueryAsinEntries/renderQueryAsinRows:纵向 rowspan 展示 + 逐国行。 */ function item(id: number, overrides: Partial = {}): QueryAsinItem { return { id, groupId: 1, groupName: 'A组', shopName: `店铺${id}`, asinDe: '', asinUk: '', asinFr: '', asinIt: '', asinEs: '', ...overrides, } } test('align_query_asin_row_entries_collects_valued_countries_in_order', () => { const entries = queryAsinRowEntries(item(1, { asinDe: 'B0DE', asinFr: 'B0FR' })) assert.deepEqual(entries, [ { country: 'DE', asin: 'B0DE' }, { country: 'FR', asin: 'B0FR' }, ]) }) test('align_query_asin_row_entries_empty_shop_yields_single_dash_row', () => { const entries = queryAsinRowEntries(item(2)) assert.deepEqual(entries, [{ country: null, asin: '' }]) }) test('align_query_asin_display_rows_merge_rowspan_and_numbering', () => { // 第 2 页(每页 15)第一条 rowNo=16:店铺A 占 2 行合并,店铺B 1 行。 const rows = queryAsinDisplayRows( [item(1, { asinDe: 'B0DE', asinUk: 'B0UK' }), item(2)], 16, ) assert.equal(rows.length, 3) const [r0, r1, r2] = rows assert.equal(r0.rowNo, 16) assert.equal(r0.rowspan, 2) assert.equal(r0.isFirst, true) assert.equal(r0.country, 'DE') assert.equal(r0.asin, 'B0DE') assert.equal(r1.rowNo, 16) assert.equal(r1.isFirst, false) assert.equal(r1.country, 'UK') assert.equal(r2.rowNo, 17) assert.equal(r2.rowspan, 1) assert.equal(r2.isFirst, true) assert.equal(r2.country, null) assert.equal(r2.asin, '') // key 唯一,供 v-for 使用。 assert.equal(new Set(rows.map((r) => r.key)).size, rows.length) }) test('align_query_asin_display_rows_empty_input', () => { assert.deepEqual(queryAsinDisplayRows([], 1), []) }) test('align_query_asin_create_api_wiring', () => { // 新增适配:POST /api/admin/query-asins,载荷含 groupId/shopName/countries/asinMappings(对齐 Java QueryAsinCreateRequest)。 const api = readSource('src/pages/asin/query-asin-api.ts') assert.match(api, /createQueryAsin/, '含新增适配函数') assert.match(api, /query-asins/, '端点正确') assert.match(api, /asinMappings/, '载荷含逐国映射') assert.match(api, /fetchShopManageList/, '店铺名联动复用店铺列表适配') assert.match(api, /page_size|pageSize:\s*100/, '店铺名加载按 100/页分页拉取') }) test('align_query_asin_page_layout_wiring', () => { const page = readSource('src/pages/asin/QueryAsinPage.vue') assert.match(page, /新增 ASIN/, '顶栏补新增 ASIN 按钮') assert.match(page, /:rowspan="row\.rowspan"/, '表格用原生 rowspan 合并(像素复刻旧版)') assert.match(page, /CopyText/, 'ASIN 单元格点击复制') assert.doesNotMatch(page, /更新时间/, '去掉更新时间列(参考无此列)') assert.match(page, /queryAsinDisplayRows/, '行展开走纯模型') assert.match(page, /请完整填写分组、店铺名、国家和 ASIN/, '新增弹窗校验文案对齐') assert.match(page, /请先选择分组/, '店铺下拉未选分组时占位对齐') })