test(zalo): share webhook replay post helpers

This commit is contained in:
Vincent Koc
2026-04-12 08:38:28 +01:00
parent 38b72a6ae0
commit f4697f7b0d

View File

@@ -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);