Files
bun.sh/test/js/third_party/socket.io/socket.io-utility-methods.test.ts
2024-09-03 21:32:52 -07:00

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);
});
});
});