diff --git a/src/gateway/server-methods/health.status-scope.test.ts b/src/gateway/server-methods/health.status-scope.test.ts deleted file mode 100644 index f8a83aa19..000000000 --- a/src/gateway/server-methods/health.status-scope.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { describe, expect, it, vi } from "vitest"; -import { getStatusSummary } from "../../commands/status.js"; -import { healthHandlers } from "./health.js"; - -vi.mock("../../commands/status.js", () => ({ - getStatusSummary: vi.fn().mockResolvedValue({ ok: true }), -})); - -describe("gateway healthHandlers.status scope handling", () => { - it("requests redacted status for non-admin clients", async () => { - const respond = vi.fn(); - await healthHandlers.status({ - respond, - client: { connect: { role: "operator", scopes: ["operator.read"] } }, - } as Parameters<(typeof healthHandlers)["status"]>[0]); - - expect(vi.mocked(getStatusSummary)).toHaveBeenCalledWith({ includeSensitive: false }); - expect(respond).toHaveBeenCalledWith(true, { ok: true }, undefined); - }); - - it("requests full status for admin clients", async () => { - const respond = vi.fn(); - await healthHandlers.status({ - respond, - client: { connect: { role: "operator", scopes: ["operator.admin"] } }, - } as Parameters<(typeof healthHandlers)["status"]>[0]); - - expect(vi.mocked(getStatusSummary)).toHaveBeenCalledWith({ includeSensitive: true }); - expect(respond).toHaveBeenCalledWith(true, { ok: true }, undefined); - }); -}); diff --git a/src/gateway/server-methods/server-methods.test.ts b/src/gateway/server-methods/server-methods.test.ts index dfc11df94..fe666dcbc 100644 --- a/src/gateway/server-methods/server-methods.test.ts +++ b/src/gateway/server-methods/server-methods.test.ts @@ -16,6 +16,14 @@ import { sanitizeChatSendMessageInput } from "./chat.js"; import { createExecApprovalHandlers } from "./exec-approval.js"; import { logsHandlers } from "./logs.js"; +vi.mock("../../commands/status.js", () => ({ + getStatusSummary: vi.fn().mockResolvedValue({ ok: true }), +})); + +type HealthStatusHandlerParams = Parameters< + (typeof import("./health.js"))["healthHandlers"]["status"] +>[0]; + describe("waitForAgentJob", () => { it("maps lifecycle end events with aborted=true to timeout", async () => { const runId = `run-timeout-${Date.now()}-${Math.random().toString(36).slice(2)}`; @@ -446,6 +454,41 @@ describe("exec approval handlers", () => { }); }); +describe("gateway healthHandlers.status scope handling", () => { + beforeEach(async () => { + const status = await import("../../commands/status.js"); + vi.mocked(status.getStatusSummary).mockClear(); + }); + + it("requests redacted status for non-admin clients", async () => { + const respond = vi.fn(); + const status = await import("../../commands/status.js"); + const { healthHandlers } = await import("./health.js"); + + await healthHandlers.status({ + respond, + client: { connect: { role: "operator", scopes: ["operator.read"] } }, + } as HealthStatusHandlerParams); + + expect(vi.mocked(status.getStatusSummary)).toHaveBeenCalledWith({ includeSensitive: false }); + expect(respond).toHaveBeenCalledWith(true, { ok: true }, undefined); + }); + + it("requests full status for admin clients", async () => { + const respond = vi.fn(); + const status = await import("../../commands/status.js"); + const { healthHandlers } = await import("./health.js"); + + await healthHandlers.status({ + respond, + client: { connect: { role: "operator", scopes: ["operator.admin"] } }, + } as HealthStatusHandlerParams); + + expect(vi.mocked(status.getStatusSummary)).toHaveBeenCalledWith({ includeSensitive: true }); + expect(respond).toHaveBeenCalledWith(true, { ok: true }, undefined); + }); +}); + describe("logs.tail", () => { const logsNoop = () => false; diff --git a/src/signal/monitor/event-handler.mention-gating.test.ts b/src/signal/monitor/event-handler.mention-gating.test.ts index 6fb211f1f..7c45d3cf2 100644 --- a/src/signal/monitor/event-handler.mention-gating.test.ts +++ b/src/signal/monitor/event-handler.mention-gating.test.ts @@ -18,6 +18,7 @@ vi.mock("../../auto-reply/dispatch.js", async (importOriginal) => { }); import { createSignalEventHandler } from "./event-handler.js"; +import { renderSignalMentions } from "./mentions.js"; function createBaseDeps(overrides: Record = {}) { return { @@ -270,3 +271,34 @@ describe("signal mention gating", () => { expect(capturedCtx?.WasMentioned).toBe(true); }); }); + +describe("renderSignalMentions", () => { + const PLACEHOLDER = "\uFFFC"; + + it("returns the original message when no mentions are provided", () => { + const message = `${PLACEHOLDER} ping`; + expect(renderSignalMentions(message, null)).toBe(message); + expect(renderSignalMentions(message, [])).toBe(message); + }); + + it("replaces placeholder code points using mention metadata", () => { + const message = `${PLACEHOLDER} hi ${PLACEHOLDER}!`; + const normalized = renderSignalMentions(message, [ + { uuid: "abc-123", start: 0, length: 1 }, + { number: "+15550005555", start: message.lastIndexOf(PLACEHOLDER), length: 1 }, + ]); + + expect(normalized).toBe("@abc-123 hi @+15550005555!"); + }); + + it("skips mentions that lack identifiers or out-of-bounds spans", () => { + const message = `${PLACEHOLDER} hi`; + const normalized = renderSignalMentions(message, [ + { name: "ignored" }, + { uuid: "valid", start: 0, length: 1 }, + { number: "+1555", start: 999, length: 1 }, + ]); + + expect(normalized).toBe("@valid hi"); + }); +}); diff --git a/src/signal/monitor/mentions.test.ts b/src/signal/monitor/mentions.test.ts deleted file mode 100644 index 1a30f6d2c..000000000 --- a/src/signal/monitor/mentions.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { renderSignalMentions } from "./mentions.js"; - -const PLACEHOLDER = "\uFFFC"; - -describe("renderSignalMentions", () => { - it("returns the original message when no mentions are provided", () => { - const message = `${PLACEHOLDER} ping`; - expect(renderSignalMentions(message, null)).toBe(message); - expect(renderSignalMentions(message, [])).toBe(message); - }); - - it("replaces placeholder code points using mention metadata", () => { - const message = `${PLACEHOLDER} hi ${PLACEHOLDER}!`; - const normalized = renderSignalMentions(message, [ - { uuid: "abc-123", start: 0, length: 1 }, - { number: "+15550005555", start: message.lastIndexOf(PLACEHOLDER), length: 1 }, - ]); - - expect(normalized).toBe("@abc-123 hi @+15550005555!"); - }); - - it("skips mentions that lack identifiers or out-of-bounds spans", () => { - const message = `${PLACEHOLDER} hi`; - const normalized = renderSignalMentions(message, [ - { name: "ignored" }, - { uuid: "valid", start: 0, length: 1 }, - { number: "+1555", start: 999, length: 1 }, - ]); - - expect(normalized).toBe("@valid hi"); - }); -});