@eleven-am/pondsocket 0.1.57 → 0.1.58
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 +3 -3
- package/.eslintrc.json +0 -387
- package/dist/LICENSE +0 -674
- package/dist/README.md +0 -139
- package/dist/package.json +0 -51
- package/jest.config.js +0 -11
- package/src/abstracts/abstractRequest.test.ts +0 -49
- package/src/abstracts/abstractRequest.ts +0 -56
- package/src/abstracts/abstractResponse.ts +0 -26
- package/src/abstracts/middleware.test.ts +0 -75
- package/src/abstracts/middleware.ts +0 -50
- package/src/channel/channel.test.ts +0 -501
- package/src/channel/channel.ts +0 -305
- package/src/channel/eventRequest.test.ts +0 -37
- package/src/channel/eventRequest.ts +0 -27
- package/src/channel/eventResponse.test.ts +0 -249
- package/src/channel/eventResponse.ts +0 -172
- package/src/client/channel.test.ts +0 -799
- package/src/client/channel.ts +0 -342
- package/src/client.ts +0 -124
- package/src/endpoint/endpoint.test.ts +0 -825
- package/src/endpoint/endpoint.ts +0 -304
- package/src/endpoint/response.ts +0 -106
- package/src/enums.ts +0 -52
- package/src/errors/pondError.ts +0 -32
- package/src/express.ts +0 -58
- package/src/index.ts +0 -3
- package/src/lobby/JoinRequest.test.ts +0 -48
- package/src/lobby/JoinResponse.test.ts +0 -162
- package/src/lobby/joinRequest.ts +0 -32
- package/src/lobby/joinResponse.ts +0 -146
- package/src/lobby/lobby.ts +0 -182
- package/src/matcher/matcher.test.ts +0 -103
- package/src/matcher/matcher.ts +0 -105
- package/src/node.ts +0 -33
- package/src/presence/presence.ts +0 -127
- package/src/presence/presenceEngine.test.ts +0 -143
- package/src/server/pondSocket.ts +0 -153
- package/src/subjects/subject.test.ts +0 -163
- package/src/subjects/subject.ts +0 -137
- package/src/typedefs.d.ts +0 -451
- package/src/types.d.ts +0 -89
- package/tsconfig.build.json +0 -7
- package/tsconfig.json +0 -12
- /package/{dist/abstracts → abstracts}/abstractRequest.js +0 -0
- /package/{dist/abstracts → abstracts}/abstractResponse.js +0 -0
- /package/{dist/abstracts → abstracts}/middleware.js +0 -0
- /package/{dist/channel → channel}/channel.js +0 -0
- /package/{dist/channel → channel}/eventRequest.js +0 -0
- /package/{dist/channel → channel}/eventResponse.js +0 -0
- /package/{dist/client → client}/channel.js +0 -0
- /package/{dist/client.d.ts → client.d.ts} +0 -0
- /package/{dist/client.js → client.js} +0 -0
- /package/{dist/endpoint → endpoint}/endpoint.js +0 -0
- /package/{dist/endpoint → endpoint}/response.js +0 -0
- /package/{dist/enums.js → enums.js} +0 -0
- /package/{dist/errors → errors}/pondError.js +0 -0
- /package/{dist/express.d.ts → express.d.ts} +0 -0
- /package/{dist/express.js → express.js} +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
- /package/{dist/index.js → index.js} +0 -0
- /package/{dist/lobby → lobby}/joinRequest.js +0 -0
- /package/{dist/lobby → lobby}/joinResponse.js +0 -0
- /package/{dist/lobby → lobby}/lobby.js +0 -0
- /package/{dist/matcher → matcher}/matcher.js +0 -0
- /package/{dist/node.d.ts → node.d.ts} +0 -0
- /package/{dist/node.js → node.js} +0 -0
- /package/{dist/presence → presence}/presence.js +0 -0
- /package/{dist/server → server}/pondSocket.js +0 -0
- /package/{dist/subjects → subjects}/subject.js +0 -0
- /package/{dist/types.d.ts → types.d.ts} +0 -0
package/src/channel/channel.ts
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
import { EventRequest } from './eventRequest';
|
|
2
|
-
import { EventResponse } from './eventResponse';
|
|
3
|
-
import { MiddlewareFunction } from '../abstracts/middleware';
|
|
4
|
-
import { SystemSender, ServerActions, ChannelReceiver, ErrorTypes } from '../enums';
|
|
5
|
-
import { ChannelError } from '../errors/pondError';
|
|
6
|
-
import { PresenceEngine } from '../presence/presence';
|
|
7
|
-
import { Subject } from '../subjects/subject';
|
|
8
|
-
import {
|
|
9
|
-
PondMessage,
|
|
10
|
-
PondAssigns,
|
|
11
|
-
PondPresence,
|
|
12
|
-
UserAssigns,
|
|
13
|
-
ChannelEvent,
|
|
14
|
-
ChannelReceivers,
|
|
15
|
-
ClientMessage,
|
|
16
|
-
UserData,
|
|
17
|
-
// eslint-disable-next-line import/no-unresolved
|
|
18
|
-
} from '../types';
|
|
19
|
-
|
|
20
|
-
type ChannelSenders = SystemSender.CHANNEL | string;
|
|
21
|
-
|
|
22
|
-
export type InternalChannelEvent = ChannelEvent & {
|
|
23
|
-
recipients: string[];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type BroadcastEvent = Omit<InternalChannelEvent, 'action' | 'payload'> & {
|
|
27
|
-
action: ServerActions.BROADCAST;
|
|
28
|
-
sender: ChannelSenders;
|
|
29
|
-
payload: PondMessage;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type ParentEngine = {
|
|
33
|
-
destroyChannel: () => void;
|
|
34
|
-
execute: MiddlewareFunction<EventRequest<string>, EventResponse>;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class ChannelEngine {
|
|
38
|
-
public readonly name: string;
|
|
39
|
-
|
|
40
|
-
readonly #receiver: Subject<InternalChannelEvent>;
|
|
41
|
-
|
|
42
|
-
#presenceEngine: PresenceEngine | undefined;
|
|
43
|
-
|
|
44
|
-
readonly #users: Map<string, PondAssigns>;
|
|
45
|
-
|
|
46
|
-
readonly #parentEngine: ParentEngine;
|
|
47
|
-
|
|
48
|
-
constructor (name: string, parent: ParentEngine) {
|
|
49
|
-
this.name = name;
|
|
50
|
-
this.#receiver = new Subject<InternalChannelEvent>();
|
|
51
|
-
this.#users = new Map<string, PondAssigns>();
|
|
52
|
-
this.#parentEngine = parent;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @desc Adds a user to the channel
|
|
57
|
-
* @param userId - The id of the user to add
|
|
58
|
-
* @param assigns - The assigns to add to the user
|
|
59
|
-
* @param onMessage - The callback to call when a message is received
|
|
60
|
-
*/
|
|
61
|
-
public addUser (userId: string, assigns: PondAssigns, onMessage: (event: ChannelEvent) => void) {
|
|
62
|
-
const oldUser = this.#users.get(userId);
|
|
63
|
-
|
|
64
|
-
if (oldUser) {
|
|
65
|
-
const message = `ChannelEngine: User with id ${userId} already exists in channel ${this.name}`;
|
|
66
|
-
const code = 400;
|
|
67
|
-
|
|
68
|
-
throw new ChannelError(message, code, this.name);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
this.#users.set(userId, assigns);
|
|
72
|
-
|
|
73
|
-
return this.#subscribe(userId, onMessage);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @desc Removes a user from the channel
|
|
78
|
-
* @param userId - The id of the user to remove
|
|
79
|
-
* @param graceful - Whether to remove the user gracefully or not
|
|
80
|
-
*/
|
|
81
|
-
public removeUser (userId: string, graceful = false) {
|
|
82
|
-
const user = this.#users.get(userId);
|
|
83
|
-
|
|
84
|
-
if (user) {
|
|
85
|
-
this.#users.delete(userId);
|
|
86
|
-
this.#receiver.unsubscribe(userId);
|
|
87
|
-
this.#presenceEngine?.removePresence(userId, graceful);
|
|
88
|
-
|
|
89
|
-
if (this.#users.size === 0) {
|
|
90
|
-
this.#parentEngine.destroyChannel();
|
|
91
|
-
}
|
|
92
|
-
} else if (!graceful) {
|
|
93
|
-
throw new ChannelError(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`, 404, this.name);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* @desc Kicks a user from the channel
|
|
99
|
-
* @param userId - The id of the user to kick
|
|
100
|
-
* @param reason - The reason for kicking the user
|
|
101
|
-
*/
|
|
102
|
-
public kickUser (userId: string, reason: string) {
|
|
103
|
-
this.sendMessage(SystemSender.CHANNEL, [userId], ServerActions.SYSTEM, 'kicked_out', {
|
|
104
|
-
message: reason ?? 'You have been kicked out of the channel',
|
|
105
|
-
});
|
|
106
|
-
this.removeUser(userId);
|
|
107
|
-
this.sendMessage(SystemSender.CHANNEL, ChannelReceiver.ALL_USERS, ServerActions.SYSTEM, 'kicked', {
|
|
108
|
-
userId,
|
|
109
|
-
reason,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* @desc Self destructs the channel
|
|
115
|
-
* @param reason - The reason for self-destructing the channel
|
|
116
|
-
*/
|
|
117
|
-
public destroy (reason: string) {
|
|
118
|
-
this.sendMessage(SystemSender.CHANNEL, ChannelReceiver.ALL_USERS, ServerActions.ERROR, 'destroyed', {
|
|
119
|
-
message: reason ?? 'Channel has been destroyed',
|
|
120
|
-
});
|
|
121
|
-
this.#parentEngine.destroyChannel();
|
|
122
|
-
this.#users.forEach((_, userId) => this.#receiver.unsubscribe(userId));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* @desc Updates a user's assigns
|
|
127
|
-
* @param userId - The id of the user to update
|
|
128
|
-
* @param assigns - The new assigns of the user
|
|
129
|
-
*/
|
|
130
|
-
public updateAssigns (userId: string, assigns: PondAssigns) {
|
|
131
|
-
const user = this.#users.get(userId);
|
|
132
|
-
|
|
133
|
-
if (user) {
|
|
134
|
-
this.#users.set(userId, {
|
|
135
|
-
...user,
|
|
136
|
-
...assigns,
|
|
137
|
-
});
|
|
138
|
-
} else {
|
|
139
|
-
throw new ChannelError(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`, 404, this.name);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* @desc Gets the data of a user
|
|
145
|
-
* @param userId - The id of the user to get
|
|
146
|
-
*/
|
|
147
|
-
public getUserData (userId: string): UserData | undefined {
|
|
148
|
-
const assigns = this.#users.get(userId);
|
|
149
|
-
const presence = this.#presenceEngine ? this.#presenceEngine.getUserPresence(userId) : {};
|
|
150
|
-
|
|
151
|
-
if (assigns) {
|
|
152
|
-
return {
|
|
153
|
-
assigns,
|
|
154
|
-
id: userId,
|
|
155
|
-
presence: presence || {},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* @desc Gets the assign data of all users
|
|
164
|
-
*/
|
|
165
|
-
public getAssigns (): UserAssigns {
|
|
166
|
-
const assigns: UserAssigns = {};
|
|
167
|
-
|
|
168
|
-
this.#users.forEach((value, key) => {
|
|
169
|
-
assigns[key] = value;
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
return assigns;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* @desc Sends a message to a specified set of users, from a specified sender
|
|
177
|
-
* @param sender - The sender of the message
|
|
178
|
-
* @param recipient - The users to send the message to
|
|
179
|
-
* @param action - The action of the message
|
|
180
|
-
* @param event - The event name
|
|
181
|
-
* @param payload - The payload of the message
|
|
182
|
-
* @private
|
|
183
|
-
*/
|
|
184
|
-
public sendMessage (sender: ChannelSenders, recipient: ChannelReceivers, action: ServerActions, event: string, payload: PondMessage) {
|
|
185
|
-
if (!this.#users.has(sender) && sender !== SystemSender.CHANNEL) {
|
|
186
|
-
throw new ChannelError(`ChannelEngine: User with id ${sender} does not exist in channel ${this.name}`, 404, this.name);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const eventMessage = {
|
|
190
|
-
recipients: this.#getUsersFromRecipients(recipient, sender),
|
|
191
|
-
channelName: this.name,
|
|
192
|
-
action,
|
|
193
|
-
payload,
|
|
194
|
-
event,
|
|
195
|
-
} as InternalChannelEvent;
|
|
196
|
-
|
|
197
|
-
this.#receiver.publish(eventMessage);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* @desc Handles a message from a user
|
|
202
|
-
* @param userId - The id of the user who sent the message
|
|
203
|
-
* @param message - The message received
|
|
204
|
-
*/
|
|
205
|
-
public broadcastMessage (userId: string, message: ClientMessage) {
|
|
206
|
-
if (!this.#users.has(userId)) {
|
|
207
|
-
throw new ChannelError(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`, 404, this.name);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const responseEvent: BroadcastEvent = {
|
|
211
|
-
sender: userId,
|
|
212
|
-
event: message.event,
|
|
213
|
-
payload: message.payload,
|
|
214
|
-
action: ServerActions.BROADCAST,
|
|
215
|
-
channelName: this.name,
|
|
216
|
-
recipients: this.#getUsersFromRecipients(message.addresses || ChannelReceiver.ALL_USERS, userId),
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const request = new EventRequest(responseEvent, this);
|
|
220
|
-
const response = new EventResponse(responseEvent, this);
|
|
221
|
-
|
|
222
|
-
this.#parentEngine.execute(request, response, () => {
|
|
223
|
-
this.sendMessage(SystemSender.CHANNEL, [userId], ServerActions.ERROR, ErrorTypes.HANDLER_NOT_FOUND, {
|
|
224
|
-
message: 'A handler did not respond to the event',
|
|
225
|
-
code: 404,
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* @desc Begins tracking a user's presence
|
|
232
|
-
* @param userId - The id of the user to track
|
|
233
|
-
* @param presence - The initial presence of the user
|
|
234
|
-
*/
|
|
235
|
-
public trackPresence (userId: string, presence: PondPresence) {
|
|
236
|
-
if (!this.#users.has(userId)) {
|
|
237
|
-
throw new ChannelError(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`, 404, this.name);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
this.#presenceEngine = this.#presenceEngine ?? new PresenceEngine(this);
|
|
241
|
-
this.#presenceEngine.trackPresence(userId, presence);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* @desc Gets the presence engine for the channel
|
|
246
|
-
*/
|
|
247
|
-
public get presenceEngine () {
|
|
248
|
-
return this.#presenceEngine;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* @desc Gets the number of users in the channel
|
|
253
|
-
*/
|
|
254
|
-
public get size () {
|
|
255
|
-
return this.#users.size;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* @desc Subscribes a user to the channel
|
|
260
|
-
* @param userId - The id of the user to subscribe
|
|
261
|
-
* @param onMessage - The callback to call when a message is received
|
|
262
|
-
* @private
|
|
263
|
-
*/
|
|
264
|
-
#subscribe (userId: string, onMessage: (event: ChannelEvent) => void) {
|
|
265
|
-
this.#receiver.subscribeWith(userId, ({ recipients, ...event }) => {
|
|
266
|
-
if (recipients.includes(userId)) {
|
|
267
|
-
onMessage(event);
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* @desc Gets the users from a set of recipients
|
|
274
|
-
* @param recipients - The recipients to get the users from
|
|
275
|
-
* @param sender - The sender of the message
|
|
276
|
-
* @private
|
|
277
|
-
*/
|
|
278
|
-
#getUsersFromRecipients (recipients: ChannelReceivers, sender: ChannelSenders): string[] {
|
|
279
|
-
const allUsers = Array.from(this.#users.keys());
|
|
280
|
-
let users: string[];
|
|
281
|
-
|
|
282
|
-
switch (recipients) {
|
|
283
|
-
case ChannelReceiver.ALL_USERS:
|
|
284
|
-
users = allUsers;
|
|
285
|
-
break;
|
|
286
|
-
case ChannelReceiver.ALL_EXCEPT_SENDER:
|
|
287
|
-
if (sender === SystemSender.CHANNEL) {
|
|
288
|
-
throw new ChannelError(`ChannelEngine: Cannot use ${ChannelReceiver.ALL_EXCEPT_SENDER} with ${SystemSender.CHANNEL}`, 500, this.name);
|
|
289
|
-
}
|
|
290
|
-
users = allUsers.filter((user) => user !== sender);
|
|
291
|
-
break;
|
|
292
|
-
default:
|
|
293
|
-
const absentUsers = recipients.filter((user) => !allUsers.includes(user));
|
|
294
|
-
|
|
295
|
-
if (absentUsers.length > 0) {
|
|
296
|
-
throw new ChannelError(`ChannelEngine: Users ${absentUsers.join(', ')} are not in channel ${this.name}`, 400, this.name);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
users = recipients;
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return users;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { EventRequest } from './eventRequest';
|
|
2
|
-
import { createChannelEngine, createChannelEvent } from './eventResponse.test';
|
|
3
|
-
|
|
4
|
-
describe('ChannelRequest', () => {
|
|
5
|
-
it('should create a new ChannelRequest', () => {
|
|
6
|
-
const channelEngine = createChannelEngine();
|
|
7
|
-
const event = createChannelEvent(channelEngine.name);
|
|
8
|
-
const channelRequest = new EventRequest(event, channelEngine);
|
|
9
|
-
|
|
10
|
-
expect(channelRequest).toBeDefined();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should return the payload', () => {
|
|
14
|
-
const channelEngine = createChannelEngine();
|
|
15
|
-
const event = createChannelEvent(channelEngine.name);
|
|
16
|
-
const channelRequest = new EventRequest(event, channelEngine);
|
|
17
|
-
|
|
18
|
-
channelRequest._parseQueries('event');
|
|
19
|
-
|
|
20
|
-
expect(channelRequest.event.payload).toEqual(event.payload);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should return the user', () => {
|
|
24
|
-
const channelEngine = createChannelEngine();
|
|
25
|
-
const event = createChannelEvent(channelEngine.name);
|
|
26
|
-
const channelRequest = new EventRequest(event, channelEngine);
|
|
27
|
-
|
|
28
|
-
// because the user in the event does not exist in the channel, this should throw an error
|
|
29
|
-
expect(() => channelRequest.user).toThrow();
|
|
30
|
-
|
|
31
|
-
// add the user to the channel
|
|
32
|
-
channelEngine.addUser(event.sender, { assign: 'assign' }, () => {});
|
|
33
|
-
|
|
34
|
-
// now the user should be returned
|
|
35
|
-
expect(channelRequest.user).toEqual(channelEngine.getUserData(event.sender));
|
|
36
|
-
});
|
|
37
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ChannelEngine, BroadcastEvent } from './channel';
|
|
2
|
-
import { AbstractRequest } from '../abstracts/abstractRequest';
|
|
3
|
-
import { ChannelError } from '../errors/pondError';
|
|
4
|
-
// eslint-disable-next-line import/no-unresolved
|
|
5
|
-
import { UserData } from '../types';
|
|
6
|
-
|
|
7
|
-
export class EventRequest<Path extends string> extends AbstractRequest<Path> {
|
|
8
|
-
private readonly _internalEvent: BroadcastEvent;
|
|
9
|
-
|
|
10
|
-
constructor (event: BroadcastEvent, engine: ChannelEngine) {
|
|
11
|
-
super(event.event, engine, event.payload);
|
|
12
|
-
this._internalEvent = event;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public get user (): UserData {
|
|
16
|
-
const assigns = this._engine.getUserData(this._internalEvent.sender);
|
|
17
|
-
|
|
18
|
-
if (!assigns) {
|
|
19
|
-
const message = `ChannelRequest: User with id ${this._internalEvent.sender} does not exist in channel ${this._engine.name}`;
|
|
20
|
-
const code = 404;
|
|
21
|
-
|
|
22
|
-
throw new ChannelError(message, code, this._engine.name);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return assigns;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import { ChannelEngine, BroadcastEvent } from './channel';
|
|
2
|
-
import { createParentEngine } from './channel.test';
|
|
3
|
-
import { EventResponse } from './eventResponse';
|
|
4
|
-
import { ServerActions, SystemSender, ErrorTypes, ChannelReceiver } from '../enums';
|
|
5
|
-
|
|
6
|
-
export const createChannelEngine = () => {
|
|
7
|
-
const parentEngine = createParentEngine();
|
|
8
|
-
|
|
9
|
-
return new ChannelEngine('test', parentEngine);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const createChannelEvent = (name: string) => {
|
|
13
|
-
const responseEvent: BroadcastEvent = {
|
|
14
|
-
event: 'event',
|
|
15
|
-
payload: {
|
|
16
|
-
payload: 'payload',
|
|
17
|
-
},
|
|
18
|
-
sender: 'sender',
|
|
19
|
-
action: ServerActions.BROADCAST,
|
|
20
|
-
recipients: ['recipient'],
|
|
21
|
-
channelName: name,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return responseEvent;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const createChannelResponse = () => {
|
|
28
|
-
const channelEngine = createChannelEngine();
|
|
29
|
-
const event = createChannelEvent(channelEngine.name);
|
|
30
|
-
|
|
31
|
-
channelEngine.addUser(event.sender, { assign: 'assign' }, () => {});
|
|
32
|
-
channelEngine.addUser(event.recipients[0], { assign: 'assign' }, () => {});
|
|
33
|
-
const response = new EventResponse(event, channelEngine);
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
channelEngine,
|
|
37
|
-
event,
|
|
38
|
-
response,
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
describe('ChannelResponse', () => {
|
|
43
|
-
it('should create a new ChannelResponse', () => {
|
|
44
|
-
const { response } = createChannelResponse();
|
|
45
|
-
|
|
46
|
-
expect(response).toBeDefined();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should accept the request', () => {
|
|
50
|
-
const { response, channelEngine } = createChannelResponse();
|
|
51
|
-
|
|
52
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
53
|
-
|
|
54
|
-
response.accept();
|
|
55
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith('sender', ['recipient'], ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should reject the request', () => {
|
|
59
|
-
const { response, channelEngine, event } = createChannelResponse();
|
|
60
|
-
|
|
61
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
62
|
-
response.reject();
|
|
63
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith(SystemSender.CHANNEL, [event.sender], ServerActions.ERROR, ErrorTypes.UNAUTHORIZED_BROADCAST, {
|
|
64
|
-
message: 'Unauthorized request',
|
|
65
|
-
code: 403,
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should send a direct message', () => {
|
|
70
|
-
const { response, channelEngine, event } = createChannelResponse();
|
|
71
|
-
|
|
72
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
73
|
-
response.send('event', { payload: 'payload' });
|
|
74
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith(SystemSender.CHANNEL, [event.sender], ServerActions.SYSTEM, 'event', { payload: 'payload' });
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should broadcast a message', () => {
|
|
78
|
-
const { response, channelEngine } = createChannelResponse();
|
|
79
|
-
|
|
80
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
81
|
-
response.broadcast('event', { payload: 'payload' });
|
|
82
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith('sender', ChannelReceiver.ALL_USERS, ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should broadcastFromUser a message', () => {
|
|
86
|
-
const { response, channelEngine } = createChannelResponse();
|
|
87
|
-
|
|
88
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
89
|
-
response.broadcastFromUser('event', { payload: 'payload' });
|
|
90
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith('sender', ChannelReceiver.ALL_EXCEPT_SENDER, ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should sendToUsers a message', () => {
|
|
94
|
-
const { response, channelEngine } = createChannelResponse();
|
|
95
|
-
|
|
96
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
97
|
-
response.sendToUsers('event', { payload: 'payload' }, ['recipient']);
|
|
98
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith('sender', ['recipient'], ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should fail to send to non existing users', () => {
|
|
102
|
-
const { event, response, channelEngine } = createChannelResponse();
|
|
103
|
-
|
|
104
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
105
|
-
event.recipients = ['non_existing_user'];
|
|
106
|
-
|
|
107
|
-
expect(() => response.accept()).toThrowError('ChannelEngine: Users non_existing_user are not in channel test');
|
|
108
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith(event.sender, ['non_existing_user'], ServerActions.BROADCAST, event.event, event.payload);
|
|
109
|
-
|
|
110
|
-
expect(() => response.sendToUsers('event', { payload: 'payload' }, ['non_existing_user']))
|
|
111
|
-
.toThrowError('ChannelEngine: Users non_existing_user are not in channel test');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should track a trackPresence', () => {
|
|
115
|
-
const { response, channelEngine } = createChannelResponse();
|
|
116
|
-
|
|
117
|
-
jest.spyOn(channelEngine, 'trackPresence');
|
|
118
|
-
response.trackPresence({ status: 'online' });
|
|
119
|
-
expect(channelEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should update a users assign data', () => {
|
|
123
|
-
const { response, channelEngine } = createChannelResponse();
|
|
124
|
-
|
|
125
|
-
jest.spyOn(channelEngine, 'updateAssigns');
|
|
126
|
-
response.accept({ assign: 'updated' });
|
|
127
|
-
expect(channelEngine.updateAssigns).toHaveBeenCalledWith('sender', { assign: 'updated' });
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should evict a user', () => {
|
|
131
|
-
const { response, channelEngine } = createChannelResponse();
|
|
132
|
-
|
|
133
|
-
jest.spyOn(channelEngine, 'kickUser');
|
|
134
|
-
response.evictUser('recipient');
|
|
135
|
-
expect(channelEngine.kickUser).toHaveBeenCalledWith('sender', 'recipient');
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('should destroy the channel', () => {
|
|
139
|
-
const { response, channelEngine } = createChannelResponse();
|
|
140
|
-
|
|
141
|
-
jest.spyOn(channelEngine, 'destroy');
|
|
142
|
-
response.closeChannel('recipient');
|
|
143
|
-
expect(channelEngine.destroy).toHaveBeenCalledWith('recipient');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should call the presence engine when the trackPresence is called', () => {
|
|
147
|
-
const { response, channelEngine } = createChannelResponse();
|
|
148
|
-
|
|
149
|
-
jest.spyOn(channelEngine, 'trackPresence');
|
|
150
|
-
expect(channelEngine.trackPresence).not.toHaveBeenCalled();
|
|
151
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
152
|
-
response.accept();
|
|
153
|
-
response.trackPresence({ status: 'online' });
|
|
154
|
-
expect(channelEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('should throw an error if trackPresence is called twice', () => {
|
|
158
|
-
const { response, channelEngine } = createChannelResponse();
|
|
159
|
-
|
|
160
|
-
jest.spyOn(channelEngine, 'trackPresence');
|
|
161
|
-
expect(channelEngine.trackPresence).not.toHaveBeenCalled();
|
|
162
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
163
|
-
response.accept();
|
|
164
|
-
response.trackPresence({ status: 'online' });
|
|
165
|
-
expect(channelEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
166
|
-
expect(() => response.trackPresence({ status: 'online' })).toThrowError('PresenceEngine: Presence with key sender already exists');
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('should throw an error if trackPresence is called for a non existing user', () => {
|
|
170
|
-
const { response, channelEngine } = createChannelResponse();
|
|
171
|
-
|
|
172
|
-
jest.spyOn(channelEngine, 'trackPresence');
|
|
173
|
-
expect(channelEngine.trackPresence).not.toHaveBeenCalled();
|
|
174
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
175
|
-
response.accept();
|
|
176
|
-
expect(() => response.trackPresence({ status: 'online' }, 'non_existent_user'))
|
|
177
|
-
.toThrowError('ChannelEngine: User with id non_existent_user does not exist in channel test');
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should update the presence of a user that is already tracked', () => {
|
|
181
|
-
const { response, channelEngine } = createChannelResponse();
|
|
182
|
-
|
|
183
|
-
jest.spyOn(channelEngine, 'trackPresence');
|
|
184
|
-
expect(channelEngine.trackPresence).not.toHaveBeenCalled();
|
|
185
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
186
|
-
response.accept();
|
|
187
|
-
expect(channelEngine.presenceEngine?.getPresence()).toBeUndefined();
|
|
188
|
-
response.trackPresence({ status: 'online' });
|
|
189
|
-
expect(channelEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
190
|
-
expect(channelEngine.presenceEngine?.getPresence()).toEqual({
|
|
191
|
-
sender: { status: 'online' },
|
|
192
|
-
});
|
|
193
|
-
response.updatePresence({ status: 'offline' });
|
|
194
|
-
expect(channelEngine.presenceEngine?.getPresence()).toEqual({
|
|
195
|
-
sender: { status: 'offline' },
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should throw an error if updatePresence is called for a non existing user', () => {
|
|
200
|
-
const { response, channelEngine } = createChannelResponse();
|
|
201
|
-
|
|
202
|
-
jest.spyOn(channelEngine, 'trackPresence');
|
|
203
|
-
expect(channelEngine.trackPresence).not.toHaveBeenCalled();
|
|
204
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
205
|
-
response.accept();
|
|
206
|
-
expect(channelEngine.presenceEngine?.getPresence()).toBeUndefined();
|
|
207
|
-
response.trackPresence({ status: 'online' });
|
|
208
|
-
expect(() => response.updatePresence({ status: 'online' }, 'non_existent_user'))
|
|
209
|
-
.toThrowError('PresenceEngine: Presence with key non_existent_user does not exist');
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('should unTrack a trackPresence', () => {
|
|
213
|
-
const { response, channelEngine } = createChannelResponse();
|
|
214
|
-
|
|
215
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
216
|
-
response.trackPresence({ status: 'online' });
|
|
217
|
-
expect(channelEngine.presenceEngine?.getPresence()).toEqual({
|
|
218
|
-
sender: { status: 'online' },
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
response.unTrackPresence();
|
|
222
|
-
expect(channelEngine.presenceEngine?.getPresence()).toEqual({});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('should throw an error if unTrackPresence is called for a non existing user', () => {
|
|
226
|
-
const { response, channelEngine } = createChannelResponse();
|
|
227
|
-
|
|
228
|
-
expect(channelEngine.presenceEngine).toBeUndefined();
|
|
229
|
-
response.trackPresence({ status: 'online' });
|
|
230
|
-
expect(channelEngine.presenceEngine?.getPresence()).toEqual({
|
|
231
|
-
sender: { status: 'online' },
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
expect(() => response.unTrackPresence('non_existent_user'))
|
|
235
|
-
.toThrowError('PresenceEngine: Presence with key non_existent_user does not exist');
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it('should throw an error if accept, reject / send is called more than once', () => {
|
|
239
|
-
const { response, channelEngine } = createChannelResponse();
|
|
240
|
-
|
|
241
|
-
jest.spyOn(channelEngine, 'sendMessage');
|
|
242
|
-
expect(channelEngine.sendMessage).not.toHaveBeenCalled();
|
|
243
|
-
response.accept();
|
|
244
|
-
expect(channelEngine.sendMessage).toHaveBeenCalledWith('sender', ['recipient'], ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
245
|
-
expect(() => response.accept()).toThrowError('Event response has already been executed');
|
|
246
|
-
expect(() => response.reject()).toThrowError('Event response has already been executed');
|
|
247
|
-
expect(() => response.send('event', { payload: 'payload' })).toThrowError('Event response has already been executed');
|
|
248
|
-
});
|
|
249
|
-
});
|