import { describe, expect, it } from "vitest"; import { extractProblemId, normalizePbankBaseUrl, pbankRightsFromCredential, } from "../../src/capability/pbankClient.js"; import type { PbankCapabilitySecretPayload } from "../../src/capability/types.js"; import { claudeSdkToolConfigForRole, cphHubMcpToolsForRole } from "../../src/agent/roleTools.js"; describe("pbank client helpers", () => { it("extracts problem UUID from bare id and URL", () => { const id = "01234567-89ab-4def-8abc-0123456789ab"; expect(extractProblemId(id)).toBe(id); expect(extractProblemId(`https://pbank.paradigm-edu.net/problem/${id}`)).toBe(id); expect(extractProblemId(`https://pbank.example/x?id=${id}`)).toBe(id); }); it("normalizes base URL trailing slashes", () => { expect(normalizePbankBaseUrl("https://pbank.paradigm-edu.net/api/")).toBe( "https://pbank.paradigm-edu.net/api", ); expect(normalizePbankBaseUrl("")).toBe("https://pbank.paradigm-edu.net/api"); }); it("marks derivative use from operator rights status", () => { const owned: PbankCapabilitySecretPayload = { schemaVersion: 1, kind: "pbank", baseUrl: "https://pbank.paradigm-edu.net/api", username: "u", password: "p", rightsStatus: "owned", }; expect(pbankRightsFromCredential(owned).derivativeUseAllowed).toBe(true); const unknown: PbankCapabilitySecretPayload = { ...owned, rightsStatus: "unknown", }; expect(pbankRightsFromCredential(unknown).derivativeUseAllowed).toBe(false); }); }); describe("role tool mapping for pbank", () => { it("maps umbrella pbank role tool to three MCP tools", () => { expect(cphHubMcpToolsForRole(["pbank"])).toEqual([ "todo_write", "pbank_search_problems", "pbank_get_problem", "pbank_get_many_problems", ]); const cfg = claudeSdkToolConfigForRole(["pbank", "Read"]); expect(cfg.tools).toContain("Read"); expect(cfg.allowedTools).toContain("mcp__cph_hub__pbank_search_problems"); expect(cfg.allowedTools).toContain("mcp__cph_hub__pbank_get_problem"); expect(cfg.allowedTools).toContain("mcp__cph_hub__pbank_get_many_problems"); }); });