-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathdevhook.test.ts
More file actions
100 lines (82 loc) · 3.05 KB
/
devhook.test.ts
File metadata and controls
100 lines (82 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { expect, test } from "bun:test";
import { serve } from "../test";
test("devhook url with createRequestURL", async () => {
const { helpers, bindings } = await serve();
const { client } = await helpers.createUser();
const id = crypto.randomUUID();
const url = await client.devhook.getUrl(id);
expect(url).toBe(
bindings.createRequestURL!(id).toString().replace(/\/$/, "")
);
});
test("devhook url with path-based routing", async () => {
const { helpers, bindings } = await serve({
bindings: {
createRequestURL: undefined,
},
});
const { client } = await helpers.createUser();
const id = crypto.randomUUID();
const url = await client.devhook.getUrl(id);
const expectedUrl = new URL(`api/webhook/${id}`, bindings.accessUrl);
expect(url).toBe(expectedUrl.toString());
});
test("devhook routes require auth by default", async () => {
const { url } = await serve();
const id = crypto.randomUUID();
const urlResponse = await fetch(new URL(`/api/devhook/${id}/url`, url));
expect(urlResponse.status).toBe(401);
const listenResponse = await fetch(new URL(`/api/devhook/${id}`, url));
expect(listenResponse.status).toBe(401);
});
test("devhook routes allow unauthenticated access when disableAuth is true", async () => {
const { url, bindings } = await serve({
bindings: { devhook: { disableAuth: true } },
});
const id = crypto.randomUUID();
const urlResponse = await fetch(new URL(`/api/devhook/${id}/url`, url));
expect(urlResponse.status).toBe(200);
const data = await urlResponse.json();
expect(data.url).toBe(
bindings.createRequestURL!(id).toString().replace(/\/$/, "")
);
// Listen endpoint tries to upgrade to WebSocket, so without proper headers
// it won't succeed, but it should not return 401
const listenResponse = await fetch(new URL(`/api/devhook/${id}`, url));
expect(listenResponse.status).not.toBe(401);
});
test.each([
{ disableAuth: true, name: "without auth" },
{ disableAuth: false, name: "with auth" },
])("devhook listen $name", async ({ disableAuth }) => {
const { helpers, bindings, url } = await serve({
bindings: { devhook: { disableAuth } },
});
const { client } = await helpers.createUser();
const id = crypto.randomUUID();
let resolveConnect: () => void;
const connectPromise = new Promise<void>((resolve) => {
resolveConnect = resolve;
});
let requestReceived = false;
client.devhook.listen({
id,
onError: () => {},
onRequest: async () => {
requestReceived = true;
return new Response("Hello from devhook!");
},
onConnect: () => {
resolveConnect?.();
},
});
// Ensure connection works.
await connectPromise;
// Test wildcard hostname routing.
// We need to make the request go through the test server with the correct Host header.
const devhookURL = bindings.createRequestURL!(id);
const response = await fetch(url, { headers: { Host: devhookURL.host } });
expect(response.status).toBe(200);
expect(await response.text()).toBe("Hello from devhook!");
expect(requestReceived).toBe(true);
});