diff --git a/lib/index.ts b/lib/index.ts index 619ad2e..019f8cd 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -59,8 +59,12 @@ export class Adapter extends EventEmitter { if (!this.rooms.has(room)) { this.rooms.set(room, new Set()); + this.emit("create-room", room); + } + if (!this.rooms.get(room).has(id)) { + this.rooms.get(room).add(id); + this.emit("join-room", room, id); } - this.rooms.get(room).add(id); } } @@ -75,9 +79,19 @@ export class Adapter extends EventEmitter { this.sids.get(id).delete(room); } + this._del(room, id); + } + + private _del(room, id) { if (this.rooms.has(room)) { - this.rooms.get(room).delete(id); - if (this.rooms.get(room).size === 0) this.rooms.delete(room); + const deleted = this.rooms.get(room).delete(id); + if (deleted) { + this.emit("leave-room", room, id); + } + if (this.rooms.get(room).size === 0) { + this.rooms.delete(room); + this.emit("delete-room", room); + } } } @@ -92,10 +106,7 @@ export class Adapter extends EventEmitter { } for (const room of this.sids.get(id)) { - if (this.rooms.has(room)) { - this.rooms.get(room).delete(id); - if (this.rooms.get(room).size === 0) this.rooms.delete(room); - } + this._del(room, id); } this.sids.delete(id); diff --git a/test/index.js b/test/index.js index 5d4f9e8..b517f66 100644 --- a/test/index.js +++ b/test/index.js @@ -57,4 +57,88 @@ describe("socket.io-adapter", () => { expect(rooms.size).to.be(2); expect(adapter.socketRooms("s4")).to.be(undefined); }); + + describe("events", () => { + it("should emit a 'create-room' event", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.on("create-room", room => { + expect(room).to.eql("r1"); + done(); + }); + adapter.addAll("s1", new Set(["r1"])); + }); + + it("should not emit a 'create-room' event if the room already exists", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.addAll("s1", new Set(["r1"])); + adapter.on("create-room", room => { + done(new Error("should not happen")); + }); + adapter.addAll("s2", new Set(["r1"])); + done(); + }); + + it("should emit a 'join-room' event", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.on("join-room", (room, sid) => { + expect(room).to.eql("r1"); + expect(sid).to.eql("s1"); + done(); + }); + adapter.addAll("s1", new Set(["r1"])); + }); + + it("should not emit a 'join-room' event if the sid is already in the room", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.addAll("s1", new Set(["r1", "r2"])); + adapter.on("join-room", () => { + done(new Error("should not happen")); + }); + adapter.addAll("s1", new Set(["r1"])); + done(); + }); + + it("should emit a 'leave-room' event with del method", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.on("leave-room", (room, sid) => { + expect(room).to.eql("r1"); + expect(sid).to.eql("s1"); + done(); + }); + adapter.addAll("s1", new Set(["r1"])); + adapter.del("s1", "r1"); + }); + + it("should emit a 'leave-room' event with delAll method", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.on("leave-room", (room, sid) => { + expect(room).to.eql("r1"); + expect(sid).to.eql("s1"); + done(); + }); + adapter.addAll("s1", new Set(["r1"])); + adapter.delAll("s1"); + }); + + it("should emit a 'delete-room' event", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.on("delete-room", room => { + expect(room).to.eql("r1"); + done(); + }); + adapter.addAll("s1", new Set(["r1"])); + adapter.delAll("s1"); + }); + + it("should not emit a 'delete-room' event if there is another sid in the room", done => { + const adapter = new Adapter({ server: { encoder: null } }); + adapter.on("delete-room", room => { + done(new Error("should not happen")); + }); + adapter.addAll("s1", new Set(["r1"])); + adapter.addAll("s2", new Set(["r1", "r2"])); + adapter.delAll("s1"); + done(); + }); + }); });