Skip to content

Commit f000384

Browse files
committed
test: 100% coverage
1 parent dc800a2 commit f000384

File tree

1 file changed

+230
-4
lines changed

1 file changed

+230
-4
lines changed

test/integration/node-middleware.test.ts

Lines changed: 230 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { createServer } from "http";
22

33
import fetch from "node-fetch";
4+
import express from "express";
45

56
import { Webhooks, createNodeMiddleware, sign } from "../../src";
6-
import { EmitterWebhookEvent } from "../../src/types";
77
import { pushEventPayload } from "../fixtures";
88

99
const signatureSha256 = sign(
@@ -12,10 +12,10 @@ const signatureSha256 = sign(
1212
);
1313

1414
describe("createNodeMiddleware(webhooks)", () => {
15-
it("README example", async () => {
15+
test("README example", async () => {
1616
expect.assertions(3);
1717

18-
const webhooks = new Webhooks<EmitterWebhookEvent>({
18+
const webhooks = new Webhooks({
1919
secret: "mySecret",
2020
});
2121

@@ -50,7 +50,7 @@ describe("createNodeMiddleware(webhooks)", () => {
5050
test("request.body already parsed (e.g. Lambda)", async () => {
5151
expect.assertions(3);
5252

53-
const webhooks = new Webhooks<EmitterWebhookEvent>({
53+
const webhooks = new Webhooks({
5454
secret: "mySecret",
5555
});
5656
const dataChunks: any[] = [];
@@ -89,4 +89,230 @@ describe("createNodeMiddleware(webhooks)", () => {
8989

9090
server.close();
9191
});
92+
93+
test("Handles invalid JSON", async () => {
94+
const webhooks = new Webhooks({
95+
secret: "mySecret",
96+
});
97+
98+
const server = createServer(createNodeMiddleware(webhooks)).listen();
99+
100+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
101+
const { port } = server.address();
102+
103+
const response = await fetch(
104+
`http://localhost:${port}/api/github/webhooks`,
105+
{
106+
method: "POST",
107+
headers: {
108+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
109+
"X-GitHub-Event": "push",
110+
"X-Hub-Signature-256": signatureSha256,
111+
},
112+
body: "invalid",
113+
}
114+
);
115+
116+
expect(response.status).toEqual(400);
117+
118+
await expect(response.text()).resolves.toMatch(/SyntaxError: Invalid JSON/);
119+
120+
server.close();
121+
});
122+
123+
test("Handles non POST request", async () => {
124+
const webhooks = new Webhooks({
125+
secret: "mySecret",
126+
});
127+
128+
const server = createServer(createNodeMiddleware(webhooks)).listen();
129+
130+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
131+
const { port } = server.address();
132+
133+
const response = await fetch(
134+
`http://localhost:${port}/api/github/webhooks`,
135+
{
136+
method: "PUT",
137+
headers: {
138+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
139+
"X-GitHub-Event": "push",
140+
"X-Hub-Signature-256": signatureSha256,
141+
},
142+
body: "invalid",
143+
}
144+
);
145+
146+
expect(response.status).toEqual(404);
147+
148+
await expect(response.text()).resolves.toMatch(
149+
/Unknown route: PUT \/api\/github\/webhooks/
150+
);
151+
152+
server.close();
153+
});
154+
155+
test("Handles missing headers", async () => {
156+
const webhooks = new Webhooks({
157+
secret: "mySecret",
158+
});
159+
160+
const server = createServer(createNodeMiddleware(webhooks)).listen();
161+
162+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
163+
const { port } = server.address();
164+
165+
const response = await fetch(
166+
`http://localhost:${port}/api/github/webhooks`,
167+
{
168+
method: "POST",
169+
headers: {
170+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
171+
// "X-GitHub-Event": "push",
172+
"X-Hub-Signature-256": signatureSha256,
173+
},
174+
body: "invalid",
175+
}
176+
);
177+
178+
expect(response.status).toEqual(400);
179+
180+
await expect(response.text()).resolves.toMatch(
181+
/Required headers missing: x-github-event/
182+
);
183+
184+
server.close();
185+
});
186+
187+
test("Handles non-request errors", async () => {
188+
const webhooks = new Webhooks({
189+
secret: "mySecret",
190+
});
191+
192+
webhooks.on("push", () => {
193+
throw new Error("boom");
194+
});
195+
196+
const server = createServer(createNodeMiddleware(webhooks)).listen();
197+
198+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
199+
const { port } = server.address();
200+
201+
const response = await fetch(
202+
`http://localhost:${port}/api/github/webhooks`,
203+
{
204+
method: "POST",
205+
headers: {
206+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
207+
"X-GitHub-Event": "push",
208+
"X-Hub-Signature-256": signatureSha256,
209+
},
210+
body: JSON.stringify(pushEventPayload),
211+
}
212+
);
213+
214+
await expect(response.text()).resolves.toMatch(/boom/);
215+
expect(response.status).toEqual(500);
216+
217+
server.close();
218+
});
219+
220+
test("Handles timeout", async () => {
221+
jest.useFakeTimers();
222+
223+
const webhooks = new Webhooks({
224+
secret: "mySecret",
225+
});
226+
227+
webhooks.on("push", async () => {
228+
jest.advanceTimersByTime(10000);
229+
server.close();
230+
});
231+
232+
const server = createServer(createNodeMiddleware(webhooks)).listen();
233+
234+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
235+
const { port } = server.address();
236+
237+
const response = await fetch(
238+
`http://localhost:${port}/api/github/webhooks`,
239+
{
240+
method: "POST",
241+
headers: {
242+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
243+
"X-GitHub-Event": "push",
244+
"X-Hub-Signature-256": signatureSha256,
245+
},
246+
body: JSON.stringify(pushEventPayload),
247+
}
248+
);
249+
250+
await expect(response.text()).resolves.toMatch(/still processing/);
251+
expect(response.status).toEqual(202);
252+
});
253+
254+
test("Handles timeout with error", async () => {
255+
jest.useFakeTimers();
256+
257+
const webhooks = new Webhooks({
258+
secret: "mySecret",
259+
});
260+
261+
webhooks.on("push", async () => {
262+
jest.advanceTimersByTime(10000);
263+
server.close();
264+
throw new Error("oops");
265+
});
266+
267+
const server = createServer(createNodeMiddleware(webhooks)).listen();
268+
269+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
270+
const { port } = server.address();
271+
272+
const response = await fetch(
273+
`http://localhost:${port}/api/github/webhooks`,
274+
{
275+
method: "POST",
276+
headers: {
277+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
278+
"X-GitHub-Event": "push",
279+
"X-Hub-Signature-256": signatureSha256,
280+
},
281+
body: JSON.stringify(pushEventPayload),
282+
}
283+
);
284+
285+
await expect(response.text()).resolves.toMatch(/still processing/);
286+
expect(response.status).toEqual(202);
287+
});
288+
289+
test("express middleware 404", async () => {
290+
const app = express();
291+
const webhooks = new Webhooks({
292+
secret: "mySecret",
293+
});
294+
295+
app.post("/test", createNodeMiddleware(webhooks));
296+
app.all("*", (...[, response]) => response.status(404).send("Dafuq"));
297+
298+
const server = app.listen();
299+
300+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
301+
const { port } = server.address();
302+
303+
const response = await fetch(`http://localhost:${port}/test`, {
304+
method: "POST",
305+
headers: {
306+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
307+
"X-GitHub-Event": "push",
308+
"X-Hub-Signature-256": signatureSha256,
309+
},
310+
body: JSON.stringify(pushEventPayload),
311+
});
312+
313+
await expect(response.text()).resolves.toBe("ok\n");
314+
expect(response.status).toEqual(200);
315+
316+
server.close();
317+
});
92318
});

0 commit comments

Comments
 (0)