refactor: 统一 target name/description 可空语义,前端展示 fallback 到 id
- schema: name/description 允许省略或显式 null,TypeBox Union([Null, String]) - 类型: RawTargetConfig/ResolvedTargetBase/子类型/StoredTarget/TargetStatus name 改为 string | null - checker resolve: name: t.name ?? null,不再 fallback 到 id - 语义校验: 拒绝空字符串和纯空白 name - SQLite: targets.name 列改为可空 TEXT - 前端: 新增 getTargetDisplayName(target) 展示 name ?? id - 测试: 覆盖 name/description null 全场景,查找改为按 id - 文档: 更新 README/DEVELOPMENT 和 6 个 openspec specs
This commit is contained in:
32
tests/web/utils/target.test.ts
Normal file
32
tests/web/utils/target.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import type { TargetStatus } from "../../../src/shared/api";
|
||||
|
||||
import { getTargetDisplayName } from "../../../src/web/utils/target";
|
||||
|
||||
function makeTarget(overrides: Partial<TargetStatus> = {}): TargetStatus {
|
||||
return {
|
||||
currentStreak: null,
|
||||
description: null,
|
||||
group: "default",
|
||||
id: "api-health",
|
||||
interval: "30s",
|
||||
latestCheck: null,
|
||||
name: null,
|
||||
recentSamples: [],
|
||||
stats: { availability: 100, downChecks: 0, totalChecks: 0, upChecks: 0 },
|
||||
target: "https://example.com",
|
||||
type: "http",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("getTargetDisplayName", () => {
|
||||
test("name 为 null 时返回 id", () => {
|
||||
expect(getTargetDisplayName(makeTarget())).toBe("api-health");
|
||||
});
|
||||
|
||||
test("name 有值时返回 name", () => {
|
||||
expect(getTargetDisplayName(makeTarget({ name: "我的 API" }))).toBe("我的 API");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user