import { describe, expect, it } from "vitest"; import { RpcRequestSchemas, RpcResponseSchemas, parseRpcRequest } from "./rpcSchemas.js"; describe("RPC schemas", () => { it("defines request and response schemas for every method", () => { expect(Object.keys(RpcRequestSchemas).sort()).toEqual(Object.keys(RpcResponseSchemas).sort()); }); it("accepts valid payloads and trims bounded strings", () => { expect(parseRpcRequest("portfolio.addHolding", { ticker: " cost " })).toEqual({ ticker: "cost" }); expect(parseRpcRequest("model.updateCell", { companyId: "cost", tab: "base", row: 0, col: 1, value: "42" })).toEqual({ companyId: "cost", tab: "base", row: 0, col: 1, value: "42", }); }); it("rejects invalid payloads", () => { expect(() => parseRpcRequest("portfolio.addHolding", { ticker: "" })).toThrow(); expect(() => parseRpcRequest("model.updateCell", { companyId: "cost", tab: "base", row: -1, col: 0, value: "42" })).toThrow(); }); it("rejects scope-mismatched settings updates", () => { expect(() => parseRpcRequest("settings.update", { scope: "client", changes: { sidebarWidth: 40 } })).toThrow(); expect(() => parseRpcRequest("settings.update", { scope: "server", changes: { dataSources: { sec: "yes" } } })).toThrow(); }); it("catches malformed handler output", () => { expect(RpcResponseSchemas["memo.updateSection"].safeParse({ section: {}, status: "draft", savedAt: "now" }).success).toBe(false); }); });