Files
huangzd1997 479cc449d6 task-117(任务与重复分析中心): 实现重复检查明细列表
新增 duplicate-filter.ts(明细筛选 snake 查询) 与 parseDuplicateItemsPage/
fetchDuplicateItems(GET /duplicate-check-items)。

TDD: task-117.test.ts 8 用例先 RED 后 GREEN。
2026-09-05 17:25:41 +08:00

85 lines
3.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test from 'node:test'
import assert from 'node:assert/strict'
import { readSource } from './helpers.ts'
import { parseDuplicateItemsPage } from '../src/pages/tasks/duplicate-model.ts'
import { toDuplicateItemsQuery } from '../src/pages/tasks/duplicate-filter.ts'
test('test_task_117_duplicate_items_normal_primary_path', () => {
// 正常主路径:明细筛选序列化与分页负载解析。
const query = toDuplicateItemsQuery(
{ view: 'monitor', asin: 'B0X', shopName: '店', country: 'DE', site: '', dateFrom: '2026-01-01', dateTo: '2026-01-31' },
2,
20,
)
assert.equal(query.view, 'monitor')
assert.equal(query.asin, 'B0X')
assert.equal(query.shop_name, '店')
assert.equal(query.country, 'DE')
assert.equal(query.date_from, '2026-01-01')
assert.equal(query.page, 2)
assert.equal(query.page_size, 20)
})
test('test_task_117_duplicate_items_normal_variant_input', () => {
// 正常变体:明细项含跨店出现记录解析。
const page = parseDuplicateItemsPage({
data: {
pending: false,
items: [
{ asin: 'B0ABC', shop_count: 2, record_count: 3, occurrences: [
{ asin: 'B0ABC', shop_name: 'A店', group_name: '华东', country_codes: ['DE'], country: 'DE', date: '2026-01-01', price: '9.9', brand: 'X' },
] },
],
total: 1,
page: 1,
page_size: 20,
},
})
assert.equal(page.items.length, 1)
const item = page.items[0]
assert.equal(item.asin, 'B0ABC')
assert.equal(item.shopCount, 2)
assert.equal(item.occurrences[0].shopName, 'A店')
assert.equal(item.occurrences[0].price, '9.9')
})
test('test_task_117_duplicate_items_repeated_is_idempotent', () => {
// 正常重复:查询序列化稳定。
const filter = { view: '', asin: 'A', shopName: '', country: '', site: '', dateFrom: '', dateTo: '' }
assert.deepEqual(toDuplicateItemsQuery(filter, 1, 20), toDuplicateItemsQuery(filter, 1, 20))
})
test('test_task_117_duplicate_items_boundary_empty_input', () => {
// 边界空值:空筛选回默认分页;pending 空态。
const page = parseDuplicateItemsPage({ data: { pending: true, items: [], total: 0, page: 1, page_size: 20 } })
assert.equal(page.pending, true)
assert.deepEqual(page.items, [])
})
test('test_task_117_duplicate_items_boundary_single_item', () => {
// 边界单元素:单明细项。
const page = parseDuplicateItemsPage({ data: { pending: false, items: [{ asin: 'S', shop_count: 1, record_count: 1, occurrences: [] }], total: 1, page: 1, page_size: 20 } })
assert.equal(page.items[0].asin, 'S')
assert.deepEqual(page.items[0].occurrences, [])
})
test('test_task_117_duplicate_items_boundary_limit_or_missing_field', () => {
// 边界上限/缺字段:页大小钳制到上限。
const query = toDuplicateItemsQuery({ view: '', asin: '', shopName: '', country: '', site: '', dateFrom: '', dateTo: '' }, 1, 999)
assert.equal(query.page_size, 100)
})
test('test_task_117_duplicate_items_invalid_input_rejected', () => {
// 异常输入:success=false 抛后端 message。
assert.throws(() => parseDuplicateItemsPage({ success: false, message: '暂无权限查看' }), /暂无权限/)
})
test('test_task_117_duplicate_items_dependency_failure_returns_actionable_message', () => {
// 依赖失败/加载走 adapterGET /duplicate-check-items + 解析。
const api = readSource('src/pages/tasks/duplicate-api.ts')
assert.match(api, /\/duplicate-check-items/)
assert.match(api, /fetchDuplicateItems/)
const model = readSource('src/pages/tasks/duplicate-model.ts')
assert.equal(/axios|http\./.test(model), false, '明细解析保持纯逻辑')
})