douyin-release-gate / verify (push) Failing after 3m57s
- 资料表单三行分组:登录用户名/更新密码/业务状态;实名状态/实名姓名/实名证件号;账号备注独占一行 - 新增 FingerprintFields 共享组件(字段+载荷构建+回显转换),创建页同步复用 - 编辑页指纹独立卡片单独保存(PUT fingerprint),运行中环境保存后自动重启生效 - 修复暗病:保存资料不再发送 Number(undefined)=NaN 的 cooldown_seconds,改透传当前值
83 lines
4.3 KiB
JavaScript
83 lines
4.3 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { readFileSync } = require('node:fs');
|
|
const { test } = require('node:test');
|
|
const ts = require('typescript');
|
|
|
|
function loadSource(relativePath) {
|
|
return ts.createSourceFile(
|
|
relativePath,
|
|
readFileSync(`${__dirname}/../src/${relativePath}`, 'utf8'),
|
|
ts.ScriptTarget.Latest,
|
|
true,
|
|
ts.ScriptKind.TSX,
|
|
).getFullText();
|
|
}
|
|
|
|
const editPage = loadSource('pages/accounts/$id/edit.tsx');
|
|
const fingerprintFields = loadSource('components/accounts/FingerprintFields.tsx');
|
|
const createPage = loadSource('pages/accounts/new.tsx');
|
|
|
|
test('账号资料表单按三行分组:登录用户名/更新密码/业务状态、实名三项、账号备注', () => {
|
|
// 第一行:登录用户名、更新密码、业务状态在同一个 Row 中按序出现
|
|
const firstRow = editPage.indexOf('<Row gutter={16}>');
|
|
const businessStatus = editPage.indexOf('name="business_status"');
|
|
const secondRow = editPage.indexOf('<Row gutter={16}>', firstRow + 1);
|
|
assert.ok(firstRow > -1 && businessStatus > firstRow && businessStatus < secondRow, '登录用户名/更新密码/业务状态应同属第一行');
|
|
assert.ok(editPage.includes('name="login_username"') && editPage.includes('name="password"'), '第一行应包含登录用户名与更新密码');
|
|
|
|
// 第二行:实名状态、实名姓名、实名证件号
|
|
const noteItem = editPage.indexOf('name="note"');
|
|
assert.ok(secondRow > firstRow && secondRow < noteItem, '实名三项应与第一行分行');
|
|
assert.ok(
|
|
editPage.includes('name="real_name_status"') && editPage.includes('name="real_name"') && editPage.includes('name="identity_number"'),
|
|
'第二行应包含实名状态、实名姓名、实名证件号',
|
|
);
|
|
|
|
// 账号备注独占一行(不包在 Row/Col 中)
|
|
assert.ok(
|
|
!editPage.slice(editPage.lastIndexOf('<Row gutter={16}>', noteItem), noteItem).includes('name="note"'),
|
|
'账号备注不应在 Row 内',
|
|
);
|
|
});
|
|
|
|
test('指纹浏览器环境独立卡片单独保存,不混入账号资料保存', () => {
|
|
assert.ok(editPage.includes('title="指纹浏览器环境"'), '指纹环境应为独立卡片');
|
|
assert.ok(editPage.includes('>保存指纹<') || editPage.includes('保存指纹'), '指纹卡片应有独立保存按钮');
|
|
assert.match(editPage, /\/creator\/accounts\/\$\{encodeURIComponent\(selected\.id\)\}\/fingerprint/);
|
|
assert.ok(editPage.includes('<FingerprintFields />'), '指纹字段应复用共享组件');
|
|
assert.ok(editPage.includes('fpForm.validateFields()'), '指纹保存前应先校验表单');
|
|
});
|
|
|
|
test('指纹保存后按运行状态提示:运行中重启 / 未运行下次启动生效', () => {
|
|
assert.ok(editPage.includes("result?.runtime_id ? '指纹已保存,运行环境已用新配置重启。' : '指纹已保存,将在环境下次启动时生效。'"));
|
|
});
|
|
|
|
test('编辑页加载时从账号详情内联 environment.fingerprint 回显指纹', () => {
|
|
assert.ok(editPage.includes("getOne('accounts', selectedID)"), '编辑页应请求账号详情');
|
|
assert.match(editPage, /fingerprintFormValues\(detail\?\.environment\?\.fingerprint\)/);
|
|
});
|
|
|
|
test('账号资料保存保留现有冷却时间,不再发送 NaN', () => {
|
|
assert.ok(
|
|
editPage.includes('cooldown_seconds: selected.cooldown_seconds'),
|
|
'cooldown_seconds 应透传当前值,避免 Number(undefined)=NaN 被 400 拒绝',
|
|
);
|
|
assert.ok(!editPage.includes('Number(values.cooldown_seconds)'), '不得再从缺失的表单字段计算冷却时间');
|
|
});
|
|
|
|
test('共享指纹字段:载荷只含非空项,disable_spoofing 以逗号合并', () => {
|
|
assert.match(fingerprintFields, /fp\.disable_spoofing\?\.length\) payload\.disable_spoofing = fp\.disable_spoofing\.join\(','\)/);
|
|
assert.match(fingerprintFields, /if \(fp\.timezone\?\.trim\(\)\) payload\.timezone = fp\.timezone\.trim\(\)/);
|
|
assert.match(fingerprintFields, /payload\.hardware_concurrency = fp\.hardware_concurrency/);
|
|
});
|
|
|
|
test('共享指纹字段:回显把逗号字符串拆回多选数组', () => {
|
|
assert.match(fingerprintFields, /String\(fp\.disable_spoofing\)\.split\(','\)/);
|
|
});
|
|
|
|
test('创建页与编辑页共用同一指纹字段组件', () => {
|
|
assert.ok(createPage.includes("from '@/components/accounts/FingerprintFields'"));
|
|
assert.ok(createPage.includes('<FingerprintFields />'));
|
|
assert.match(createPage, /fingerprintPayload\(values\.fingerprint\)/);
|
|
});
|