@tsed/socketio 8.0.1 → 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +16 -15
- package/src/SocketIOModule.spec.ts +87 -0
- package/src/SocketIOModule.ts +113 -0
- package/src/class/SocketHandlersBuilder.spec.ts +988 -0
- package/src/class/SocketHandlersBuilder.ts +266 -0
- package/src/class/SocketProviderMetadata.ts +57 -0
- package/src/class/SocketSessionData.spec.ts +190 -0
- package/src/class/SocketSessionData.ts +81 -0
- package/src/constants/constants.ts +1 -0
- package/src/decorators/args.spec.ts +57 -0
- package/src/decorators/args.ts +60 -0
- package/src/decorators/broadcast.spec.ts +23 -0
- package/src/decorators/broadcast.ts +28 -0
- package/src/decorators/broadcastOthers.spec.ts +23 -0
- package/src/decorators/broadcastOthers.ts +28 -0
- package/src/decorators/emit.spec.ts +23 -0
- package/src/decorators/emit.ts +28 -0
- package/src/decorators/input.spec.ts +22 -0
- package/src/decorators/input.ts +33 -0
- package/src/decorators/inputAndBroadcast.spec.ts +25 -0
- package/src/decorators/inputAndBroadcast.ts +28 -0
- package/src/decorators/inputAndBroadcastOthers.spec.ts +24 -0
- package/src/decorators/inputAndBroadcastOthers.ts +28 -0
- package/src/decorators/inputAndEmit.spec.ts +24 -0
- package/src/decorators/inputAndEmit.ts +28 -0
- package/src/decorators/io.ts +34 -0
- package/src/decorators/nsp.spec.ts +70 -0
- package/src/decorators/nsp.ts +101 -0
- package/src/decorators/reason.spec.ts +26 -0
- package/src/decorators/reason.ts +30 -0
- package/src/decorators/socket.spec.ts +26 -0
- package/src/decorators/socket.ts +32 -0
- package/src/decorators/socketErr.spec.ts +25 -0
- package/src/decorators/socketErr.ts +26 -0
- package/src/decorators/socketEventName.spec.ts +25 -0
- package/src/decorators/socketEventName.ts +26 -0
- package/src/decorators/socketFilter.ts +27 -0
- package/src/decorators/socketMiddleware.spec.ts +21 -0
- package/src/decorators/socketMiddleware.ts +72 -0
- package/src/decorators/socketMiddlewareError.spec.ts +22 -0
- package/src/decorators/socketMiddlewareError.ts +70 -0
- package/src/decorators/socketNsp.spec.ts +26 -0
- package/src/decorators/socketNsp.ts +32 -0
- package/src/decorators/socketReturns.ts +25 -0
- package/src/decorators/socketService.spec.ts +44 -0
- package/src/decorators/socketService.ts +24 -0
- package/src/decorators/socketSession.spec.ts +47 -0
- package/src/decorators/socketSession.ts +53 -0
- package/src/decorators/socketUseAfter.spec.ts +38 -0
- package/src/decorators/socketUseAfter.ts +69 -0
- package/src/decorators/socketUseBefore.spec.ts +34 -0
- package/src/decorators/socketUseBefore.ts +73 -0
- package/src/index.ts +41 -0
- package/src/interfaces/OnNamespaceInit.ts +8 -0
- package/src/interfaces/SocketFilters.ts +14 -0
- package/src/interfaces/SocketHandlerMetadata.ts +17 -0
- package/src/interfaces/SocketInjectableNsp.ts +4 -0
- package/src/interfaces/SocketParamMetadata.ts +9 -0
- package/src/interfaces/SocketProviderTypes.ts +7 -0
- package/src/interfaces/SocketReturnsTypes.ts +8 -0
- package/src/interfaces/interfaces.ts +9 -0
- package/src/services/SocketIOServer.spec.ts +33 -0
- package/src/services/SocketIOServer.ts +15 -0
- package/src/services/SocketIOService.spec.ts +54 -0
- package/src/services/SocketIOService.ts +69 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
import {DIContext, getContext, InjectorService, ProviderType} from "@tsed/di";
|
|
3
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
4
|
+
|
|
5
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
6
|
+
import {SocketReturnsTypes} from "../interfaces/SocketReturnsTypes.js";
|
|
7
|
+
import {SocketHandlersBuilder} from "./SocketHandlersBuilder.js";
|
|
8
|
+
import {SocketProviderMetadata} from "./SocketProviderMetadata.js";
|
|
9
|
+
|
|
10
|
+
const metadata: any = {
|
|
11
|
+
handlers: {
|
|
12
|
+
testHandler: {
|
|
13
|
+
methodClassName: "testHandler",
|
|
14
|
+
eventName: "eventName",
|
|
15
|
+
parameters: ["param"],
|
|
16
|
+
returns: {
|
|
17
|
+
eventName: "returnEventName",
|
|
18
|
+
type: "type"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe("SocketHandlersBuilder", () => {
|
|
25
|
+
beforeEach(() => PlatformTest.create());
|
|
26
|
+
afterEach(() => PlatformTest.reset());
|
|
27
|
+
describe("build()", () => {
|
|
28
|
+
function createServiceFixture() {
|
|
29
|
+
const instance: any = {
|
|
30
|
+
$onDisconnect: vi.fn(),
|
|
31
|
+
$onConnection: vi.fn(),
|
|
32
|
+
$onNamespaceInit: vi.fn()
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const provider: any = {
|
|
36
|
+
store: {
|
|
37
|
+
get: vi.fn()
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
42
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
43
|
+
return fn;
|
|
44
|
+
},
|
|
45
|
+
get() {
|
|
46
|
+
return instance;
|
|
47
|
+
}
|
|
48
|
+
} as any);
|
|
49
|
+
builder.socketProviderMetadata = new SocketProviderMetadata({
|
|
50
|
+
namespace: "/",
|
|
51
|
+
injectNamespaces: [{propertyKey: "key1"}, {propertyKey: "key2", nsp: "/test"}],
|
|
52
|
+
handlers: {
|
|
53
|
+
$onDisconnect: {} as any
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const nsps = new Map();
|
|
58
|
+
nsps.set("/", "namespace1");
|
|
59
|
+
nsps.set("/test", "namespace2");
|
|
60
|
+
|
|
61
|
+
builder.build(nsps);
|
|
62
|
+
|
|
63
|
+
return {builder, nsps, provider, instance};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
it("should create metadata when $onDisconnect exists", () => {
|
|
67
|
+
const {builder} = createServiceFixture();
|
|
68
|
+
expect(builder.socketProviderMetadata).toEqual(
|
|
69
|
+
new SocketProviderMetadata({
|
|
70
|
+
namespace: "/",
|
|
71
|
+
handlers: {
|
|
72
|
+
$onConnection: {
|
|
73
|
+
eventName: "connection",
|
|
74
|
+
methodClassName: "$onConnection"
|
|
75
|
+
},
|
|
76
|
+
$onDisconnect: {
|
|
77
|
+
eventName: "disconnect",
|
|
78
|
+
methodClassName: "$onDisconnect"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
injectNamespaces: [
|
|
82
|
+
{
|
|
83
|
+
propertyKey: "key1"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
nsp: "/test",
|
|
87
|
+
propertyKey: "key2"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
it("should call $onNamespaceInit hook", () => {
|
|
94
|
+
const {instance} = createServiceFixture();
|
|
95
|
+
expect(instance.$onNamespaceInit).toHaveBeenCalledWith("namespace1");
|
|
96
|
+
});
|
|
97
|
+
it("should add namespace1", () => {
|
|
98
|
+
const {instance} = createServiceFixture();
|
|
99
|
+
expect(instance.key1).toEqual("namespace1");
|
|
100
|
+
});
|
|
101
|
+
it("should add namespace2", () => {
|
|
102
|
+
const {instance} = createServiceFixture();
|
|
103
|
+
expect(instance.key2).toEqual("namespace2");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should add default nsp", () => {
|
|
107
|
+
const {instance} = createServiceFixture();
|
|
108
|
+
expect(instance.nsp).toEqual("namespace1");
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe("onConnection()", () => {
|
|
112
|
+
it("should build handler and invoke onConnection instance method", async () => {
|
|
113
|
+
const instance = {
|
|
114
|
+
$onConnection: vi.fn()
|
|
115
|
+
};
|
|
116
|
+
const provider: any = {
|
|
117
|
+
store: {
|
|
118
|
+
get: vi.fn().mockReturnValue({
|
|
119
|
+
injectNamespaces: [{nsp: "/nsp", propertyKey: "key"}],
|
|
120
|
+
handlers: {
|
|
121
|
+
$onConnection: {
|
|
122
|
+
eventName: "connection",
|
|
123
|
+
methodClassName: "$onConnection"
|
|
124
|
+
} as any
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const nspStub = {nsp: "nsp"};
|
|
130
|
+
const socketStub = {
|
|
131
|
+
on: vi.fn()
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
135
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
136
|
+
return fn;
|
|
137
|
+
},
|
|
138
|
+
get() {
|
|
139
|
+
return instance;
|
|
140
|
+
}
|
|
141
|
+
} as any);
|
|
142
|
+
|
|
143
|
+
const invokeStub = vi.spyOn(builder, "invoke").mockReturnValue(undefined);
|
|
144
|
+
const buildHandlersStub = vi.spyOn(builder, "buildHandlers").mockReturnValue(undefined);
|
|
145
|
+
|
|
146
|
+
await builder.onConnection(socketStub, nspStub);
|
|
147
|
+
|
|
148
|
+
expect(buildHandlersStub).toHaveBeenCalledWith(socketStub, nspStub);
|
|
149
|
+
expect(invokeStub).toHaveBeenCalledWith(
|
|
150
|
+
instance,
|
|
151
|
+
{eventName: "connection", methodClassName: "$onConnection"},
|
|
152
|
+
{
|
|
153
|
+
socket: socketStub,
|
|
154
|
+
nsp: nspStub
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("should call the $onConnection in the context", async () => {
|
|
160
|
+
let ctx!: DIContext;
|
|
161
|
+
|
|
162
|
+
const instance = {
|
|
163
|
+
$onConnection: vi.fn().mockImplementation(() => {
|
|
164
|
+
ctx = getContext()!;
|
|
165
|
+
})
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const provider: any = {
|
|
169
|
+
store: {
|
|
170
|
+
get: vi.fn().mockReturnValue({
|
|
171
|
+
injectNamespace: "nsp",
|
|
172
|
+
handlers: {
|
|
173
|
+
$onConnection: {
|
|
174
|
+
eventName: "connection",
|
|
175
|
+
methodClassName: "$onConnection"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const nspStub: any = {nsp: "nsp", name: "nsp"};
|
|
182
|
+
const socketStub: any = {
|
|
183
|
+
id: "id",
|
|
184
|
+
on: vi.fn()
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
188
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
189
|
+
return fn;
|
|
190
|
+
},
|
|
191
|
+
get() {
|
|
192
|
+
return instance;
|
|
193
|
+
}
|
|
194
|
+
} as any);
|
|
195
|
+
|
|
196
|
+
await builder.onConnection(socketStub, nspStub);
|
|
197
|
+
|
|
198
|
+
expect(ctx).toMatchObject({
|
|
199
|
+
id: expect.any(String)
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
describe("onDisconnect()", () => {
|
|
204
|
+
it("should create the $onDisconnect method if is missing", async () => {
|
|
205
|
+
const instance = {
|
|
206
|
+
$onDisconnect: vi.fn()
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const provider: any = {
|
|
210
|
+
store: {
|
|
211
|
+
get: vi.fn().mockReturnValue({
|
|
212
|
+
injectNamespace: "nsp",
|
|
213
|
+
handlers: {
|
|
214
|
+
$onDisconnect: {
|
|
215
|
+
eventName: "disconnect",
|
|
216
|
+
methodClassName: "$onDisconnect"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const nspStub: any = {nsp: "nsp"};
|
|
223
|
+
const socketStub: any = {
|
|
224
|
+
on: vi.fn()
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
228
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
229
|
+
return fn;
|
|
230
|
+
},
|
|
231
|
+
get() {
|
|
232
|
+
return instance;
|
|
233
|
+
}
|
|
234
|
+
} as any);
|
|
235
|
+
const invokeStub = vi.spyOn(builder, "invoke").mockReturnValue(undefined);
|
|
236
|
+
|
|
237
|
+
await builder.onDisconnect(socketStub, nspStub);
|
|
238
|
+
|
|
239
|
+
expect(invokeStub).toHaveBeenCalledWith(
|
|
240
|
+
instance,
|
|
241
|
+
{eventName: "disconnect", methodClassName: "$onDisconnect"},
|
|
242
|
+
{
|
|
243
|
+
socket: socketStub,
|
|
244
|
+
nsp: nspStub
|
|
245
|
+
}
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it("should pass the disconnection reason", async () => {
|
|
250
|
+
const instance = {
|
|
251
|
+
$onDisconnect: vi.fn()
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const provider: any = {
|
|
255
|
+
store: {
|
|
256
|
+
get: vi.fn().mockReturnValue({
|
|
257
|
+
injectNamespace: "nsp",
|
|
258
|
+
handlers: {
|
|
259
|
+
$onDisconnect: {
|
|
260
|
+
eventName: "disconnect",
|
|
261
|
+
methodClassName: "$onDisconnect"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
const nspStub: any = {nsp: "nsp"};
|
|
268
|
+
const reason = "transport error";
|
|
269
|
+
const socketStub: any = {
|
|
270
|
+
on: vi.fn()
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
274
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
275
|
+
return fn;
|
|
276
|
+
},
|
|
277
|
+
get() {
|
|
278
|
+
return instance;
|
|
279
|
+
}
|
|
280
|
+
} as any);
|
|
281
|
+
const invokeStub = vi.spyOn(builder, "invoke").mockReturnValue(undefined);
|
|
282
|
+
|
|
283
|
+
await builder.onDisconnect(socketStub, nspStub, reason);
|
|
284
|
+
|
|
285
|
+
expect(invokeStub).toHaveBeenCalledWith(
|
|
286
|
+
instance,
|
|
287
|
+
{eventName: "disconnect", methodClassName: "$onDisconnect"},
|
|
288
|
+
{
|
|
289
|
+
reason,
|
|
290
|
+
socket: socketStub,
|
|
291
|
+
nsp: nspStub
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("should call the $onDisconnect in the context", async () => {
|
|
297
|
+
let ctx!: DIContext;
|
|
298
|
+
|
|
299
|
+
const instance = {
|
|
300
|
+
$onDisconnect: vi.fn().mockImplementation(() => {
|
|
301
|
+
ctx = getContext()!;
|
|
302
|
+
})
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const provider: any = {
|
|
306
|
+
store: {
|
|
307
|
+
get: vi.fn().mockReturnValue({
|
|
308
|
+
injectNamespace: "nsp",
|
|
309
|
+
handlers: {
|
|
310
|
+
$onDisconnect: {
|
|
311
|
+
eventName: "disconnect",
|
|
312
|
+
methodClassName: "$onDisconnect"
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
})
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
const nspStub: any = {nsp: "nsp", name: "nsp"};
|
|
319
|
+
const socketStub: any = {
|
|
320
|
+
id: "id",
|
|
321
|
+
on: vi.fn()
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
325
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
326
|
+
return fn;
|
|
327
|
+
},
|
|
328
|
+
get() {
|
|
329
|
+
return instance;
|
|
330
|
+
}
|
|
331
|
+
} as any);
|
|
332
|
+
|
|
333
|
+
await builder.onDisconnect(socketStub, nspStub);
|
|
334
|
+
|
|
335
|
+
expect(ctx).toMatchObject({
|
|
336
|
+
id: expect.any(String)
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
describe("buildHandlers()", () => {
|
|
342
|
+
it("should call socket.on() method", async () => {
|
|
343
|
+
const metadata = {
|
|
344
|
+
handlers: {
|
|
345
|
+
testHandler: {
|
|
346
|
+
eventName: "eventName"
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
const provider: any = {
|
|
351
|
+
store: {
|
|
352
|
+
get: vi.fn().mockReturnValue(metadata)
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
const socketStub = {
|
|
356
|
+
on: vi.fn().mockImplementation((_, fn) => fn("arg1"))
|
|
357
|
+
};
|
|
358
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
359
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
360
|
+
return fn;
|
|
361
|
+
}
|
|
362
|
+
} as any);
|
|
363
|
+
vi.spyOn(builder, "runQueue").mockResolvedValue(undefined);
|
|
364
|
+
|
|
365
|
+
await builder.buildHandlers(socketStub, "ws");
|
|
366
|
+
|
|
367
|
+
expect(socketStub.on).toHaveBeenCalledWith("eventName", expect.any(Function));
|
|
368
|
+
expect(builder.runQueue).toHaveBeenCalledWith(metadata.handlers.testHandler, ["arg1"], socketStub, "ws");
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it("should call the method instance in the context", async () => {
|
|
372
|
+
const metadata = {
|
|
373
|
+
handlers: {
|
|
374
|
+
testHandler: {
|
|
375
|
+
eventName: "eventName",
|
|
376
|
+
methodClassName: "testHandler"
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
let ctx!: DIContext;
|
|
381
|
+
const instance = {
|
|
382
|
+
testHandler: vi.fn().mockImplementation(() => {
|
|
383
|
+
ctx = getContext()!;
|
|
384
|
+
})
|
|
385
|
+
};
|
|
386
|
+
const provider: any = {
|
|
387
|
+
store: {
|
|
388
|
+
get: vi.fn().mockReturnValue(metadata)
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
let promise!: Promise<unknown>;
|
|
392
|
+
const socketStub = {
|
|
393
|
+
on: vi.fn().mockImplementation((_, fn) => (promise = fn("arg1")))
|
|
394
|
+
};
|
|
395
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
396
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
397
|
+
return fn;
|
|
398
|
+
},
|
|
399
|
+
get() {
|
|
400
|
+
return instance;
|
|
401
|
+
}
|
|
402
|
+
} as any);
|
|
403
|
+
|
|
404
|
+
await builder.buildHandlers(socketStub, "ws");
|
|
405
|
+
await promise;
|
|
406
|
+
|
|
407
|
+
expect(ctx).toMatchObject({
|
|
408
|
+
id: expect.any(String)
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
describe("invoke()", () => {
|
|
413
|
+
it("should call the method instance", () => {
|
|
414
|
+
const instance = {
|
|
415
|
+
testHandler: vi.fn().mockReturnValue("response")
|
|
416
|
+
};
|
|
417
|
+
const provider: any = {
|
|
418
|
+
store: {
|
|
419
|
+
get: vi.fn().mockReturnValue(metadata)
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
424
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
425
|
+
return fn;
|
|
426
|
+
},
|
|
427
|
+
get() {
|
|
428
|
+
return instance;
|
|
429
|
+
}
|
|
430
|
+
} as any);
|
|
431
|
+
const buildParametersStub = vi.spyOn(builder, "buildParameters").mockReturnValue(["argMapped"]);
|
|
432
|
+
|
|
433
|
+
builder.invoke(instance, metadata.handlers.testHandler, {scope: "scope"});
|
|
434
|
+
|
|
435
|
+
expect(buildParametersStub).toHaveBeenCalledWith(["param"], {
|
|
436
|
+
scope: "scope"
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
expect(instance.testHandler).toHaveBeenCalledWith("argMapped");
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
describe("buildParameters()", () => {
|
|
443
|
+
function createFixture() {
|
|
444
|
+
const instance: any = {
|
|
445
|
+
testHandler: vi.fn().mockReturnValue("response")
|
|
446
|
+
};
|
|
447
|
+
const provider: any = {
|
|
448
|
+
store: {
|
|
449
|
+
get: vi.fn().mockReturnValue(metadata)
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const builder: any = new SocketHandlersBuilder(provider, {
|
|
454
|
+
alterAsync(_event: any, fn: any, _ctx: any) {
|
|
455
|
+
return fn;
|
|
456
|
+
},
|
|
457
|
+
get() {
|
|
458
|
+
return instance;
|
|
459
|
+
}
|
|
460
|
+
} as any);
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
instance,
|
|
464
|
+
builder,
|
|
465
|
+
provider
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
describe("when ARGS", () => {
|
|
470
|
+
it("should return a list of parameters", () => {
|
|
471
|
+
const {builder} = createFixture();
|
|
472
|
+
|
|
473
|
+
const result = builder.buildParameters(
|
|
474
|
+
{
|
|
475
|
+
0: {
|
|
476
|
+
filter: SocketFilters.ARGS
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
{args: ["mapValue"]}
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
expect(result).toEqual([["mapValue"]]);
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
describe("when ARGS with mapIndex", () => {
|
|
487
|
+
it("should return a list of parameters", () => {
|
|
488
|
+
const {builder} = createFixture();
|
|
489
|
+
|
|
490
|
+
const result = builder.buildParameters(
|
|
491
|
+
{
|
|
492
|
+
0: {
|
|
493
|
+
filter: SocketFilters.ARGS,
|
|
494
|
+
mapIndex: 0
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
{args: ["mapValue"]}
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
expect(result).toEqual(["mapValue"]);
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
describe("when Socket", () => {
|
|
505
|
+
it("should return a list of parameters", () => {
|
|
506
|
+
const {builder} = createFixture();
|
|
507
|
+
|
|
508
|
+
const result = builder.buildParameters(
|
|
509
|
+
{
|
|
510
|
+
0: {
|
|
511
|
+
filter: SocketFilters.SOCKET
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
{socket: "socket"}
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
expect(result).toEqual(["socket"]);
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
describe("when NSP", () => {
|
|
522
|
+
it("should return a list of parameters", () => {
|
|
523
|
+
const {builder} = createFixture();
|
|
524
|
+
|
|
525
|
+
const result = builder.buildParameters(
|
|
526
|
+
{
|
|
527
|
+
0: {
|
|
528
|
+
filter: SocketFilters.NSP
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
{nsp: "nsp"}
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
expect(result).toEqual(["nsp"]);
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
describe("when REASON", () => {
|
|
539
|
+
it("should return a disconnect reason", () => {
|
|
540
|
+
const {builder} = createFixture();
|
|
541
|
+
|
|
542
|
+
const result = builder.buildParameters(
|
|
543
|
+
{
|
|
544
|
+
0: {
|
|
545
|
+
filter: SocketFilters.REASON
|
|
546
|
+
}
|
|
547
|
+
},
|
|
548
|
+
{reason: "transport error"}
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
expect(result).toEqual(["transport error"]);
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
describe("when ERROR", () => {
|
|
556
|
+
it("should return a list of parameters", () => {
|
|
557
|
+
const {builder} = createFixture();
|
|
558
|
+
|
|
559
|
+
const result = builder.buildParameters(
|
|
560
|
+
{
|
|
561
|
+
0: {
|
|
562
|
+
filter: SocketFilters.ERR
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
{error: "error"}
|
|
566
|
+
);
|
|
567
|
+
|
|
568
|
+
expect(result).toEqual(["error"]);
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
describe("when EVENT_NAME", () => {
|
|
573
|
+
it("should return a list of parameters", () => {
|
|
574
|
+
const {builder} = createFixture();
|
|
575
|
+
const result = builder.buildParameters(
|
|
576
|
+
{
|
|
577
|
+
0: {
|
|
578
|
+
filter: SocketFilters.EVENT_NAME
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
{eventName: "eventName"}
|
|
582
|
+
);
|
|
583
|
+
|
|
584
|
+
expect(result).toEqual(["eventName"]);
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
describe("when SESSION", () => {
|
|
589
|
+
it("should return a list of parameters", () => {
|
|
590
|
+
const data = {id: "id"};
|
|
591
|
+
|
|
592
|
+
const {builder} = createFixture();
|
|
593
|
+
|
|
594
|
+
const result = builder.buildParameters(
|
|
595
|
+
{
|
|
596
|
+
0: {
|
|
597
|
+
filter: SocketFilters.SESSION
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
{socket: {data, id: "id"}}
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
expect(new Map(result[0])).toEqual(new Map(Object.entries(data)));
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
describe("when RAW_SESSION", () => {
|
|
608
|
+
it("should return a list of parameters", () => {
|
|
609
|
+
const data = {id: "id"};
|
|
610
|
+
|
|
611
|
+
const {builder} = createFixture();
|
|
612
|
+
|
|
613
|
+
const result = builder.buildParameters(
|
|
614
|
+
{
|
|
615
|
+
0: {
|
|
616
|
+
filter: SocketFilters.RAW_SESSION
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
{socket: {data, id: "id"}}
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
expect(result[0]).toEqual(data);
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
describe("when SOCKET_NSP", () => {
|
|
627
|
+
it("should return a list of parameters", () => {
|
|
628
|
+
const {builder} = createFixture();
|
|
629
|
+
|
|
630
|
+
const result = builder.buildParameters(
|
|
631
|
+
{
|
|
632
|
+
0: {
|
|
633
|
+
filter: SocketFilters.SOCKET_NSP
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
{socket: {nsp: "socket_nsp"}}
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
expect(result).toEqual(["socket_nsp"]);
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
describe("bindResponseMiddleware()", () => {
|
|
644
|
+
describe("when BROADCAST", () => {
|
|
645
|
+
it("should call the ws.emit method", () => {
|
|
646
|
+
const nspStub = {
|
|
647
|
+
emit: vi.fn()
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
(SocketHandlersBuilder as any).bindResponseMiddleware(
|
|
651
|
+
{
|
|
652
|
+
returns: {
|
|
653
|
+
type: SocketReturnsTypes.BROADCAST,
|
|
654
|
+
eventName: "eventName"
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
{nsp: nspStub}
|
|
658
|
+
)({response: "response"});
|
|
659
|
+
|
|
660
|
+
expect(nspStub.emit).toHaveBeenCalledWith("eventName", {response: "response"});
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
describe("when BROADCAST_OTHERS", () => {
|
|
664
|
+
it("should call the socket.broadcast.emit method", () => {
|
|
665
|
+
const socketStub = {
|
|
666
|
+
broadcast: {
|
|
667
|
+
emit: vi.fn()
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
(SocketHandlersBuilder as any).bindResponseMiddleware(
|
|
672
|
+
{
|
|
673
|
+
returns: {
|
|
674
|
+
type: SocketReturnsTypes.BROADCAST_OTHERS,
|
|
675
|
+
eventName: "eventName"
|
|
676
|
+
}
|
|
677
|
+
},
|
|
678
|
+
{socket: socketStub}
|
|
679
|
+
)({response: "response"});
|
|
680
|
+
|
|
681
|
+
expect(socketStub.broadcast.emit).toHaveBeenCalledWith("eventName", {response: "response"});
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
describe("when EMIT", () => {
|
|
686
|
+
it("should call the socket.emit method", () => {
|
|
687
|
+
const socketStub = {
|
|
688
|
+
emit: vi.fn()
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
(SocketHandlersBuilder as any).bindResponseMiddleware(
|
|
692
|
+
{
|
|
693
|
+
returns: {
|
|
694
|
+
type: SocketReturnsTypes.EMIT,
|
|
695
|
+
eventName: "eventName"
|
|
696
|
+
}
|
|
697
|
+
},
|
|
698
|
+
{socket: socketStub}
|
|
699
|
+
)({response: "response"});
|
|
700
|
+
|
|
701
|
+
expect(socketStub.emit).toHaveBeenCalledWith("eventName", {response: "response"});
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
describe("runQueue()", () => {
|
|
706
|
+
function createServiceFixture() {
|
|
707
|
+
const provider = {
|
|
708
|
+
store: {
|
|
709
|
+
get: vi.fn().mockReturnValue({
|
|
710
|
+
useBefore: [{target: "target before global"}],
|
|
711
|
+
useAfter: [{target: "target after global"}]
|
|
712
|
+
})
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
const instance = {instance: "instance"};
|
|
716
|
+
|
|
717
|
+
const handlerMetadata = {
|
|
718
|
+
eventName: "eventName",
|
|
719
|
+
useBefore: [{target: "target before"}],
|
|
720
|
+
useAfter: [{target: "target after"}]
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
vi.spyOn(SocketHandlersBuilder as any, "bindResponseMiddleware").mockResolvedValue(undefined);
|
|
724
|
+
|
|
725
|
+
const builder: any = new SocketHandlersBuilder(
|
|
726
|
+
provider as any,
|
|
727
|
+
{
|
|
728
|
+
get() {
|
|
729
|
+
return instance;
|
|
730
|
+
}
|
|
731
|
+
} as any
|
|
732
|
+
);
|
|
733
|
+
|
|
734
|
+
vi.spyOn(builder, "invoke").mockResolvedValue(undefined);
|
|
735
|
+
vi.spyOn(builder, "bindMiddleware").mockResolvedValue(undefined);
|
|
736
|
+
vi.spyOn(builder, "deserialize").mockResolvedValue(undefined);
|
|
737
|
+
|
|
738
|
+
return {builder, handlerMetadata, provider, instance};
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
it("should call bindMiddleware (handler before global)", async () => {
|
|
742
|
+
const {builder, handlerMetadata, instance} = createServiceFixture();
|
|
743
|
+
|
|
744
|
+
await builder.runQueue(handlerMetadata, ["arg1"], "socket", "nsp");
|
|
745
|
+
|
|
746
|
+
expect((builder as any).bindMiddleware).toHaveBeenNthCalledWith(
|
|
747
|
+
1,
|
|
748
|
+
{target: "target before global"},
|
|
749
|
+
{
|
|
750
|
+
eventName: "eventName",
|
|
751
|
+
args: ["arg1"],
|
|
752
|
+
socket: "socket",
|
|
753
|
+
nsp: "nsp"
|
|
754
|
+
},
|
|
755
|
+
expect.any(Object)
|
|
756
|
+
);
|
|
757
|
+
|
|
758
|
+
expect((builder as any).bindMiddleware).toHaveBeenNthCalledWith(
|
|
759
|
+
2,
|
|
760
|
+
{target: "target before"},
|
|
761
|
+
{
|
|
762
|
+
eventName: "eventName",
|
|
763
|
+
args: ["arg1"],
|
|
764
|
+
socket: "socket",
|
|
765
|
+
nsp: "nsp"
|
|
766
|
+
},
|
|
767
|
+
expect.any(Object)
|
|
768
|
+
);
|
|
769
|
+
|
|
770
|
+
expect(builder.invoke).toHaveBeenCalledWith(instance, handlerMetadata, {
|
|
771
|
+
eventName: "eventName",
|
|
772
|
+
args: ["arg1"],
|
|
773
|
+
socket: "socket",
|
|
774
|
+
nsp: "nsp"
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
expect((SocketHandlersBuilder as any).bindResponseMiddleware).toHaveBeenCalledWith(handlerMetadata, {
|
|
778
|
+
eventName: "eventName",
|
|
779
|
+
args: ["arg1"],
|
|
780
|
+
socket: "socket",
|
|
781
|
+
nsp: "nsp"
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
expect((builder as any).bindMiddleware).toHaveBeenNthCalledWith(
|
|
785
|
+
3,
|
|
786
|
+
{target: "target after"},
|
|
787
|
+
{
|
|
788
|
+
eventName: "eventName",
|
|
789
|
+
args: ["arg1"],
|
|
790
|
+
socket: "socket",
|
|
791
|
+
nsp: "nsp"
|
|
792
|
+
},
|
|
793
|
+
expect.any(Object)
|
|
794
|
+
);
|
|
795
|
+
|
|
796
|
+
expect((builder as any).bindMiddleware).toHaveBeenNthCalledWith(
|
|
797
|
+
4,
|
|
798
|
+
{target: "target after global"},
|
|
799
|
+
{
|
|
800
|
+
eventName: "eventName",
|
|
801
|
+
args: ["arg1"],
|
|
802
|
+
socket: "socket",
|
|
803
|
+
nsp: "nsp"
|
|
804
|
+
},
|
|
805
|
+
expect.any(Object)
|
|
806
|
+
);
|
|
807
|
+
|
|
808
|
+
expect(builder.deserialize).toHaveBeenCalledWith(handlerMetadata, {
|
|
809
|
+
eventName: "eventName",
|
|
810
|
+
args: ["arg1"],
|
|
811
|
+
socket: "socket",
|
|
812
|
+
nsp: "nsp"
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
});
|
|
816
|
+
describe("bindMiddleware()", () => {
|
|
817
|
+
describe("middleware is not registered", () => {
|
|
818
|
+
it("should call Middleware.get", () => {
|
|
819
|
+
class Test {}
|
|
820
|
+
|
|
821
|
+
const injector = PlatformTest.get(InjectorService);
|
|
822
|
+
const provider: any = {
|
|
823
|
+
token: Test,
|
|
824
|
+
store: {
|
|
825
|
+
get: vi.fn()
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
Store.from(Test).set("socketIO", {
|
|
830
|
+
handlers: {
|
|
831
|
+
use: "use"
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
vi.spyOn(injector, "getProvider").mockReturnValue(false);
|
|
836
|
+
vi.spyOn(injector, "get").mockReturnValue(undefined);
|
|
837
|
+
|
|
838
|
+
const scope = {scope: "scope"};
|
|
839
|
+
|
|
840
|
+
const builder: any = new SocketHandlersBuilder(provider, injector);
|
|
841
|
+
vi.spyOn(builder, "invoke");
|
|
842
|
+
|
|
843
|
+
builder.bindMiddleware({target: "target"}, scope, Promise.resolve());
|
|
844
|
+
|
|
845
|
+
expect(injector.get).toHaveBeenCalledWith({target: "target"});
|
|
846
|
+
expect(builder.invoke).not.toHaveBeenCalled();
|
|
847
|
+
});
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
describe("middleware", () => {
|
|
851
|
+
it("should call build handler from metadata", async () => {
|
|
852
|
+
// GIVEN
|
|
853
|
+
class Test {}
|
|
854
|
+
|
|
855
|
+
const instance = new Test();
|
|
856
|
+
const provider = {
|
|
857
|
+
token: Test,
|
|
858
|
+
store: {
|
|
859
|
+
get: vi.fn()
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
|
|
863
|
+
Store.from(Test).set("socketIO", {
|
|
864
|
+
type: ProviderType.MIDDLEWARE,
|
|
865
|
+
handlers: {
|
|
866
|
+
use: "use"
|
|
867
|
+
}
|
|
868
|
+
});
|
|
869
|
+
const scope = {scope: "scope", args: undefined};
|
|
870
|
+
const injector = PlatformTest.get(InjectorService);
|
|
871
|
+
const builder: any = new SocketHandlersBuilder(provider as any, injector);
|
|
872
|
+
|
|
873
|
+
vi.spyOn(injector, "getProvider").mockReturnValue({type: ProviderType.MIDDLEWARE});
|
|
874
|
+
vi.spyOn(injector, "get").mockReturnValue(instance);
|
|
875
|
+
vi.spyOn(builder, "invoke").mockReturnValue({result: "result"});
|
|
876
|
+
|
|
877
|
+
// WHEN
|
|
878
|
+
await builder.bindMiddleware({target: "target"}, scope, Promise.resolve());
|
|
879
|
+
|
|
880
|
+
// THEN
|
|
881
|
+
expect(injector.get).toHaveBeenCalledWith({target: "target"});
|
|
882
|
+
expect(builder.invoke).toHaveBeenCalledWith(instance, "use", scope);
|
|
883
|
+
expect(scope.args).toEqual([{result: "result"}]);
|
|
884
|
+
});
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
describe("middleware error", () => {
|
|
888
|
+
it("should call build handler from metadata", async () => {
|
|
889
|
+
class Test {}
|
|
890
|
+
|
|
891
|
+
const injector = PlatformTest.get(InjectorService);
|
|
892
|
+
|
|
893
|
+
const instance = new Test();
|
|
894
|
+
const provider = {
|
|
895
|
+
store: {
|
|
896
|
+
get: vi.fn()
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
Store.from(Test).set("socketIO", {
|
|
901
|
+
type: ProviderType.MIDDLEWARE,
|
|
902
|
+
error: true,
|
|
903
|
+
handlers: {
|
|
904
|
+
use: "use"
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
const getProviderStub = vi.spyOn(injector as any, "getProvider");
|
|
909
|
+
const getStub = vi.spyOn(injector as any, "get");
|
|
910
|
+
getProviderStub.mockReturnValue({
|
|
911
|
+
type: ProviderType.MIDDLEWARE
|
|
912
|
+
});
|
|
913
|
+
getStub.mockReturnValue(instance);
|
|
914
|
+
|
|
915
|
+
const scope = {scope: "scope", args: undefined};
|
|
916
|
+
const error = new Error("test");
|
|
917
|
+
const builder: any = new SocketHandlersBuilder(provider as any, injector);
|
|
918
|
+
vi.spyOn(builder, "invoke").mockReturnValue({result: "result"});
|
|
919
|
+
|
|
920
|
+
// WHEN
|
|
921
|
+
await builder.bindMiddleware({target: "target"}, scope, Promise.reject(error));
|
|
922
|
+
|
|
923
|
+
// THEN
|
|
924
|
+
expect(injector.get).toHaveBeenCalledWith({target: "target"});
|
|
925
|
+
expect(builder.invoke).toHaveBeenCalledWith(instance, "use", {error, ...scope});
|
|
926
|
+
});
|
|
927
|
+
});
|
|
928
|
+
});
|
|
929
|
+
describe("deserialize()", () => {
|
|
930
|
+
it("should call deserialize on args", () => {
|
|
931
|
+
const provider: any = {
|
|
932
|
+
store: {
|
|
933
|
+
get: vi.fn()
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
const parameters: any[] = [
|
|
937
|
+
{
|
|
938
|
+
filter: SocketFilters.ARGS,
|
|
939
|
+
useMapper: true,
|
|
940
|
+
mapIndex: 0,
|
|
941
|
+
type: String,
|
|
942
|
+
collectionType: Array
|
|
943
|
+
}
|
|
944
|
+
];
|
|
945
|
+
const scope: any = {
|
|
946
|
+
args: ["any"]
|
|
947
|
+
};
|
|
948
|
+
|
|
949
|
+
const builder = new SocketHandlersBuilder(provider, PlatformTest.injector);
|
|
950
|
+
|
|
951
|
+
// @ts-ignore
|
|
952
|
+
builder.deserialize({parameters} as any, scope as any);
|
|
953
|
+
|
|
954
|
+
expect(scope).toEqual({
|
|
955
|
+
args: [["any"]]
|
|
956
|
+
});
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
it("should map ack callback without deserialization", () => {
|
|
960
|
+
const provider: any = {
|
|
961
|
+
store: {
|
|
962
|
+
get: vi.fn()
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
const parameters: any[] = [
|
|
966
|
+
{
|
|
967
|
+
filter: SocketFilters.ARGS,
|
|
968
|
+
useMapper: true,
|
|
969
|
+
mapIndex: 0,
|
|
970
|
+
type: Function
|
|
971
|
+
}
|
|
972
|
+
];
|
|
973
|
+
const ack = () => {};
|
|
974
|
+
const scope: any = {
|
|
975
|
+
args: [ack]
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
const builder = new SocketHandlersBuilder(provider, PlatformTest.injector);
|
|
979
|
+
|
|
980
|
+
// @ts-ignore
|
|
981
|
+
builder.deserialize({parameters} as any, scope as any);
|
|
982
|
+
|
|
983
|
+
expect(scope).toEqual({
|
|
984
|
+
args: [ack]
|
|
985
|
+
});
|
|
986
|
+
});
|
|
987
|
+
});
|
|
988
|
+
});
|