-
-
Notifications
You must be signed in to change notification settings - Fork 80.8k
Expand file tree
/
Copy pathshared-auth.test-helpers.ts
More file actions
79 lines (76 loc) · 2.28 KB
/
Copy pathshared-auth.test-helpers.ts
File metadata and controls
79 lines (76 loc) · 2.28 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
import { expect } from "vitest";
import { WebSocket } from "ws";
import { connectOk, rpcReq, trackConnectChallengeNonce } from "./test-helpers.js";
export async function openAuthenticatedGatewayWs(
port: number,
token: string,
timeoutMs = 10_000,
): Promise<WebSocket> {
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
trackConnectChallengeNonce(ws);
await new Promise<void>((resolve, reject) => {
const cleanup = () => {
clearTimeout(timer);
ws.off("open", onOpen);
ws.off("error", onError);
ws.off("close", onClose);
};
const onOpen = () => {
cleanup();
resolve();
};
const onError = (error: unknown) => {
cleanup();
reject(error instanceof Error ? error : new Error(String(error)));
};
const onClose = (code: number, reason: Buffer) => {
cleanup();
reject(new Error(`gateway websocket closed before open (${code}: ${reason.toString()})`));
};
const timer = setTimeout(() => {
cleanup();
ws.close();
reject(new Error(`gateway websocket did not open within ${timeoutMs}ms`));
}, timeoutMs);
timer.unref?.();
ws.once("open", onOpen);
ws.once("error", onError);
ws.once("close", onClose);
});
await connectOk(ws, { token });
return ws;
}
export async function waitForGatewayWsClose(
ws: WebSocket,
timeoutMs = 10_000,
): Promise<{ code: number; reason: string }> {
return await new Promise((resolve, reject) => {
const timer = setTimeout(() => {
ws.off("close", onClose);
reject(
new Error(`gateway websocket did not close within ${timeoutMs}ms (state=${ws.readyState})`),
);
}, timeoutMs);
timer.unref?.();
const onClose = (code: number, reason: Buffer) => {
clearTimeout(timer);
resolve({ code, reason: reason.toString() });
};
ws.once("close", onClose);
});
}
export async function loadGatewayConfig(ws: WebSocket): Promise<{
hash: string;
config: Record<string, unknown>;
}> {
const current = await rpcReq<{
hash?: string;
config?: Record<string, unknown>;
}>(ws, "config.get", {});
expect(current.ok).toBe(true);
expect(typeof current.payload?.hash).toBe("string");
return {
hash: String(current.payload?.hash),
config: structuredClone(current.payload?.config ?? {}),
};
}