diff --git a/extensions/zalo/src/monitor.webhook.test.ts b/extensions/zalo/src/monitor.webhook.test.ts index 4a150c0b4c6..27ac082124e 100644 --- a/extensions/zalo/src/monitor.webhook.test.ts +++ b/extensions/zalo/src/monitor.webhook.test.ts @@ -111,6 +111,44 @@ async function postUntilRateLimited(params: { return false; } +async function postWebhookJson(params: { + baseUrl: string; + path: string; + secret: string; + payload: unknown; +}) { + return fetch(`${params.baseUrl}${params.path}`, { + method: "POST", + headers: { + "x-bot-api-secret-token": params.secret, + "content-type": "application/json", + }, + body: JSON.stringify(params.payload), + }); +} + +async function expectTwoWebhookPostsOk(params: { + baseUrl: string; + first: { path: string; secret: string; payload: unknown }; + second: { path: string; secret: string; payload: unknown }; +}) { + const first = await postWebhookJson({ + baseUrl: params.baseUrl, + path: params.first.path, + secret: params.first.secret, + payload: params.first.payload, + }); + const second = await postWebhookJson({ + baseUrl: params.baseUrl, + path: params.second.path, + secret: params.second.secret, + payload: params.second.payload, + }); + + expect(first.status).toBe(200); + expect(second.status).toBe(200); +} + describe("handleZaloWebhookRequest", () => { afterEach(() => { clearZaloWebhookSecurityStateForTest(); @@ -242,25 +280,11 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - const first = await fetch(`${baseUrl}/hook-replay-scope`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret-a", - "content-type": "application/json", - }, - body: JSON.stringify(payload), + await expectTwoWebhookPostsOk({ + baseUrl, + first: { path: "/hook-replay-scope", secret: "secret-a", payload }, + second: { path: "/hook-replay-scope", secret: "secret-b", payload }, }); - const second = await fetch(`${baseUrl}/hook-replay-scope`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret-b", - "content-type": "application/json", - }, - body: JSON.stringify(payload), - }); - - expect(first.status).toBe(200); - expect(second.status).toBe(200); }); expect(sinkA).toHaveBeenCalledTimes(1); @@ -291,25 +315,11 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - const first = await fetch(`${baseUrl}/hook-replay-chat-scope`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret", - "content-type": "application/json", - }, - body: JSON.stringify(firstPayload), + await expectTwoWebhookPostsOk({ + baseUrl, + first: { path: "/hook-replay-chat-scope", secret: "secret", payload: firstPayload }, + second: { path: "/hook-replay-chat-scope", secret: "secret", payload: secondPayload }, }); - const second = await fetch(`${baseUrl}/hook-replay-chat-scope`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret", - "content-type": "application/json", - }, - body: JSON.stringify(secondPayload), - }); - - expect(first.status).toBe(200); - expect(second.status).toBe(200); }); expect(sink).toHaveBeenCalledTimes(2); @@ -338,25 +348,11 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - const first = await fetch(`${baseUrl}/hook-replay-sender-scope`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret", - "content-type": "application/json", - }, - body: JSON.stringify(firstPayload), + await expectTwoWebhookPostsOk({ + baseUrl, + first: { path: "/hook-replay-sender-scope", secret: "secret", payload: firstPayload }, + second: { path: "/hook-replay-sender-scope", secret: "secret", payload: secondPayload }, }); - const second = await fetch(`${baseUrl}/hook-replay-sender-scope`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret", - "content-type": "application/json", - }, - body: JSON.stringify(secondPayload), - }); - - expect(first.status).toBe(200); - expect(second.status).toBe(200); }); expect(sink).toHaveBeenCalledTimes(2); @@ -429,25 +425,11 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - const first = await fetch(`${baseUrl}/hook-replay-collision:a`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret-a", - "content-type": "application/json", - }, - body: JSON.stringify(payload), + await expectTwoWebhookPostsOk({ + baseUrl, + first: { path: "/hook-replay-collision:a", secret: "secret-a", payload }, + second: { path: "/hook-replay-collision", secret: "secret-b", payload }, }); - const second = await fetch(`${baseUrl}/hook-replay-collision`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret-b", - "content-type": "application/json", - }, - body: JSON.stringify(payload), - }); - - expect(first.status).toBe(200); - expect(second.status).toBe(200); }); expect(sinkA).toHaveBeenCalledTimes(1); @@ -482,25 +464,11 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - const first = await fetch(`${baseUrl}/hook-replay-scope-a`, { - method: "POST", - headers: { - "x-bot-api-secret-token": sharedSecret, - "content-type": "application/json", - }, - body: JSON.stringify(payload), + await expectTwoWebhookPostsOk({ + baseUrl, + first: { path: "/hook-replay-scope-a", secret: sharedSecret, payload }, + second: { path: "/hook-replay-scope-b", secret: sharedSecret, payload }, }); - const second = await fetch(`${baseUrl}/hook-replay-scope-b`, { - method: "POST", - headers: { - "x-bot-api-secret-token": sharedSecret, - "content-type": "application/json", - }, - body: JSON.stringify(payload), - }); - - expect(first.status).toBe(200); - expect(second.status).toBe(200); }); expect(sinkA).toHaveBeenCalledTimes(1);