From a9fa43419128718fdddf3fbdb47ed98167a10001 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 22:08:04 +0000 Subject: [PATCH] test(discord): share provider lifecycle test harness --- .../monitor/provider.lifecycle.test.ts | 71 +++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/src/discord/monitor/provider.lifecycle.test.ts b/src/discord/monitor/provider.lifecycle.test.ts index 1221af69d..845e4e114 100644 --- a/src/discord/monitor/provider.lifecycle.test.ts +++ b/src/discord/monitor/provider.lifecycle.test.ts @@ -45,18 +45,20 @@ describe("runDiscordGatewayLifecycle", () => { stopGatewayLoggingMock.mockClear(); }); - it("cleans up thread bindings when exec approvals startup fails", async () => { - const { runDiscordGatewayLifecycle } = await import("./provider.lifecycle.js"); - - const start = vi.fn(async () => { - throw new Error("startup failed"); - }); - const stop = vi.fn(async () => undefined); + const createLifecycleHarness = (params?: { + accountId?: string; + start?: () => Promise; + stop?: () => Promise; + }) => { + const start = vi.fn(params?.start ?? (async () => undefined)); + const stop = vi.fn(params?.stop ?? (async () => undefined)); const threadStop = vi.fn(); - - await expect( - runDiscordGatewayLifecycle({ - accountId: "default", + return { + start, + stop, + threadStop, + lifecycleParams: { + accountId: params?.accountId ?? "default", client: { getPlugin: vi.fn(() => undefined) } as unknown as Client, runtime: {} as RuntimeEnv, isDisallowedIntentsError: () => false, @@ -64,8 +66,19 @@ describe("runDiscordGatewayLifecycle", () => { voiceManagerRef: { current: null }, execApprovalsHandler: { start, stop }, threadBindings: { stop: threadStop }, - }), - ).rejects.toThrow("startup failed"); + }, + }; + }; + + it("cleans up thread bindings when exec approvals startup fails", async () => { + const { runDiscordGatewayLifecycle } = await import("./provider.lifecycle.js"); + const { lifecycleParams, start, stop, threadStop } = createLifecycleHarness({ + start: async () => { + throw new Error("startup failed"); + }, + }); + + await expect(runDiscordGatewayLifecycle(lifecycleParams)).rejects.toThrow("startup failed"); expect(start).toHaveBeenCalledTimes(1); expect(stop).toHaveBeenCalledTimes(1); @@ -78,23 +91,25 @@ describe("runDiscordGatewayLifecycle", () => { it("cleans up when gateway wait fails after startup", async () => { const { runDiscordGatewayLifecycle } = await import("./provider.lifecycle.js"); waitForDiscordGatewayStopMock.mockRejectedValueOnce(new Error("gateway wait failed")); + const { lifecycleParams, start, stop, threadStop } = createLifecycleHarness(); - const start = vi.fn(async () => undefined); - const stop = vi.fn(async () => undefined); - const threadStop = vi.fn(); + await expect(runDiscordGatewayLifecycle(lifecycleParams)).rejects.toThrow( + "gateway wait failed", + ); - await expect( - runDiscordGatewayLifecycle({ - accountId: "default", - client: { getPlugin: vi.fn(() => undefined) } as unknown as Client, - runtime: {} as RuntimeEnv, - isDisallowedIntentsError: () => false, - voiceManager: null, - voiceManagerRef: { current: null }, - execApprovalsHandler: { start, stop }, - threadBindings: { stop: threadStop }, - }), - ).rejects.toThrow("gateway wait failed"); + expect(start).toHaveBeenCalledTimes(1); + expect(stop).toHaveBeenCalledTimes(1); + expect(waitForDiscordGatewayStopMock).toHaveBeenCalledTimes(1); + expect(unregisterGatewayMock).toHaveBeenCalledWith("default"); + expect(stopGatewayLoggingMock).toHaveBeenCalledTimes(1); + expect(threadStop).toHaveBeenCalledTimes(1); + }); + + it("cleans up after successful gateway wait", async () => { + const { runDiscordGatewayLifecycle } = await import("./provider.lifecycle.js"); + const { lifecycleParams, start, stop, threadStop } = createLifecycleHarness(); + + await expect(runDiscordGatewayLifecycle(lifecycleParams)).resolves.toBeUndefined(); expect(start).toHaveBeenCalledTimes(1); expect(stop).toHaveBeenCalledTimes(1);