146 lines
6.9 KiB
JavaScript
146 lines
6.9 KiB
JavaScript
/**
|
||
* 配置服务单元测试
|
||
* 覆盖维度映射路径构建与嵌套键规整两项核心逻辑
|
||
* 运行: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));
|
||
});
|