From 12432ca1389e12918c2d60a9393e8fde5192c588 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 20:50:09 +0000 Subject: [PATCH] test: share googlechat webhook routing helpers --- .../src/monitor.webhook-routing.test.ts | 92 +++++++++++-------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/extensions/googlechat/src/monitor.webhook-routing.test.ts b/extensions/googlechat/src/monitor.webhook-routing.test.ts index 812883f1b4c..9896efce645 100644 --- a/extensions/googlechat/src/monitor.webhook-routing.test.ts +++ b/extensions/googlechat/src/monitor.webhook-routing.test.ts @@ -117,6 +117,34 @@ function registerTwoTargets() { }; } +async function dispatchWebhookRequest(req: IncomingMessage) { + const res = createMockServerResponse(); + const handled = await handleGoogleChatWebhookRequest(req, res); + expect(handled).toBe(true); + return res; +} + +async function expectVerifiedRoute(params: { + request: IncomingMessage; + expectedStatus: number; + sinkA: ReturnType; + sinkB: ReturnType; + expectedSink: "none" | "A" | "B"; +}) { + const res = await dispatchWebhookRequest(params.request); + expect(res.statusCode).toBe(params.expectedStatus); + const expectedCounts = + params.expectedSink === "A" ? [1, 0] : params.expectedSink === "B" ? [0, 1] : [0, 0]; + expect(params.sinkA).toHaveBeenCalledTimes(expectedCounts[0]); + expect(params.sinkB).toHaveBeenCalledTimes(expectedCounts[1]); +} + +function mockSecondVerifierSuccess() { + vi.mocked(verifyGoogleChatRequest) + .mockResolvedValueOnce({ ok: false, reason: "invalid" }) + .mockResolvedValueOnce({ ok: true }); +} + describe("Google Chat webhook routing", () => { afterEach(() => { setActivePluginRegistry(createEmptyPluginRegistry()); @@ -165,45 +193,37 @@ describe("Google Chat webhook routing", () => { const { sinkA, sinkB, unregister } = registerTwoTargets(); try { - const res = createMockServerResponse(); - const handled = await handleGoogleChatWebhookRequest( - createWebhookRequest({ + await expectVerifiedRoute({ + request: createWebhookRequest({ authorization: "Bearer test-token", payload: { type: "ADDED_TO_SPACE", space: { name: "spaces/AAA" } }, }), - res, - ); - - expect(handled).toBe(true); - expect(res.statusCode).toBe(401); - expect(sinkA).not.toHaveBeenCalled(); - expect(sinkB).not.toHaveBeenCalled(); + expectedStatus: 401, + sinkA, + sinkB, + expectedSink: "none", + }); } finally { unregister(); } }); it("routes to the single verified target when earlier targets fail verification", async () => { - vi.mocked(verifyGoogleChatRequest) - .mockResolvedValueOnce({ ok: false, reason: "invalid" }) - .mockResolvedValueOnce({ ok: true }); + mockSecondVerifierSuccess(); const { sinkA, sinkB, unregister } = registerTwoTargets(); try { - const res = createMockServerResponse(); - const handled = await handleGoogleChatWebhookRequest( - createWebhookRequest({ + await expectVerifiedRoute({ + request: createWebhookRequest({ authorization: "Bearer test-token", payload: { type: "ADDED_TO_SPACE", space: { name: "spaces/BBB" } }, }), - res, - ); - - expect(handled).toBe(true); - expect(res.statusCode).toBe(200); - expect(sinkA).not.toHaveBeenCalled(); - expect(sinkB).toHaveBeenCalledTimes(1); + expectedStatus: 200, + sinkA, + sinkB, + expectedSink: "B", + }); } finally { unregister(); } @@ -218,10 +238,7 @@ describe("Google Chat webhook routing", () => { authorization: "Bearer invalid-token", }); const onSpy = vi.spyOn(req, "on"); - const res = createMockServerResponse(); - const handled = await handleGoogleChatWebhookRequest(req, res); - - expect(handled).toBe(true); + const res = await dispatchWebhookRequest(req); expect(res.statusCode).toBe(401); expect(onSpy).not.toHaveBeenCalledWith("data", expect.any(Function)); } finally { @@ -230,15 +247,12 @@ describe("Google Chat webhook routing", () => { }); it("supports add-on requests that provide systemIdToken in the body", async () => { - vi.mocked(verifyGoogleChatRequest) - .mockResolvedValueOnce({ ok: false, reason: "invalid" }) - .mockResolvedValueOnce({ ok: true }); + mockSecondVerifierSuccess(); const { sinkA, sinkB, unregister } = registerTwoTargets(); try { - const res = createMockServerResponse(); - const handled = await handleGoogleChatWebhookRequest( - createWebhookRequest({ + await expectVerifiedRoute({ + request: createWebhookRequest({ payload: { commonEventObject: { hostApp: "CHAT" }, authorizationEventObject: { systemIdToken: "addon-token" }, @@ -252,13 +266,11 @@ describe("Google Chat webhook routing", () => { }, }, }), - res, - ); - - expect(handled).toBe(true); - expect(res.statusCode).toBe(200); - expect(sinkA).not.toHaveBeenCalled(); - expect(sinkB).toHaveBeenCalledTimes(1); + expectedStatus: 200, + sinkA, + sinkB, + expectedSink: "B", + }); } finally { unregister(); }