mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
87 lines
3 KiB
TypeScript
87 lines
3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import type { AppServerClientHandlers, AppServerClientOptions } from "../../src/app-server/connection/client";
|
|
import { withShortLivedAppServerClient } from "../../src/app-server/connection/short-lived-client";
|
|
|
|
const clientMocks = vi.hoisted(() => ({
|
|
connect: vi.fn<() => Promise<unknown>>(),
|
|
disconnect: vi.fn<() => void>(),
|
|
options: [] as AppServerClientOptions[],
|
|
}));
|
|
|
|
vi.mock("../../src/app-server/connection/client", () => ({
|
|
AppServerClient: class {
|
|
constructor(options: AppServerClientOptions) {
|
|
clientMocks.options.push(options);
|
|
}
|
|
|
|
connect = clientMocks.connect;
|
|
disconnect = clientMocks.disconnect;
|
|
},
|
|
}));
|
|
|
|
describe("withShortLivedAppServerClient", () => {
|
|
beforeEach(() => {
|
|
clientMocks.connect.mockReset().mockResolvedValue({});
|
|
clientMocks.disconnect.mockReset();
|
|
clientMocks.options.length = 0;
|
|
});
|
|
|
|
it("connects, runs the operation, and disconnects in lifecycle order", async () => {
|
|
const lifecycle: string[] = [];
|
|
clientMocks.connect.mockImplementation(async () => {
|
|
lifecycle.push("connect");
|
|
});
|
|
clientMocks.disconnect.mockImplementation(() => {
|
|
lifecycle.push("disconnect");
|
|
});
|
|
|
|
await expect(
|
|
withShortLivedAppServerClient("/opt/codex", "/vault", async (client) => {
|
|
lifecycle.push("operation");
|
|
return client;
|
|
}),
|
|
).resolves.toBeDefined();
|
|
|
|
expect(lifecycle).toEqual(["connect", "operation", "disconnect"]);
|
|
expect(clientMocks.options[0]).toMatchObject({ codexPath: "/opt/codex", cwd: "/vault" });
|
|
});
|
|
|
|
it.each([
|
|
["connect", () => clientMocks.connect.mockRejectedValue(new Error("connect failed"))],
|
|
["operation", () => undefined],
|
|
])("disconnects when %s fails", async (failure, arrange) => {
|
|
arrange();
|
|
|
|
const operation = vi.fn(async () => {
|
|
throw new Error("operation failed");
|
|
});
|
|
await expect(withShortLivedAppServerClient("/opt/codex", "/vault", failure === "connect" ? vi.fn() : operation)).rejects.toThrow(
|
|
`${failure} failed`,
|
|
);
|
|
|
|
expect(clientMocks.disconnect).toHaveBeenCalledOnce();
|
|
expect(operation).toHaveBeenCalledTimes(failure === "connect" ? 0 : 1);
|
|
});
|
|
|
|
it.each([
|
|
[undefined, "This Codex Panel view does not handle server requests."],
|
|
[
|
|
{ serverRequests: { kind: "reject" as const, message: "Background operation cannot answer." } },
|
|
"Background operation cannot answer.",
|
|
],
|
|
])("rejects server requests with the configured policy message", async (options, expectedMessage) => {
|
|
await withShortLivedAppServerClient("/opt/codex", "/vault", async () => undefined, options);
|
|
const reject = vi.fn();
|
|
|
|
clientHandlers().onServerRequest({} as never, { respond: vi.fn(), reject });
|
|
|
|
expect(reject).toHaveBeenCalledWith(-32601, expectedMessage);
|
|
});
|
|
});
|
|
|
|
function clientHandlers(): AppServerClientHandlers {
|
|
const handlers = clientMocks.options[0]?.handlers;
|
|
if (!handlers) throw new Error("Expected a short-lived client to be constructed.");
|
|
return handlers;
|
|
}
|