/** * Token 服务单元测试 * 覆盖:mcpEnabled 标记、MCP token 列表过滤、历史 MCP 配置迁移 * 运行:npm test */ const test = require("node:test"); const assert = require("node:assert"); const fs = require("node:fs"); const os = require("node:os"); const path = require("node:path"); // 使用临时数据目录,避免污染真实 data/ const tmpDataDir = fs.mkdtempSync(path.join(os.tmpdir(), "registry-token-test-")); process.env.REGISTRY_DATA_DIR = tmpDataDir; const { init } = require("../src/persistence/duckdbAdapter"); const tokenService = require("../src/services/tokenService"); test.before(async () => { await init(); }); test("createToken 保存 mcpEnabled 标记", async () => { const mcpToken = await tokenService.createToken({ name: "mcp-key", projectId: "all", permission: "readwrite", mcpEnabled: true, expiresInDays: 30, }); assert.strictEqual(mcpToken.mcpEnabled, true); const plainToken = await tokenService.createToken({ name: "plain", mcpEnabled: false, }); assert.strictEqual(plainToken.mcpEnabled, false); }); test("getMcpTokenValues 仅返回生效的 MCP token 明文", async () => { const values = await tokenService.getMcpTokenValues(); assert.ok(values.length >= 1); // 明文值以 reg_ 开头 assert.ok(values.every((v) => typeof v === "string" && v.startsWith("reg_"))); }); test("updateToken 可切换 mcpEnabled", async () => { const plain = await tokenService.createToken({ name: "toggle", mcpEnabled: false }); const before = await tokenService.getMcpTokenValues(); assert.ok(!before.includes(plain.value)); await tokenService.updateToken(plain.id, { mcpEnabled: true }); const after = await tokenService.getMcpTokenValues(); assert.ok(after.includes(plain.value)); }); test("吊销或过期后 MCP token 不再生效", async () => { const t = await tokenService.createToken({ name: "will-revoke", mcpEnabled: true, expiresInDays: 30 }); const ok = await tokenService.getMcpTokenValues(); assert.ok(ok.includes(t.value)); await tokenService.revokeToken(t.id); const revoked = await tokenService.getMcpTokenValues(); assert.ok(!revoked.includes(t.value)); }); test("migrateLegacyMcpToken 把历史 mcp_kv 配置迁移为 Token 记录", async () => { // 清理当前 token 表,模拟空 MCP 标记状态 const { loadApiTokens, saveApiTokens, saveMcpConfig, loadMcpConfig } = require("../src/persistence/duckdbAdapter"); await saveApiTokens([]); await saveMcpConfig({ enabled: true, token: "legacy-mcp-token-abc" }); await tokenService.migrateLegacyMcpToken(); const tokens = await loadApiTokens(); const migrated = tokens.find((t) => t.mcpEnabled); assert.ok(migrated, "应生成一条 mcpEnabled 的 Token"); assert.strictEqual(migrated.value, "legacy-mcp-token-abc"); const values = await tokenService.getMcpTokenValues(); assert.ok(values.includes("legacy-mcp-token-abc")); // 旧配置已清空 const mcp = await loadMcpConfig(); assert.strictEqual(mcp.token, ""); });