103 lines
3.3 KiB
TypeScript
103 lines
3.3 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const fakes = vi.hoisted(() => {
|
|
const stop = vi.fn(async () => {
|
|
throw new Error("stop failed");
|
|
});
|
|
return {
|
|
stop,
|
|
closeBrowser: vi.fn(async () => {}),
|
|
startChannelsOverRealtimeGateway: vi.fn(async () => ({ stop })),
|
|
bot: {
|
|
onMention: vi.fn(),
|
|
onModalSubmit: vi.fn(),
|
|
onThreadStarted: vi.fn(),
|
|
},
|
|
};
|
|
});
|
|
|
|
vi.mock("@copilotkit/channels", () => ({
|
|
createBot: vi.fn(() => fakes.bot),
|
|
}));
|
|
vi.mock("@copilotkit/channels-slack", () => ({
|
|
defaultSlackTools: [],
|
|
defaultSlackContext: [],
|
|
SanitizingHttpAgent: function SanitizingHttpAgent() {},
|
|
}));
|
|
vi.mock("@copilotkit/channels-intelligence", () => ({
|
|
startChannelsOverRealtimeGateway: fakes.startChannelsOverRealtimeGateway,
|
|
}));
|
|
vi.mock("./tools/index.js", () => ({ appTools: [] }));
|
|
vi.mock("./context/app-context.js", () => ({ appContext: [] }));
|
|
vi.mock("./commands/index.js", () => ({ appCommands: [] }));
|
|
vi.mock("./sender-context.js", () => ({ senderContext: vi.fn() }));
|
|
vi.mock("./modals/file-issue.js", () => ({
|
|
fileIssueSubmit: vi.fn(),
|
|
FILE_ISSUE_CALLBACK: "file-issue",
|
|
}));
|
|
vi.mock("./render/browser.js", () => ({ closeBrowser: fakes.closeBrowser }));
|
|
|
|
const envKeys = [
|
|
"AGENT_URL",
|
|
"INTELLIGENCE_PROJECT_ID",
|
|
"INTELLIGENCE_CHANNEL_NAME",
|
|
"INTELLIGENCE_GATEWAY_WS_URL",
|
|
"INTELLIGENCE_API_KEY",
|
|
"INTELLIGENCE_ORG_ID",
|
|
"INTELLIGENCE_CHANNEL_ID",
|
|
] as const;
|
|
|
|
describe("channel entrypoint shutdown", () => {
|
|
const previousEnv = new Map<string, string | undefined>();
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
for (const key of envKeys) {
|
|
const value = previousEnv.get(key);
|
|
if (value === undefined) delete process.env[key];
|
|
else process.env[key] = value;
|
|
}
|
|
previousEnv.clear();
|
|
});
|
|
|
|
it("exits nonzero when stopping the channel runtime fails", async () => {
|
|
for (const key of envKeys) previousEnv.set(key, process.env[key]);
|
|
process.env.AGENT_URL = "http://agent.test/run";
|
|
process.env.INTELLIGENCE_PROJECT_ID = "7";
|
|
process.env.INTELLIGENCE_CHANNEL_NAME = "opentag";
|
|
process.env.INTELLIGENCE_GATEWAY_WS_URL = "wss://gateway.test/runner";
|
|
process.env.INTELLIGENCE_API_KEY = "cpk-test";
|
|
process.env.INTELLIGENCE_ORG_ID = "org_1";
|
|
process.env.INTELLIGENCE_CHANNEL_ID = "channel_1";
|
|
|
|
let sigterm: (() => void) | undefined;
|
|
vi.spyOn(process, "on").mockImplementation(((event, listener) => {
|
|
if (event === "SIGTERM") sigterm = listener as () => void;
|
|
return process;
|
|
}) as typeof process.on);
|
|
const exit = vi
|
|
.spyOn(process, "exit")
|
|
.mockImplementation((() => undefined as never) as typeof process.exit);
|
|
vi.spyOn(console, "log").mockImplementation(() => {});
|
|
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
|
|
await import("./managed.js");
|
|
await vi.waitFor(() => expect(sigterm).toBeTypeOf("function"));
|
|
expect(fakes.startChannelsOverRealtimeGateway).toHaveBeenCalledWith(
|
|
[fakes.bot],
|
|
expect.objectContaining({
|
|
scope: expect.objectContaining({
|
|
channelId: "channel_1",
|
|
channelName: "opentag",
|
|
}),
|
|
}),
|
|
);
|
|
sigterm!();
|
|
await vi.waitFor(() => expect(exit).toHaveBeenCalled());
|
|
|
|
expect(fakes.stop).toHaveBeenCalledOnce();
|
|
expect(fakes.closeBrowser).toHaveBeenCalledOnce();
|
|
expect(exit).toHaveBeenCalledWith(1);
|
|
});
|
|
});
|