Files
socket.io/test/socket.ts
Zachary Haber f6ef267b03 refactor(typings): improve emit types (#4817)
This commit fixes several issues with emit types:

- calling `emit()` without calling `timeout()` first is now only available for events without acknowledgement
- calling `emit()` after calling `timeout()` is now only available for events with an acknowledgement
- calling `emitWithAck()` is now only available for events with an acknowledgement
- `timeout()` must be called before calling `emitWithAck()`
2023-10-11 10:37:13 +02:00

1124 lines
30 KiB
TypeScript

import fs = require("fs");
import { join } from "path";
import {
createClient,
createPartialDone,
getPort,
success,
successFn,
} from "./support/util";
import { Server } from "..";
import expect from "expect.js";
describe("socket", () => {
it("should not fire events more than once after manually reconnecting", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { reconnection: false });
clientSocket.on("connect", function init() {
clientSocket.off("connect", init);
clientSocket.io.engine.close();
process.nextTick(() => {
clientSocket.connect();
});
clientSocket.on("connect", successFn(done, io, clientSocket));
});
});
it("should not fire reconnect_failed event more than once when server closed", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", {
reconnectionAttempts: 3,
reconnectionDelay: 100,
});
clientSocket.on("connect", () => {
io.close();
});
clientSocket.io.on("reconnect_failed", () => {
success(done, io, clientSocket);
});
});
it("should receive events", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("random", (a, b, c) => {
expect(a).to.be(1);
expect(b).to.be("2");
expect(c).to.eql([3]);
success(done, io, socket);
});
socket.emit("random", 1, "2", [3]);
});
});
it("should receive message events through `send`", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("message", (a) => {
expect(a).to.be(1337);
success(done, io, socket);
});
socket.send(1337);
});
});
it("should error with null messages", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("message", (a) => {
expect(a).to.be(null);
success(done, io, socket);
});
socket.send(null);
});
});
it("should handle transport null messages", (done) => {
const io = new Server(0);
const socket = createClient(io, "/", { reconnection: false });
io.on("connection", (s) => {
s.on("error", (err) => {
expect(err).to.be.an(Error);
s.on("disconnect", (reason) => {
expect(reason).to.be("forced close");
success(done, io, socket);
});
});
(s as any).client.ondata(null);
});
});
it("should emit events", (done) => {
const io = new Server(0);
const socket = createClient(io);
socket.on("woot", (a) => {
expect(a).to.be("tobi");
success(done, io, socket);
});
io.on("connection", (s) => {
s.emit("woot", "tobi");
});
});
it("should emit events with utf8 multibyte character", (done) => {
const io = new Server(0);
const socket = createClient(io);
let i = 0;
socket.on("hoot", (a) => {
expect(a).to.be("utf8 — string");
i++;
if (3 == i) {
success(done, io, socket);
}
});
io.on("connection", (s) => {
s.emit("hoot", "utf8 — string");
s.emit("hoot", "utf8 — string");
s.emit("hoot", "utf8 — string");
});
});
it("should emit events with binary data", (done) => {
const io = new Server(0);
const socket = createClient(io);
let imageData;
socket.on("doge", (a) => {
expect(Buffer.isBuffer(a)).to.be(true);
expect(imageData.length).to.equal(a.length);
expect(imageData[0]).to.equal(a[0]);
expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);
success(done, io, socket);
});
io.on("connection", (s) => {
fs.readFile(join(__dirname, "support", "doge.jpg"), (err, data) => {
if (err) return done(err);
imageData = data;
s.emit("doge", data);
});
});
});
it("should emit events with several types of data (including binary)", (done) => {
const io = new Server(0);
const socket = createClient(io);
socket.on("multiple", (a, b, c, d, e, f) => {
expect(a).to.be(1);
expect(Buffer.isBuffer(b)).to.be(true);
expect(c).to.be("3");
expect(d).to.eql([4]);
expect(Buffer.isBuffer(e)).to.be(true);
expect(Buffer.isBuffer(f[0])).to.be(true);
expect(f[1]).to.be("swag");
expect(Buffer.isBuffer(f[2])).to.be(true);
success(done, io, socket);
});
io.on("connection", (s) => {
fs.readFile(join(__dirname, "support", "doge.jpg"), (err, data) => {
if (err) return done(err);
const buf = Buffer.from("asdfasdf", "utf8");
s.emit("multiple", 1, data, "3", [4], buf, [data, "swag", buf]);
});
});
});
it("should receive events with binary data", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("buff", (a) => {
expect(Buffer.isBuffer(a)).to.be(true);
success(done, io, socket);
});
const buf = Buffer.from("abcdefg", "utf8");
socket.emit("buff", buf);
});
});
it("should receive events with several types of data (including binary)", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("multiple", (a, b, c, d, e, f) => {
expect(a).to.be(1);
expect(Buffer.isBuffer(b)).to.be(true);
expect(c).to.be("3");
expect(d).to.eql([4]);
expect(Buffer.isBuffer(e)).to.be(true);
expect(Buffer.isBuffer(f[0])).to.be(true);
expect(f[1]).to.be("swag");
expect(Buffer.isBuffer(f[2])).to.be(true);
success(done, io, socket);
});
fs.readFile(join(__dirname, "support", "doge.jpg"), (err, data) => {
if (err) return done(err);
const buf = Buffer.from("asdfasdf", "utf8");
socket.emit("multiple", 1, data, "3", [4], buf, [data, "swag", buf]);
});
});
});
it("should not emit volatile event after regular event (polling)", (done) => {
const io = new Server(0, { transports: ["polling"] });
let counter = 0;
io.on("connection", (s) => {
s.emit("ev", "data");
s.volatile.emit("ev", "data");
});
const socket = createClient(io, "/", { transports: ["polling"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 200);
});
it("should not emit volatile event after regular event (ws)", (done) => {
const io = new Server(0, { transports: ["websocket"] });
let counter = 0;
io.on("connection", (s) => {
s.emit("ev", "data");
s.volatile.emit("ev", "data");
});
const socket = createClient(io, "/", { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 200);
});
it("should emit volatile event (polling)", (done) => {
const io = new Server(0, { transports: ["polling"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.volatile.emit("ev", "data");
}, 100);
});
const socket = createClient(io, "/", { transports: ["polling"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 500);
});
it("should emit volatile event (ws)", (done) => {
const io = new Server(0, { transports: ["websocket"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.volatile.emit("ev", "data");
}, 20);
});
const socket = createClient(io, "/", { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 200);
});
it("should emit only one consecutive volatile event (polling)", (done) => {
const io = new Server(0, { transports: ["polling"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.volatile.emit("ev", "data");
s.volatile.emit("ev", "data");
}, 100);
});
const socket = createClient(io, "/", { transports: ["polling"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 500);
});
it("should emit only one consecutive volatile event (ws)", (done) => {
const io = new Server(0, { transports: ["websocket"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.volatile.emit("ev", "data");
s.volatile.emit("ev", "data");
}, 20);
});
const socket = createClient(io, "/", { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 200);
});
it("should emit only one consecutive volatile event with binary (ws)", (done) => {
const io = new Server(0, { transports: ["websocket"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.volatile.emit("ev", Buffer.from([1, 2, 3]));
s.volatile.emit("ev", Buffer.from([4, 5, 6]));
}, 20);
});
const socket = createClient(io, "/", { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 200);
});
it("should broadcast only one consecutive volatile event with binary (ws)", (done) => {
const io = new Server(0, { transports: ["websocket"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
io.volatile.emit("ev", Buffer.from([1, 2, 3]));
io.volatile.emit("ev", Buffer.from([4, 5, 6]));
}, 20);
});
const socket = createClient(io, "/", { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(1);
success(done, io, socket);
}, 200);
});
it("should emit regular events after trying a failed volatile event (polling)", (done) => {
const io = new Server(0, { transports: ["polling"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.emit("ev", "data");
s.volatile.emit("ev", "data");
s.emit("ev", "data");
}, 20);
});
const socket = createClient(io, "/", { transports: ["polling"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(2);
success(done, io, socket);
}, 200);
});
it("should emit regular events after trying a failed volatile event (ws)", (done) => {
const io = new Server(0, { transports: ["websocket"] });
let counter = 0;
io.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.emit("ev", "data");
s.volatile.emit("ev", "data");
s.emit("ev", "data");
}, 20);
});
const socket = createClient(io, "/", { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
setTimeout(() => {
expect(counter).to.be(2);
success(done, io, socket);
}, 200);
});
it("should emit message events through `send`", (done) => {
const io = new Server(0);
const socket = createClient(io);
socket.on("message", (a) => {
expect(a).to.be("a");
success(done, io, socket);
});
io.on("connection", (s) => {
s.send("a");
});
});
it("should receive event with callbacks", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("woot", (fn) => {
fn(1, 2);
});
socket.emit("woot", (a, b) => {
expect(a).to.be(1);
expect(b).to.be(2);
success(done, io, socket);
});
});
});
it("should receive all events emitted from namespaced client immediately and in order", (done) => {
const io = new Server(0);
let total = 0;
io.of("/chat", (s) => {
s.on("hi", (letter) => {
total++;
if (total == 2 && letter == "b") {
success(done, io, chat);
} else if (total == 1 && letter != "a") {
throw new Error("events out of order");
}
});
});
const chat = createClient(io, "/chat");
chat.emit("hi", "a");
setTimeout(() => {
chat.emit("hi", "b");
}, 50);
});
it("should emit events with callbacks", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
socket.on("hi", (fn) => {
fn();
});
s.emit("hi", () => {
success(done, io, socket);
});
});
});
it("should receive events with args and callback", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("woot", (a, b, fn) => {
expect(a).to.be(1);
expect(b).to.be(2);
fn();
});
socket.emit("woot", 1, 2, () => {
success(done, io, socket);
});
});
});
it("should emit events with args and callback", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
socket.on("hi", (a, b, fn) => {
expect(a).to.be(1);
expect(b).to.be(2);
fn();
});
s.emit("hi", 1, 2, () => {
success(done, io, socket);
});
});
});
it("should receive events with binary args and callbacks", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("woot", (buf, fn) => {
expect(Buffer.isBuffer(buf)).to.be(true);
fn(1, 2);
});
socket.emit("woot", Buffer.alloc(3), (a, b) => {
expect(a).to.be(1);
expect(b).to.be(2);
success(done, io, socket);
});
});
});
it("should emit events with binary args and callback", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
socket.on("hi", (a, fn) => {
expect(Buffer.isBuffer(a)).to.be(true);
fn();
});
s.emit("hi", Buffer.alloc(4), () => {
success(done, io, socket);
});
});
});
it("should emit events and receive binary data in a callback", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
socket.on("hi", (fn) => {
fn(Buffer.alloc(1));
});
s.emit("hi", (a) => {
expect(Buffer.isBuffer(a)).to.be(true);
success(done, io, socket);
});
});
});
it("should receive events and pass binary data in a callback", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
s.on("woot", (fn) => {
fn(Buffer.alloc(2));
});
socket.emit("woot", (a) => {
expect(Buffer.isBuffer(a)).to.be(true);
success(done, io, socket);
});
});
});
it("should emit an event and wait for the acknowledgement", (done) => {
type Events = {
hi: (a: number, b: number, cb: (c: number) => void) => void;
};
const io = new Server<{}, Events>(0);
const socket = createClient<Events, Events>(io);
io.on("connection", async (s) => {
socket.on("hi", (a, b, fn) => {
expect(a).to.be(1);
expect(b).to.be(2);
fn(3);
});
const val = await s.emitWithAck("hi", 1, 2);
expect(val).to.be(3);
success(done, io, socket);
});
});
it("should have access to the client", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
expect(s.client).to.be.an("object");
success(done, io, socket);
});
});
it("should have access to the connection", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
expect(s.client.conn).to.be.an("object");
expect(s.conn).to.be.an("object");
success(done, io, socket);
});
});
it("should have access to the request", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
expect(s.client.request.headers).to.be.an("object");
expect(s.request.headers).to.be.an("object");
success(done, io, socket);
});
});
it("should see query parameters in the request", (done) => {
const io = new Server(0);
const socket = createClient(io, "/", { query: { key1: 1, key2: 2 } });
io.on("connection", (s) => {
const parsed = require("url").parse(s.request.url);
const query = require("querystring").parse(parsed.query);
expect(query.key1).to.be("1");
expect(query.key2).to.be("2");
success(done, io, socket);
});
});
it("should see query parameters sent from secondary namespace connections in handshake object", (done) => {
const io = new Server(0);
const client1 = createClient(io);
const client2 = createClient(io, "/connection2", {
auth: { key1: "aa", key2: "&=bb" },
});
io.on("connection", (s) => {});
io.of("/connection2").on("connection", (s) => {
expect(s.handshake.query.key1).to.be(undefined);
expect(s.handshake.query.EIO).to.be("4");
expect(s.handshake.auth.key1).to.be("aa");
expect(s.handshake.auth.key2).to.be("&=bb");
success(done, io, client1, client2);
});
});
it("should handshake a client without access to the Engine.IO request (WebTransport-only connection)", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/");
io.engine.on("connection", (socket) => {
delete socket.request;
});
io.on("connection", (socket) => {
expect(socket.handshake.secure).to.be(true);
expect(socket.handshake.headers).to.eql({});
expect(socket.handshake.query).to.eql({});
success(done, io, clientSocket);
});
});
it("should handle very large json", function (done) {
this.timeout(30000);
const io = new Server(0, { perMessageDeflate: false });
let received = 0;
const socket = createClient(io);
socket.on("big", (a) => {
expect(Buffer.isBuffer(a.json)).to.be(false);
if (++received == 3) success(done, io, socket);
else socket.emit("big", a);
});
io.on("connection", (s) => {
fs.readFile(join(__dirname, "fixtures", "big.json"), (err, data: any) => {
if (err) return done(err);
data = JSON.parse(data);
s.emit("big", { hello: "friend", json: data });
});
s.on("big", (a) => {
s.emit("big", a);
});
});
});
it("should handle very large binary data", function (done) {
this.timeout(30000);
const io = new Server(0, { perMessageDeflate: false });
let received = 0;
const socket = createClient(io);
socket.on("big", (a) => {
expect(Buffer.isBuffer(a.image)).to.be(true);
if (++received == 3) success(done, io, socket);
else socket.emit("big", a);
});
io.on("connection", (s) => {
fs.readFile(join(__dirname, "fixtures", "big.jpg"), (err, data) => {
if (err) return done(err);
s.emit("big", { hello: "friend", image: data });
});
s.on("big", (a) => {
expect(Buffer.isBuffer(a.image)).to.be(true);
s.emit("big", a);
});
});
});
it("should be able to emit after server close and restart", (done) => {
const io = new Server(0);
io.on("connection", (socket) => {
socket.on("ev", (data) => {
expect(data).to.be("payload");
success(done, io, clientSocket);
});
});
const port = getPort(io);
const clientSocket = createClient(io, "/", {
reconnectionAttempts: 10,
reconnectionDelay: 100,
});
clientSocket.once("connect", () => {
io.close(() => {
clientSocket.io.on("reconnect", () => {
clientSocket.emit("ev", "payload");
});
io.listen(port);
});
});
});
it("should enable compression by default", (done) => {
const io = new Server(0);
const socket = createClient(io, "/chat");
io.of("/chat").on("connection", (s) => {
s.conn.once("packetCreate", (packet) => {
expect(packet.options.compress).to.be(true);
success(done, io, socket);
});
s.emit("woot", "hi");
});
});
it("should disable compression", (done) => {
const io = new Server(0);
const socket = createClient(io, "/chat");
io.of("/chat").on("connection", (s) => {
s.conn.once("packetCreate", (packet) => {
expect(packet.options.compress).to.be(false);
success(done, io, socket);
});
s.compress(false).emit("woot", "hi");
});
});
it("should error with raw binary and warn", (done) => {
const io = new Server(0);
const socket = createClient(io, "/", { reconnection: false });
io.on("connection", (s) => {
s.conn.on("upgrade", () => {
console.log(
"\u001b[96mNote: warning expected and normal in test.\u001b[39m"
);
// @ts-ignore
socket.io.engine.write("5woooot");
setTimeout(() => {
success(done, io, socket);
}, 100);
});
});
});
it("should not crash when receiving an error packet without handler", (done) => {
const io = new Server(0);
const socket = createClient(io, "/", { reconnection: false });
io.on("connection", (s) => {
s.conn.on("upgrade", () => {
console.log(
"\u001b[96mNote: warning expected and normal in test.\u001b[39m"
);
// @ts-ignore
socket.io.engine.write('44["handle me please"]');
setTimeout(() => {
success(done, io, socket);
}, 100);
});
});
});
it("should not crash with raw binary", (done) => {
const io = new Server(0);
const socket = createClient(io, "/", { reconnection: false });
io.on("connection", (s) => {
s.once("error", (err) => {
expect(err.message).to.match(/Illegal attachments/);
success(done, io, socket);
});
s.conn.on("upgrade", () => {
// @ts-ignore
socket.io.engine.write("5woooot");
});
});
});
it("should handle empty binary packet", (done) => {
const io = new Server(0);
const socket = createClient(io, "/", { reconnection: false });
io.on("connection", (s) => {
s.once("error", (err) => {
expect(err.message).to.match(/Illegal attachments/);
success(done, io, socket);
});
s.conn.on("upgrade", () => {
// @ts-ignore
socket.io.engine.write("5");
});
});
});
it("should not crash when messing with Object prototype (and other globals)", (done) => {
// @ts-ignore
Object.prototype.foo = "bar";
const io = new Server(0);
const socket = createClient(io);
io.on("connection", successFn(done, io, socket));
});
it("should throw on reserved event", (done) => {
const io = new Server(0);
const socket = createClient(io);
io.on("connection", (s) => {
expect(() => s.emit("connect_error")).to.throwException(
/"connect_error" is a reserved event name/
);
socket.close();
success(done, io, socket);
});
});
it("should ignore a packet received after disconnection", (done) => {
const io = new Server(0);
const clientSocket = createClient(io);
io.on("connection", (socket) => {
socket.on("test", () => {
done(new Error("should not happen"));
});
socket.on("disconnect", successFn(done, io, clientSocket));
});
clientSocket.on("connect", () => {
clientSocket.emit("test", Buffer.alloc(10));
clientSocket.disconnect();
});
});
it("should leave all rooms joined after a middleware failure", (done) => {
const io = new Server(0);
const client = createClient(io, "/");
io.use((socket, next) => {
socket.join("room1");
next(new Error("nope"));
});
client.on("connect_error", () => {
expect(io.of("/").adapter.rooms.size).to.eql(0);
io.close();
success(done, io, client);
});
});
it("should not join rooms after disconnection", (done) => {
const io = new Server(0);
const client = createClient(io, "/");
io.on("connection", (socket) => {
socket.disconnect();
socket.join("room1");
});
client.on("disconnect", () => {
expect(io.of("/").adapter.rooms.size).to.eql(0);
io.close();
success(done, io, client);
});
});
describe("onAny", () => {
it("should call listener", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
clientSocket.emit("my-event", "123");
io.on("connection", (socket) => {
socket.onAny((event, arg1) => {
expect(event).to.be("my-event");
expect(arg1).to.be("123");
success(done, io, clientSocket);
});
});
});
it("should prepend listener", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
clientSocket.emit("my-event", "123");
io.on("connection", (socket) => {
let count = 0;
socket.onAny((event, arg1) => {
expect(count).to.be(2);
success(done, io, clientSocket);
});
socket.prependAny(() => {
expect(count++).to.be(1);
});
socket.prependAny(() => {
expect(count++).to.be(0);
});
});
});
it("should remove listener", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
clientSocket.emit("my-event", "123");
io.on("connection", (socket) => {
const fail = () => done(new Error("fail"));
socket.onAny(fail);
socket.offAny(fail);
expect(socket.listenersAny.length).to.be(0);
socket.onAny(() => {
success(done, io, clientSocket);
});
});
});
});
describe("onAnyOutgoing", () => {
it("should call listener", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
io.on("connection", (socket) => {
socket.onAnyOutgoing((event, arg1) => {
expect(event).to.be("my-event");
expect(arg1).to.be("123");
success(done, io, clientSocket);
});
socket.emit("my-event", "123");
});
});
it("should call listener when broadcasting", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
io.on("connection", (socket) => {
socket.onAnyOutgoing((event, arg1) => {
expect(event).to.be("my-event");
expect(arg1).to.be("123");
success(done, io, clientSocket);
});
io.emit("my-event", "123");
});
});
it("should call listener when broadcasting binary data", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
io.on("connection", (socket) => {
socket.onAnyOutgoing((event, arg1) => {
expect(event).to.be("my-event");
expect(arg1).to.be.an(Uint8Array);
success(done, io, clientSocket);
});
io.emit("my-event", Uint8Array.of(1, 2, 3));
});
});
it("should prepend listener", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
io.on("connection", (socket) => {
let count = 0;
socket.onAnyOutgoing((event, arg1) => {
expect(count).to.be(2);
success(done, io, clientSocket);
});
socket.prependAnyOutgoing(() => {
expect(count++).to.be(1);
});
socket.prependAnyOutgoing(() => {
expect(count++).to.be(0);
});
socket.emit("my-event", "123");
});
});
it("should remove listener", (done) => {
const io = new Server(0);
const clientSocket = createClient(io, "/", { multiplex: false });
io.on("connection", (socket) => {
const fail = () => done(new Error("fail"));
socket.onAnyOutgoing(fail);
socket.offAnyOutgoing(fail);
expect(socket.listenersAnyOutgoing.length).to.be(0);
socket.onAnyOutgoing(() => {
success(done, io, clientSocket);
});
socket.emit("my-event", "123");
});
});
it("should disconnect all namespaces when calling disconnect(true)", (done) => {
const io = new Server(0);
io.of("/foo");
io.of("/bar");
const socket1 = createClient(io, "/", {
transports: ["websocket"],
});
const socket2 = createClient(io, "/foo");
const socket3 = createClient(io, "/bar");
io.of("/bar").on("connection", (socket) => {
socket.disconnect(true);
});
const partialDone = createPartialDone(
3,
successFn(done, io, socket1, socket2, socket3)
);
socket1.on("disconnect", partialDone);
socket2.on("disconnect", partialDone);
socket3.on("disconnect", partialDone);
});
});
});