72a8f75dc5
新增 shop-key-form-model.ts(备注/紫鸟账号/令牌校验与 camel 请求体序列化, 镜像 Java NotBlank/Size 规则,令牌去 Bearer 前缀) 并在 shop-key-api.ts 增加 submitCreateShopKey(POST /api/admin/shop-keys)。 TDD: task-84.test.ts 8 用例先 RED 后 GREEN。
93 lines
4.1 KiB
TypeScript
93 lines
4.1 KiB
TypeScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { readSource } from './helpers.ts'
|
|
import {
|
|
SHOP_KEY_ACCOUNT_MAX_LEN,
|
|
SHOP_KEY_REMARK_MAX_LEN,
|
|
SHOP_KEY_TOKEN_MAX_LEN,
|
|
emptyShopKeyForm,
|
|
toShopKeyCreateRequest,
|
|
validateShopKeyForm,
|
|
} from '../src/pages/shop/shop-key-form-model.ts'
|
|
|
|
test('test_task_084_shop_key_create_form_normal_primary_path', () => {
|
|
// 正常主路径:合法表单校验通过并序列化为 Java camelCase 请求体。
|
|
const form = emptyShopKeyForm()
|
|
form.remarkName = '主店'
|
|
form.ziniaoAccountName = 'blue_agent'
|
|
form.ziniaoToken = 'token-secret-1'
|
|
const { valid, errors } = validateShopKeyForm(form)
|
|
assert.equal(valid, true)
|
|
assert.deepEqual(errors, {})
|
|
assert.deepEqual(toShopKeyCreateRequest(form), {
|
|
remarkName: '主店',
|
|
ziniaoAccountName: 'blue_agent',
|
|
ziniaoToken: 'token-secret-1',
|
|
})
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_normal_variant_input', () => {
|
|
// 正常变体:可选备注留空不下发;令牌首尾空白去除。
|
|
const request = toShopKeyCreateRequest({
|
|
remarkName: ' ',
|
|
ziniaoAccountName: ' red_agent ',
|
|
ziniaoToken: ' tok-2 ',
|
|
})
|
|
assert.equal('remarkName' in request, false)
|
|
assert.equal(request.ziniaoAccountName, 'red_agent')
|
|
assert.equal(request.ziniaoToken, 'tok-2')
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_repeated_is_idempotent', () => {
|
|
// 正常重复:序列化不改输入、结果稳定。
|
|
const form = { remarkName: 'A', ziniaoAccountName: 'acc', ziniaoToken: 'tok' }
|
|
assert.deepEqual(toShopKeyCreateRequest(form), toShopKeyCreateRequest(form))
|
|
assert.deepEqual(form, { remarkName: 'A', ziniaoAccountName: 'acc', ziniaoToken: 'tok' })
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_boundary_empty_input', () => {
|
|
// 边界空值:空表单校验给出账号/令牌缺失错误,备注可选不报错。
|
|
const { valid, errors } = validateShopKeyForm(emptyShopKeyForm())
|
|
assert.equal(valid, false)
|
|
assert.equal(errors.ziniaoAccountName, '紫鸟账号名称不能为空')
|
|
assert.equal(errors.ziniaoToken, '紫鸟令牌不能为空')
|
|
assert.equal('remarkName' in errors, false)
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_boundary_single_item', () => {
|
|
// 边界单元素:仅账号+令牌的最短合法表单通过。
|
|
const { valid } = validateShopKeyForm({ remarkName: '', ziniaoAccountName: 'a', ziniaoToken: 't' })
|
|
assert.equal(valid, true)
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_boundary_limit_or_missing_field', () => {
|
|
// 边界上限:各字段长度上限校验与超限拒绝。
|
|
const long = 'x'.repeat(SHOP_KEY_REMARK_MAX_LEN + 1)
|
|
const account = 'a'.repeat(SHOP_KEY_ACCOUNT_MAX_LEN)
|
|
const token = 't'.repeat(SHOP_KEY_TOKEN_MAX_LEN)
|
|
const ok = validateShopKeyForm({ remarkName: 'x'.repeat(SHOP_KEY_REMARK_MAX_LEN), ziniaoAccountName: account, ziniaoToken: token })
|
|
assert.equal(ok.valid, true)
|
|
const over = validateShopKeyForm({ remarkName: long, ziniaoAccountName: account, ziniaoToken: token })
|
|
assert.equal(over.valid, false)
|
|
assert.match(over.errors.remarkName || '', /128/)
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_invalid_input_rejected', () => {
|
|
// 异常输入:空白令牌/账号拒绝;超长备注给出可操作消息。
|
|
const { errors } = validateShopKeyForm({ remarkName: '', ziniaoAccountName: ' ', ziniaoToken: ' ' })
|
|
assert.equal(errors.ziniaoAccountName, '紫鸟账号名称不能为空')
|
|
assert.equal(errors.ziniaoToken, '紫鸟令牌不能为空')
|
|
})
|
|
|
|
test('test_task_084_shop_key_create_form_dependency_failure_returns_actionable_message', () => {
|
|
// 依赖失败/提交走 adapter:模型纯逻辑,adapter POST /api/admin/shop-keys + 校验。
|
|
const model = readSource('src/pages/shop/shop-key-form-model.ts')
|
|
assert.equal(/axios|http\.|vue/.test(model), false, '表单模型保持纯逻辑')
|
|
assert.match(model, /SensitiveString|敏感/)
|
|
const api = readSource('src/pages/shop/shop-key-api.ts')
|
|
assert.match(api, /submitCreateShopKey/)
|
|
assert.match(api, /http\.post/)
|
|
assert.match(api, /\/api\/admin\/shop-keys/)
|
|
assert.match(api, /validateShopKeyForm/)
|
|
})
|