openclaw/extensions/signal/src/client.test.ts
scoootscooob 4540c6b3bc
refactor(signal): move Signal channel code to extensions/signal/src/ (#45531)
Move all Signal channel implementation files from src/signal/ to
extensions/signal/src/ and replace originals with re-export shims.
This continues the channel plugin migration pattern used by other
extensions, keeping backward compatibility via shims while the real
code lives in the extension.

- Copy 32 .ts files (source + tests) to extensions/signal/src/
- Transform all relative import paths for the new location
- Create 2-line re-export shims in src/signal/ for each moved file
- Preserve existing extension files (channel.ts, runtime.ts, etc.)
- Change tsconfig.plugin-sdk.dts.json rootDir from "src" to "."
  to support cross-boundary re-exports from extensions/
2026-03-14 02:42:48 -07:00

68 lines
2.0 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const fetchWithTimeoutMock = vi.fn();
const resolveFetchMock = vi.fn();
vi.mock("../../../src/infra/fetch.js", () => ({
resolveFetch: (...args: unknown[]) => resolveFetchMock(...args),
}));
vi.mock("../../../src/infra/secure-random.js", () => ({
generateSecureUuid: () => "test-id",
}));
vi.mock("../../../src/utils/fetch-timeout.js", () => ({
fetchWithTimeout: (...args: unknown[]) => fetchWithTimeoutMock(...args),
}));
import { signalRpcRequest } from "./client.js";
function rpcResponse(body: unknown, status = 200): Response {
if (typeof body === "string") {
return new Response(body, { status });
}
return new Response(JSON.stringify(body), { status });
}
describe("signalRpcRequest", () => {
beforeEach(() => {
vi.clearAllMocks();
resolveFetchMock.mockReturnValue(vi.fn());
});
it("returns parsed RPC result", async () => {
fetchWithTimeoutMock.mockResolvedValueOnce(
rpcResponse({ jsonrpc: "2.0", result: { version: "0.13.22" }, id: "test-id" }),
);
const result = await signalRpcRequest<{ version: string }>("version", undefined, {
baseUrl: "http://127.0.0.1:8080",
});
expect(result).toEqual({ version: "0.13.22" });
});
it("throws a wrapped error when RPC response JSON is malformed", async () => {
fetchWithTimeoutMock.mockResolvedValueOnce(rpcResponse("not-json", 502));
await expect(
signalRpcRequest("version", undefined, {
baseUrl: "http://127.0.0.1:8080",
}),
).rejects.toMatchObject({
message: "Signal RPC returned malformed JSON (status 502)",
cause: expect.any(SyntaxError),
});
});
it("throws when RPC response envelope has neither result nor error", async () => {
fetchWithTimeoutMock.mockResolvedValueOnce(rpcResponse({ jsonrpc: "2.0", id: "test-id" }));
await expect(
signalRpcRequest("version", undefined, {
baseUrl: "http://127.0.0.1:8080",
}),
).rejects.toThrow("Signal RPC returned invalid response envelope (status 200)");
});
});