mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
183 lines
5.6 KiB
TypeScript
183 lines
5.6 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
import { createServer } from "http";
|
|
import type { AddressInfo } from "net";
|
|
import { Server } from "socket.io";
|
|
import { Adapter, BroadcastOptions } from "socket.io-adapter";
|
|
import { Socket as ClientSocket, io as ioc } from "socket.io-client";
|
|
|
|
import { createPartialDone } from "./support/util.ts";
|
|
|
|
const SOCKETS_COUNT = 3;
|
|
|
|
class DummyAdapter extends Adapter {
|
|
fetchSockets(opts: BroadcastOptions): Promise<any[]> {
|
|
return Promise.resolve([
|
|
{
|
|
id: "42",
|
|
handshake: {
|
|
headers: {
|
|
accept: "*/*",
|
|
},
|
|
query: {
|
|
transport: "polling",
|
|
EIO: "4",
|
|
},
|
|
},
|
|
rooms: ["42", "room1"],
|
|
data: {
|
|
username: "john",
|
|
},
|
|
},
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Hanging tests are disabled because they cause the test suite to hang
|
|
describe.skip("utility methods", () => {
|
|
let io: Server, clientSockets: ClientSocket[], serverSockets: Socket[];
|
|
beforeEach(done => {
|
|
const srv = createServer();
|
|
io = new Server(srv);
|
|
const timeout = setTimeout(() => {
|
|
serverSockets = [];
|
|
// done(new Error("timeout"));
|
|
done();
|
|
}, 300);
|
|
|
|
srv.listen(() => {
|
|
const port = (srv.address() as AddressInfo).port;
|
|
|
|
clientSockets = [];
|
|
for (let i = 0; i < SOCKETS_COUNT; i++) {
|
|
clientSockets.push(
|
|
ioc(`http://localhost:${port}`, {
|
|
// FIXME needed so that clients are properly closed
|
|
transports: ["websocket"],
|
|
}),
|
|
);
|
|
}
|
|
|
|
serverSockets = [];
|
|
io.on("connection", (socket: Socket) => {
|
|
serverSockets.push(socket);
|
|
if (serverSockets.length === SOCKETS_COUNT) {
|
|
clearTimeout(timeout);
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
io.close();
|
|
clientSockets.forEach(socket => socket.disconnect());
|
|
});
|
|
|
|
describe("fetchSockets", () => {
|
|
it.skip("returns all socket instances", async () => {
|
|
const sockets = await io.fetchSockets();
|
|
expect(sockets.length).toBe(3);
|
|
});
|
|
|
|
it.skip("returns all socket instances in the given room", async () => {
|
|
serverSockets[0]?.join(["room1", "room2"]);
|
|
serverSockets[1]?.join("room1");
|
|
serverSockets[2]?.join("room2");
|
|
const sockets = await io.in("room1").fetchSockets();
|
|
expect(sockets.length).toBe(2);
|
|
});
|
|
|
|
it.skip("works with a custom adapter", async () => {
|
|
io.adapter(DummyAdapter);
|
|
const sockets = await io.fetchSockets();
|
|
expect(sockets.length).toBe(1);
|
|
const remoteSocket = sockets[0];
|
|
expect(remoteSocket.id).toBe("42");
|
|
expect(remoteSocket.rooms).toStrictEqual(new Set(["42", "room1"]));
|
|
expect(remoteSocket.data).toStrictEqual({ username: "john" });
|
|
});
|
|
});
|
|
|
|
describe("socketsJoin", () => {
|
|
it("makes all socket instances join the given room", () => {
|
|
io.socketsJoin("room1");
|
|
serverSockets.forEach(socket => {
|
|
expect(socket.rooms).toContain("room1");
|
|
});
|
|
});
|
|
|
|
it.skip("makes all socket instances in a room join the given room", () => {
|
|
serverSockets[0]?.join(["room1", "room2"]);
|
|
serverSockets[1]?.join("room1");
|
|
serverSockets[2]?.join("room2");
|
|
io.in("room1").socketsJoin("room3");
|
|
expect(serverSockets[0]?.rooms).toContain("room3");
|
|
expect(serverSockets[1]?.rooms).toContain("room3");
|
|
expect(serverSockets[2]?.rooms).not.toContain("room3");
|
|
});
|
|
});
|
|
|
|
describe("socketsLeave", () => {
|
|
it.skip("makes all socket instances leave the given room", () => {
|
|
serverSockets[0]?.join(["room1", "room2"]);
|
|
serverSockets[1]?.join("room1");
|
|
serverSockets[2]?.join("room2");
|
|
io.socketsLeave("room1");
|
|
expect(serverSockets[0]?.rooms).toContain("room2");
|
|
expect(serverSockets[0]?.rooms).toContain("room1");
|
|
expect(serverSockets[1]?.rooms).not.toContain("room1");
|
|
});
|
|
|
|
it.skip("makes all socket instances in a room leave the given room", () => {
|
|
serverSockets[0]?.join(["room1", "room2"]);
|
|
serverSockets[1]?.join("room1");
|
|
serverSockets[2]?.join("room2");
|
|
io.in("room2").socketsLeave("room1");
|
|
expect(serverSockets[0]?.rooms).toContain("room2");
|
|
expect(serverSockets[0]?.rooms).not.toContain("room1");
|
|
expect(serverSockets[1]?.rooms).toContain("room1");
|
|
});
|
|
});
|
|
|
|
describe("disconnectSockets", () => {
|
|
it.skip("makes all socket instances disconnect", done => {
|
|
io.disconnectSockets(true);
|
|
const timeout = setTimeout(() => {
|
|
done(new Error("timeout"));
|
|
}, 300);
|
|
|
|
const partialDone = createPartialDone(3, err => {
|
|
clearTimeout(timeout);
|
|
done(err);
|
|
});
|
|
|
|
clientSockets[0].on("disconnect", partialDone);
|
|
clientSockets[1].on("disconnect", partialDone);
|
|
clientSockets[2].on("disconnect", partialDone);
|
|
});
|
|
|
|
it.skip("makes all socket instances in a room disconnect", done => {
|
|
const timeout = setTimeout(() => {
|
|
done(new Error("timeout"));
|
|
}, 300);
|
|
|
|
serverSockets[0]?.join(["room1", "room2"]);
|
|
serverSockets[1]?.join("aroom1");
|
|
serverSockets[2]?.join("room2");
|
|
io.in("room2").disconnectSockets(true);
|
|
|
|
const partialDone = createPartialDone(2, err => {
|
|
clearTimeout(timeout);
|
|
clientSockets[1].off("disconnect");
|
|
done(err);
|
|
});
|
|
|
|
clientSockets[0].on("disconnect", partialDone);
|
|
clientSockets[1].on("disconnect", () => {
|
|
done(new Error("should not happen"));
|
|
});
|
|
clientSockets[2].on("disconnect", partialDone);
|
|
});
|
|
});
|
|
});
|