Files
horus-3d/tests/unit/sessionSettings.test.ts
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

113 lines
3.3 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import {
isWebchatSessionMutationBlockedError,
syncGatewaySessionSettings,
} from "@/lib/gateway/GatewayClient";
import type { GatewayClient } from "@/lib/gateway/GatewayClient";
import { GatewayResponseError } from "@/lib/gateway/errors";
describe("session settings sync helper", () => {
it("detects webchat session mutation blocked gateway errors", () => {
const blocked = new GatewayResponseError({
code: "INVALID_REQUEST",
message: "webchat clients cannot patch sessions; use chat.send for session-scoped updates",
});
expect(isWebchatSessionMutationBlockedError(blocked)).toBe(true);
});
it("does not misclassify unrelated invalid request errors", () => {
const invalid = new GatewayResponseError({
code: "INVALID_REQUEST",
message: "invalid model ref",
});
expect(isWebchatSessionMutationBlockedError(invalid)).toBe(false);
});
it("does not misclassify non-gateway errors", () => {
expect(
isWebchatSessionMutationBlockedError(
new Error("webchat clients cannot patch sessions; use chat.send for session-scoped updates")
)
).toBe(false);
});
it("throws when session key is missing", async () => {
const client = { call: vi.fn() } as unknown as GatewayClient;
await expect(
syncGatewaySessionSettings({
client,
sessionKey: "",
model: "openai/gpt-5",
})
).rejects.toThrow("Session key is required.");
});
it("throws when no settings are provided", async () => {
const client = { call: vi.fn() } as unknown as GatewayClient;
await expect(
syncGatewaySessionSettings({
client,
sessionKey: "agent:1:studio:abc",
})
).rejects.toThrow("At least one session setting must be provided.");
});
it("patches model and thinking level together", async () => {
const client = {
call: vi.fn(async () => ({ ok: true })),
} as unknown as GatewayClient;
await syncGatewaySessionSettings({
client,
sessionKey: "agent:1:studio:abc",
model: "openai/gpt-5",
thinkingLevel: "medium",
});
expect(client.call).toHaveBeenCalledWith("sessions.patch", {
key: "agent:1:studio:abc",
model: "openai/gpt-5",
thinkingLevel: "medium",
});
});
it("patches only model when thinking is omitted", async () => {
const client = {
call: vi.fn(async () => ({ ok: true })),
} as unknown as GatewayClient;
await syncGatewaySessionSettings({
client,
sessionKey: "agent:1:studio:abc",
model: null,
});
expect(client.call).toHaveBeenCalledWith("sessions.patch", {
key: "agent:1:studio:abc",
model: null,
});
});
it("patches exec session overrides without model settings", async () => {
const client = {
call: vi.fn(async () => ({ ok: true })),
} as unknown as GatewayClient;
await syncGatewaySessionSettings({
client,
sessionKey: "agent:1:studio:abc",
execHost: "gateway",
execSecurity: "allowlist",
execAsk: "always",
});
expect(client.call).toHaveBeenCalledWith("sessions.patch", {
key: "agent:1:studio:abc",
execHost: "gateway",
execSecurity: "allowlist",
execAsk: "always",
});
});
});