Implement RPC contract validation baseline
This commit is contained in:
33
packages/contracts/src/rpcSchemas.test.ts
Normal file
33
packages/contracts/src/rpcSchemas.test.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user