-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbroadcast.test.ts
More file actions
222 lines (174 loc) Β· 7.72 KB
/
Copy pathbroadcast.test.ts
File metadata and controls
222 lines (174 loc) Β· 7.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import { expect, it } from 'vitest';
import { setupServer } from './setup-server';
import { count, receive, track } from './test-events';
const ctx = setupServer();
it('socket.broadcast.emit goes to everyone except the sender', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2 } = await ctx.connectClient();
const got2 = receive(client2, 'msg');
const msg1 = track(client1, 'msg');
const marker1 = receive(client1, 'marker');
socket1.broadcast.emit('msg', 'hello');
socket1.emit('marker');
await expect(got2).resolves.toBe('hello');
await marker1;
expect(msg1.received).toBe(false); // sender excluded
});
it('io.except(room) goes to everyone not in that room', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2 } = await ctx.connectClient();
await socket1.join('room');
const got2 = receive(client2, 'msg');
const msg1 = track(client1, 'msg');
const marker1 = receive(client1, 'marker');
ctx.io.except('room').emit('msg', 'hello');
socket1.emit('marker');
await expect(got2).resolves.toBe('hello');
await marker1;
expect(msg1.received).toBe(false); // room member excluded
});
it('to() with an array delivers to the union of the rooms', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2, serverSocket: socket2 } = await ctx.connectClient();
const { client: client3, serverSocket: socket3 } = await ctx.connectClient();
await socket1.join('roomA');
await socket2.join('roomB');
// client3 is in neither room
const got1 = receive(client1, 'msg');
const got2 = receive(client2, 'msg');
const out3 = track(client3, 'msg');
const marker3 = receive(client3, 'marker');
ctx.io.to(['roomA', 'roomB']).emit('msg', 'hello');
socket3.emit('marker');
await expect(got1).resolves.toBe('hello');
await expect(got2).resolves.toBe('hello');
await marker3;
expect(out3.received).toBe(false);
});
it('chaining to() delivers to the union of the rooms', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2, serverSocket: socket2 } = await ctx.connectClient();
const { client: client3, serverSocket: socket3 } = await ctx.connectClient();
await socket1.join('roomA');
await socket2.join('roomB');
const got1 = receive(client1, 'msg');
const got2 = receive(client2, 'msg');
const out3 = track(client3, 'msg');
const marker3 = receive(client3, 'marker');
ctx.io.to('roomA').to('roomB').emit('msg', 'hello');
socket3.emit('marker');
await expect(got1).resolves.toBe('hello');
await expect(got2).resolves.toBe('hello');
await marker3;
expect(out3.received).toBe(false);
});
it('the array union delivers only once even when a socket is in several rooms', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
await socket1.join('roomA');
await socket1.join('roomB');
const counter = count(client1, 'msg');
const done = receive(client1, 'marker');
ctx.io.to(['roomA', 'roomB']).emit('msg', 'once');
socket1.emit('marker');
await done;
expect(counter.count).toBe(1); // deduplicated
});
it('the chained union delivers only once even when a socket is in several rooms', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
await socket1.join('roomA');
await socket1.join('roomB');
const counter = count(client1, 'msg');
const done = receive(client1, 'marker');
ctx.io.to('roomA').to('roomB').emit('msg', 'once');
socket1.emit('marker');
await done;
expect(counter.count).toBe(1); // a per-call delivery would make this 2 and fail
});
it('in() is an alias for to()', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2, serverSocket: socket2 } = await ctx.connectClient();
await socket1.join('room');
const got1 = receive(client1, 'msg');
const msg2 = track(client2, 'msg');
const marker2 = receive(client2, 'marker');
ctx.io.in('room').emit('msg', 'hello');
socket2.emit('marker');
await expect(got1).resolves.toBe('hello');
await marker2;
expect(msg2.received).toBe(false);
});
it('socket.except(room) excludes both the sender and that room', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2, serverSocket: socket2 } = await ctx.connectClient();
const { client: client3 } = await ctx.connectClient();
await socket2.join('room');
const got3 = receive(client3, 'msg');
const msg1 = track(client1, 'msg');
const msg2 = track(client2, 'msg');
const marker1 = receive(client1, 'marker');
const marker2 = receive(client2, 'marker');
socket1.except('room').emit('msg', 'hello');
socket1.emit('marker');
socket2.emit('marker');
await expect(got3).resolves.toBe('hello');
await marker1;
await marker2;
expect(msg1.received).toBe(false); // sender excluded
expect(msg2.received).toBe(false); // room member excluded
});
it('io.to(socketId) delivers only to that socket (its own id room)', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2, serverSocket: socket2 } = await ctx.connectClient();
const got2 = receive(client2, 'msg');
const msg1 = track(client1, 'msg');
const marker1 = receive(client1, 'marker');
ctx.io.to(socket2.id).emit('msg', 'hello');
socket1.emit('marker');
await expect(got2).resolves.toBe('hello');
await marker1;
expect(msg1.received).toBe(false);
});
it('socket.rooms is server-only and reflects its own id and join/leave', async () => {
const { serverSocket: socket1 } = await ctx.connectClient();
// socket.rooms is a server-only concept; right after connecting it holds only the socket's own id room.
expect(socket1.rooms).toBeInstanceOf(Set);
expect(socket1.rooms.has(socket1.id)).toBe(true);
expect(socket1.rooms.size).toBe(1);
await socket1.join('room');
expect(socket1.rooms.has('room')).toBe(true);
expect(socket1.rooms.has(socket1.id)).toBe(true);
await socket1.leave('room');
expect(socket1.rooms.has('room')).toBe(false);
expect(socket1.rooms.has(socket1.id)).toBe(true);
});
it('socket.to(room) excludes the sender even when the sender is a member of that room', async () => {
const { client: client1, serverSocket: socket1 } = await ctx.connectClient();
const { client: client2, serverSocket: socket2 } = await ctx.connectClient();
const { client: client3, serverSocket: socket3 } = await ctx.connectClient();
await socket1.join('room');
await socket2.join('room');
// client3 is outside the room
const got2 = receive(client2, 'msg');
const msg1 = track(client1, 'msg');
const msg3 = track(client3, 'msg');
const marker1 = receive(client1, 'marker');
const marker3 = receive(client3, 'marker');
socket1.to('room').emit('msg', 'hello');
socket1.emit('marker');
socket3.emit('marker');
await expect(got2).resolves.toBe('hello');
await marker1;
await marker3;
// The sender is in the room, so io.to("room") would have included it here.
// socket.to("room") is the same as socket.broadcast.to("room"): room minus sender.
expect(msg1.received).toBe(false);
expect(msg3.received).toBe(false); // outside the room
});
it('io.emit() delivers to everyone connected', async () => {
const clients = await ctx.connectClients(3);
const received = clients.map(({ client }) => receive(client, 'msg'));
// No sender to exclude, so this needs no marker: every client is expected to
// receive, and the awaits below would time out if one did not.
ctx.io.emit('msg', 'hello');
for (const got of received) await expect(got).resolves.toBe('hello');
});