Skip to content

Commit 589ea28

Browse files
committed
test(gateway): smoke real websocket client
1 parent 451765a commit 589ea28

1 file changed

Lines changed: 116 additions & 1 deletion

File tree

test/scripts/gateway-smoke.test.ts

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
11
// Gateway Smoke tests cover gateway smoke script behavior.
2-
import { describe, expect, it } from "vitest";
2+
import { createServer, type Server } from "node:http";
3+
import { afterEach, describe, expect, it } from "vitest";
4+
import { WebSocket, WebSocketServer } from "ws";
35
import { runGatewaySmoke } from "../../scripts/dev/gateway-smoke.js";
46

7+
let server: Server | undefined;
8+
let wss: WebSocketServer | undefined;
9+
10+
afterEach(async () => {
11+
await new Promise<void>((resolve) => {
12+
wss?.close(() => resolve());
13+
if (!wss) {
14+
resolve();
15+
}
16+
});
17+
wss = undefined;
18+
19+
await new Promise<void>((resolve, reject) => {
20+
server?.close((error) => {
21+
if (error) {
22+
reject(error);
23+
return;
24+
}
25+
resolve();
26+
});
27+
if (!server) {
28+
resolve();
29+
}
30+
});
31+
server = undefined;
32+
});
33+
534
describe("gateway-smoke", () => {
635
function healthResponse() {
736
return {
@@ -19,6 +48,58 @@ describe("gateway-smoke", () => {
1948
};
2049
}
2150

51+
async function listenGatewaySmokeServer() {
52+
const requests: Array<{ method: string; params?: unknown; timeout?: number }> = [];
53+
server = createServer();
54+
wss = new WebSocketServer({ server });
55+
wss.on("connection", (ws: WebSocket) => {
56+
ws.on("message", (data) => {
57+
const frame = JSON.parse(data.toString()) as {
58+
id: string;
59+
method: string;
60+
params?: unknown;
61+
type: string;
62+
};
63+
requests.push({ method: frame.method, params: frame.params });
64+
if (frame.method === "connect") {
65+
ws.send(JSON.stringify({ id: frame.id, ok: true, payload: {}, type: "res" }));
66+
return;
67+
}
68+
if (frame.method === "health") {
69+
ws.send(JSON.stringify({ id: frame.id, type: "res", ...healthResponse() }));
70+
return;
71+
}
72+
if (frame.method === "chat.history") {
73+
ws.send(
74+
JSON.stringify({
75+
id: frame.id,
76+
ok: true,
77+
payload: { messages: [] },
78+
type: "res",
79+
}),
80+
);
81+
return;
82+
}
83+
ws.send(
84+
JSON.stringify({
85+
error: `unexpected method ${frame.method}`,
86+
id: frame.id,
87+
ok: false,
88+
type: "res",
89+
}),
90+
);
91+
});
92+
});
93+
await new Promise<void>((resolve) => {
94+
server?.listen(0, "127.0.0.1", resolve);
95+
});
96+
const address = server.address();
97+
if (!address || typeof address === "string") {
98+
throw new Error("test gateway smoke server did not get a TCP address");
99+
}
100+
return { requests, url: `ws://127.0.0.1:${address.port}` };
101+
}
102+
22103
function createSmokeDeps(
23104
responses: Record<string, { error?: string; ok: boolean } & Record<string, unknown>>,
24105
calls: Array<{ method: string; timeout?: number }> = [],
@@ -63,6 +144,40 @@ describe("gateway-smoke", () => {
63144
};
64145
}
65146

147+
it("passes against a loopback gateway websocket using the real client", async () => {
148+
const stdout: string[] = [];
149+
const stderr: string[] = [];
150+
const loopback = await listenGatewaySmokeServer();
151+
152+
const code = await runGatewaySmoke(
153+
{ token: "secret-token", urlRaw: loopback.url },
154+
{
155+
stderr: (message) => {
156+
stderr.push(message);
157+
},
158+
stdout: (message) => {
159+
stdout.push(message);
160+
},
161+
},
162+
);
163+
164+
expect(code).toBe(0);
165+
expect(loopback.requests.map((request) => request.method)).toEqual([
166+
"connect",
167+
"health",
168+
"chat.history",
169+
]);
170+
expect(loopback.requests[0]?.params).toMatchObject({
171+
auth: { token: "secret-token" },
172+
client: { id: "openclaw-ios" },
173+
role: "operator",
174+
scopes: ["operator.read", "operator.write", "operator.admin"],
175+
});
176+
expect(loopback.requests[2]?.params).toEqual({ sessionKey: "main" });
177+
expect(stdout).toEqual(["ok: connected + health + chat.history"]);
178+
expect(stderr).toEqual([]);
179+
});
180+
66181
it("closes the websocket client when connect fails", async () => {
67182
const stderr: string[] = [];
68183
const methods: string[] = [];

0 commit comments

Comments
 (0)