task-63(ASIN 数据中心): 实现去重汇总日期和国家筛选
新增 dedupe-total-filter.ts 纯局部筛选态:createDedupeTotalFilterState 默认空、 dedupeTotalFilterActive 判定任一激活、toDedupeListParams 过滤态+页码 → AsinListParams (空白/非法日期不下发),复用共享 asin-filter 类型。8 用例全过,459 单测 + build 绿。
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
/** 去重汇总页面局部筛选状态(任务 63):日期区间/国家/分组/关键字,纯逻辑复用共享筛选类型。 */
|
||||||
|
import { validIsoDateOrUndefined, type AsinListParams } from './asin-filter.ts'
|
||||||
|
|
||||||
|
export interface DedupeTotalFilterState {
|
||||||
|
keyword: string
|
||||||
|
username: string
|
||||||
|
/** ISO yyyy-MM-dd;空串表示不限。 */
|
||||||
|
startDate: string
|
||||||
|
endDate: string
|
||||||
|
groupId: number | null
|
||||||
|
country: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDedupeTotalFilterState(): DedupeTotalFilterState {
|
||||||
|
return { keyword: '', username: '', startDate: '', endDate: '', groupId: null, country: '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 是否有任一激活筛选条件。 */
|
||||||
|
export function dedupeTotalFilterActive(state: DedupeTotalFilterState): boolean {
|
||||||
|
if ((state.keyword || '').trim()) return true
|
||||||
|
if ((state.username || '').trim()) return true
|
||||||
|
if ((state.country || '').trim()) return true
|
||||||
|
if (typeof state.groupId === 'number' && state.groupId >= 1) return true
|
||||||
|
if (validIsoDateOrUndefined(state.startDate) || validIsoDateOrUndefined(state.endDate)) return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 过滤态 + 页码 → 列表查询参数;空白/非法日期不下发。 */
|
||||||
|
export function toDedupeListParams(
|
||||||
|
state: DedupeTotalFilterState,
|
||||||
|
page: number,
|
||||||
|
pageSize: number,
|
||||||
|
): AsinListParams {
|
||||||
|
const params: AsinListParams = { page, pageSize }
|
||||||
|
const keyword = (state.keyword || '').trim()
|
||||||
|
const username = (state.username || '').trim()
|
||||||
|
const country = (state.country || '').trim()
|
||||||
|
if (keyword) params.keyword = keyword
|
||||||
|
if (username) params.username = username
|
||||||
|
if (country) params.country = country
|
||||||
|
const startDate = validIsoDateOrUndefined(state.startDate)
|
||||||
|
const endDate = validIsoDateOrUndefined(state.endDate)
|
||||||
|
if (startDate) params.startDate = startDate
|
||||||
|
if (endDate) params.endDate = endDate
|
||||||
|
if (typeof state.groupId === 'number' && state.groupId >= 1) params.groupId = state.groupId
|
||||||
|
return params
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import test from 'node:test'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import { readSource } from './helpers.ts'
|
||||||
|
import {
|
||||||
|
createDedupeTotalFilterState,
|
||||||
|
dedupeTotalFilterActive,
|
||||||
|
toDedupeListParams,
|
||||||
|
} from '../src/pages/asin/dedupe-total-filter.ts'
|
||||||
|
import { ASIN_PAGE_DEFAULT_SIZE } from '../src/pages/asin/asin-filter.ts'
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_normal_primary_path', () => {
|
||||||
|
// 正常主路径:完整筛选(国家+日期区间)可判定激活并映射到列表参数。
|
||||||
|
const state = { ...createDedupeTotalFilterState(), country: 'DE', startDate: '2026-01-01', endDate: '2026-01-31' }
|
||||||
|
assert.equal(dedupeTotalFilterActive(state), true)
|
||||||
|
const params = toDedupeListParams(state, 2, 20)
|
||||||
|
assert.equal(params.page, 2)
|
||||||
|
assert.equal(params.pageSize, 20)
|
||||||
|
assert.equal(params.country, 'DE')
|
||||||
|
assert.equal(params.startDate, '2026-01-01')
|
||||||
|
assert.equal(params.endDate, '2026-01-31')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_normal_variant_input', () => {
|
||||||
|
// 正常变体:仅分组/仅用户名筛选亦激活。
|
||||||
|
assert.equal(dedupeTotalFilterActive({ ...createDedupeTotalFilterState(), groupId: 3 }), true)
|
||||||
|
assert.equal(dedupeTotalFilterActive({ ...createDedupeTotalFilterState(), username: '张' }), true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_normal_repeated_operation_is_idempotent', () => {
|
||||||
|
// 正常重复:映射纯函数不改输入。
|
||||||
|
const state = createDedupeTotalFilterState()
|
||||||
|
assert.deepEqual(toDedupeListParams(state, 1, 15), toDedupeListParams(state, 1, 15))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_boundary_empty_input', () => {
|
||||||
|
// 边界空值:默认过滤态不激活;映射到列表参数为空筛选、带默认分页。
|
||||||
|
const state = createDedupeTotalFilterState()
|
||||||
|
assert.equal(dedupeTotalFilterActive(state), false)
|
||||||
|
const params = toDedupeListParams(state, 1, 15)
|
||||||
|
assert.equal('country' in params, false)
|
||||||
|
assert.equal('startDate' in params, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_boundary_single_item', () => {
|
||||||
|
// 边界单元素:单国家筛选激活。
|
||||||
|
const state = { ...createDedupeTotalFilterState(), country: 'UK' }
|
||||||
|
assert.equal(dedupeTotalFilterActive(state), true)
|
||||||
|
assert.equal(toDedupeListParams(state, 1, 15).country, 'UK')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_boundary_limit_or_missing_field', () => {
|
||||||
|
// 边界上限/缺字段:空白关键字/国家不激活;默认页大小常量透传。
|
||||||
|
const state = { ...createDedupeTotalFilterState(), keyword: ' ', country: ' ' }
|
||||||
|
assert.equal(dedupeTotalFilterActive(state), false)
|
||||||
|
const params = toDedupeListParams(state, 1, ASIN_PAGE_DEFAULT_SIZE)
|
||||||
|
assert.equal('keyword' in params, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_invalid_input_rejected', () => {
|
||||||
|
// 异常输入:非法 ISO 日期在映射层回 undefined(共享筛选会再校验)。
|
||||||
|
const state = { ...createDedupeTotalFilterState(), startDate: 'bad', endDate: '2026-02-01' }
|
||||||
|
const params = toDedupeListParams(state, 1, 15)
|
||||||
|
assert.equal(params.startDate, undefined)
|
||||||
|
assert.equal(params.endDate, '2026-02-01')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_063_dedupe_filter_dependency_failure_returns_actionable_message', () => {
|
||||||
|
// 依赖失败/可操作:过滤状态纯逻辑、复用共享筛选类型,不带 http。
|
||||||
|
const mod = readSource('src/pages/asin/dedupe-total-filter.ts')
|
||||||
|
assert.equal(/axios|http\.|vue/.test(mod), false, '过滤状态保持纯逻辑')
|
||||||
|
assert.match(mod, /asin-filter/)
|
||||||
|
assert.match(mod, /startDate/)
|
||||||
|
assert.match(mod, /country/)
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user