registry/test/configService.test.js
Cheney f9f3184f98
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 31s
fix
2026-08-07 14:46:52 +08:00

146 lines
6.9 KiB
JavaScript
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.

/**
* 配置服务单元测试
* 覆盖维度映射路径构建与嵌套键规整两项核心逻辑
* 运行npm test
*/
const test = require("node:test");
const assert = require("node:assert");
const { buildConfigPath, normalizeKey, validateEditValue, validateStructure } = require("../src/services/configService");
// 构造测试用项目对象的辅助函数
function makeProject(overrides) {
return {
enableIdc: true,
enableEnvironment: true,
enableGroup: true,
idcMapping: "path",
environmentMapping: "path",
groupMapping: "path",
...overrides,
};
}
test("1-1 全部维度映射为 path 时,路径包含全部维度前缀", () => {
const project = makeProject({});
const config = { idc: "华北", environment: "dev", group: "用户模块", key: "db.host" };
assert.strictEqual(buildConfigPath(project, config), "华北/dev/用户模块/db.host");
});
test("1-2 分组映射为 label 时,分组不进入路径", () => {
const project = makeProject({ groupMapping: "label" });
const config = { idc: "华北", environment: "dev", group: "用户模块", key: "db/host" };
assert.strictEqual(buildConfigPath(project, config), "华北/dev/db/host");
});
test("1-3 全部维度映射为 label 时,路径仅含嵌套键", () => {
const project = makeProject({ idcMapping: "label", environmentMapping: "label", groupMapping: "label" });
const config = { idc: "华北", environment: "dev", group: "用户模块", key: "db/pool/max" };
assert.strictEqual(buildConfigPath(project, config), "db/pool/max");
});
test("1-4 维度未启用时,即便映射为 path 也不进入路径", () => {
const project = makeProject({ enableIdc: false });
const config = { idc: "华北", environment: "dev", group: "用户模块", key: "db.host" };
assert.strictEqual(buildConfigPath(project, config), "dev/用户模块/db.host");
});
test("2-1 规整键:去除首尾斜杠与空白", () => {
assert.strictEqual(normalizeKey(" /db/host/ "), "db/host");
});
test("2-2 规整键:压缩连续斜杠并去除空段", () => {
assert.strictEqual(normalizeKey("db//pool///max"), "db/pool/max");
});
test("2-3 规整键:空输入返回空字符串", () => {
assert.strictEqual(normalizeKey(" "), "");
});
test("3-1 必填且存在:空值校验失败", () => {
const cfg = { key: "a", value: " ", type: "string", valueRange: "", required: true, exists: true };
assert.throws(() => validateEditValue(cfg), /必填项/);
});
test("3-2 必填且存在:非空值通过", () => {
const cfg = { key: "a", value: "x", type: "string", valueRange: "", required: true, exists: true };
assert.doesNotThrow(() => validateEditValue(cfg));
});
test("3-3 必填但不存在:允许空值", () => {
const cfg = { key: "a", value: "", type: "string", valueRange: "", required: true, exists: false };
assert.doesNotThrow(() => validateEditValue(cfg));
});
test("3-4 不存在:跳过类型与范围校验", () => {
const cfg = { key: "a", value: "not-number", type: "number", valueRange: "", required: false, exists: false };
assert.doesNotThrow(() => validateEditValue(cfg));
});
test("3-5 存在且值类型错误:校验失败", () => {
const cfg = { key: "a", value: "abc", type: "number", valueRange: "", required: false, exists: true };
assert.throws(() => validateEditValue(cfg), /有效的数字/);
});
test("3-6 存在且不符合正则范围:校验失败", () => {
const cfg = { key: "phone", value: "123", type: "string", valueRange: "/^1[3-9]\\d{9}$/", required: false, exists: true };
assert.throws(() => validateEditValue(cfg), /格式要求/);
});
test("3-7 必填且 json 值为空数组:不算空值", () => {
const cfg = { key: "a", value: [], type: "json", valueRange: "", required: true, exists: true };
assert.doesNotThrow(() => validateEditValue(cfg));
});
test("3-8 必填且值为 0 / false不算空值", () => {
assert.doesNotThrow(() => validateEditValue({ key: "a", value: 0, type: "number", valueRange: "", required: true, exists: true }));
assert.doesNotThrow(() => validateEditValue({ key: "a", value: false, type: "boolean", valueRange: "", required: true, exists: true }));
});
test("4-1 默认值类型校验number 类型默认值必须为数字", () => {
const project = makeProject({});
const base = { key: "a", type: "number", description: "d", idc: "x", environment: "y", group: "z" };
assert.throws(() => validateStructure({ ...base, defaultValue: "abc" }, project), /默认值不符合类型/);
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: "42" }, project));
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: 0 }, project));
});
test("4-2 默认值类型校验:空默认值不做校验", () => {
const project = makeProject({});
const base = { key: "a", type: "number", description: "d", idc: "x", environment: "y", group: "z" };
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: "" }, project));
assert.doesNotThrow(() => validateStructure({ ...base }, project));
});
test("4-3 默认值类型校验json 类型默认值需为合法 JSON", () => {
const project = makeProject({});
const base = { key: "a", type: "json", description: "d", idc: "x", environment: "y", group: "z" };
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: "{\"a\":1}" }, project));
assert.throws(() => validateStructure({ ...base, defaultValue: "{bad json}" }, project), /默认值不符合类型/);
});
test("4-4 默认值范围校验:默认值需符合值范围约束", () => {
const project = makeProject({});
const base = { key: "a", type: "string", description: "d", idc: "x", environment: "y", group: "z", valueRange: "/^1[3-9]\\d{9}$/" };
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: "13800138000" }, project));
assert.throws(() => validateStructure({ ...base, defaultValue: "12345" }, project), /默认值校验失败/);
});
test("4-5 默认值范围校验number 区间默认值", () => {
const project = makeProject({});
const base = { key: "a", type: "number", description: "d", idc: "x", environment: "y", group: "z", valueRange: "1-100" };
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: "50" }, project));
assert.throws(() => validateStructure({ ...base, defaultValue: "500" }, project), /默认值校验失败/);
});
test("4-6 默认值类型校验boolean false 为合法默认值", () => {
const project = makeProject({});
const base = { key: "a", type: "boolean", description: "d", idc: "x", environment: "y", group: "z" };
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: false }, project));
});
test("4-7 默认值判断:纯空白默认值视为未填写", () => {
const project = makeProject({});
const base = { key: "a", type: "number", description: "d", idc: "x", environment: "y", group: "z" };
assert.doesNotThrow(() => validateStructure({ ...base, defaultValue: " " }, project));
});