Files
nodeagent/tests/unit/validate.test.mjs
T
jkooe f4c605cc6d test+fix: 单元测试套件 + 两处细节修复
单元测试(新增,node:test 零依赖):
- tests/unit/: ulid / hmac / ed25519 / acl / validate 共 26 项用例
- 覆盖最关键的安全函数:签名验签、ACL 授权、参数校验
- 新增 pnpm test:unit;CI 增加单元测试步骤

细节修复:
1. screen.info 的 scale 硬编码为 1 → 改读注册表 HKCU AppliedDPI,
   真实反映 Windows DPI 缩放(100% -> 1.0, 150% -> 1.5)
2. verify.mjs 升级:支持多设备配置(resolveTarget)+ ed25519 模式 + Hub 中转
   (此前直接用旧的扁平配置 + 仅 psk,配了多设备会取不到 host)

验证:构建 + 类型检查全绿;单元 26/26;E2E 21/21;verify.mjs 13/0/3
2026-09-27 17:04:21 +08:00

83 lines
3.3 KiB
JavaScript
Raw 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 { validate, applyDefaults } from '../../packages/protocol/dist/index.js';
test('validate:基本类型', () => {
assert.deepEqual(validate('x', { type: 'string' }), []);
assert.deepEqual(validate(1, { type: 'integer' }), []);
assert.deepEqual(validate(1.5, { type: 'number' }), []);
assert.deepEqual(validate(true, { type: 'boolean' }), []);
assert.deepEqual(validate([], { type: 'array' }), []);
assert.deepEqual(validate({}, { type: 'object' }), []);
assert.ok(validate(1, { type: 'string' }).length > 0);
assert.ok(validate('x', { type: 'integer' }).length > 0);
assert.ok(validate(1.5, { type: 'integer' }).length > 0, '非整数应报错');
});
test('validate:enum', () => {
const schema = { type: 'string', enum: ['a', 'b'] };
assert.deepEqual(validate('a', schema), []);
assert.ok(validate('c', schema).length > 0, '不在枚举内应报错');
});
test('validate:数值范围', () => {
const schema = { type: 'number', minimum: 0, maximum: 10 };
assert.deepEqual(validate(5, schema), []);
assert.deepEqual(validate(0, schema), []);
assert.ok(validate(-1, schema).length > 0);
assert.ok(validate(11, schema).length > 0);
});
test('validate:字符串长度与 pattern', () => {
const schema = { type: 'string', minLength: 2, maxLength: 5, pattern: '^[a-z]+$' };
assert.deepEqual(validate('abc', schema), []);
assert.ok(validate('a', schema).length > 0, '过短');
assert.ok(validate('abcdef', schema).length > 0, '过长');
assert.ok(validate('ab1', schema).length > 0, '不匹配 pattern');
});
test('validate:数组长度与 items 类型', () => {
const schema = { type: 'array', minItems: 1, maxItems: 3, items: { type: 'integer' } };
assert.deepEqual(validate([1, 2], schema), []);
assert.ok(validate([], schema).length > 0, '空数组');
assert.ok(validate([1, 2, 3, 4], schema).length > 0, '超长');
assert.ok(validate([1, 'x'], schema).length > 0, 'item 类型错');
});
test('validate:required 与 additionalProperties', () => {
const schema = {
type: 'object',
properties: { name: { type: 'string' }, age: { type: 'integer' } },
required: ['name'],
additionalProperties: false,
};
assert.deepEqual(validate({ name: 'x', age: 1 }, schema), []);
assert.ok(validate({ age: 1 }, schema).length > 0, '缺 required');
assert.ok(validate({ name: 'x', extra: 1 }, schema).length > 0, '多余字段');
});
test('validate:嵌套路径正确', () => {
const schema = {
type: 'object',
properties: { filter: { type: 'object', properties: { pattern: { type: 'string' } } } },
};
assert.deepEqual(validate({ filter: { pattern: 'x' } }, schema), []);
const errs = validate({ filter: { pattern: 1 } }, schema);
assert.equal(errs.length, 1);
assert.ok(errs[0].includes('$.filter.pattern'), '错误应带嵌套路径');
});
test('applyDefaults:填补缺失字段,不覆盖已有值', () => {
const schema = {
type: 'object',
properties: {
limit: { type: 'integer', default: 20 },
recursive: { type: 'boolean', default: false },
},
};
const out = applyDefaults({ limit: 5 }, schema);
assert.equal(out.limit, 5, '已有值不被覆盖');
assert.equal(out.recursive, false, '缺失字段填默认值');
});