@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.
Files changed (71) hide show
  1. package/package.json +3 -3
  2. package/.eslintrc.json +0 -387
  3. package/dist/LICENSE +0 -674
  4. package/dist/README.md +0 -139
  5. package/dist/package.json +0 -51
  6. package/jest.config.js +0 -11
  7. package/src/abstracts/abstractRequest.test.ts +0 -49
  8. package/src/abstracts/abstractRequest.ts +0 -56
  9. package/src/abstracts/abstractResponse.ts +0 -26
  10. package/src/abstracts/middleware.test.ts +0 -75
  11. package/src/abstracts/middleware.ts +0 -50
  12. package/src/channel/channel.test.ts +0 -501
  13. package/src/channel/channel.ts +0 -305
  14. package/src/channel/eventRequest.test.ts +0 -37
  15. package/src/channel/eventRequest.ts +0 -27
  16. package/src/channel/eventResponse.test.ts +0 -249
  17. package/src/channel/eventResponse.ts +0 -172
  18. package/src/client/channel.test.ts +0 -799
  19. package/src/client/channel.ts +0 -342
  20. package/src/client.ts +0 -124
  21. package/src/endpoint/endpoint.test.ts +0 -825
  22. package/src/endpoint/endpoint.ts +0 -304
  23. package/src/endpoint/response.ts +0 -106
  24. package/src/enums.ts +0 -52
  25. package/src/errors/pondError.ts +0 -32
  26. package/src/express.ts +0 -58
  27. package/src/index.ts +0 -3
  28. package/src/lobby/JoinRequest.test.ts +0 -48
  29. package/src/lobby/JoinResponse.test.ts +0 -162
  30. package/src/lobby/joinRequest.ts +0 -32
  31. package/src/lobby/joinResponse.ts +0 -146
  32. package/src/lobby/lobby.ts +0 -182
  33. package/src/matcher/matcher.test.ts +0 -103
  34. package/src/matcher/matcher.ts +0 -105
  35. package/src/node.ts +0 -33
  36. package/src/presence/presence.ts +0 -127
  37. package/src/presence/presenceEngine.test.ts +0 -143
  38. package/src/server/pondSocket.ts +0 -153
  39. package/src/subjects/subject.test.ts +0 -163
  40. package/src/subjects/subject.ts +0 -137
  41. package/src/typedefs.d.ts +0 -451
  42. package/src/types.d.ts +0 -89
  43. package/tsconfig.build.json +0 -7
  44. package/tsconfig.json +0 -12
  45. /package/{dist/abstracts → abstracts}/abstractRequest.js +0 -0
  46. /package/{dist/abstracts → abstracts}/abstractResponse.js +0 -0
  47. /package/{dist/abstracts → abstracts}/middleware.js +0 -0
  48. /package/{dist/channel → channel}/channel.js +0 -0
  49. /package/{dist/channel → channel}/eventRequest.js +0 -0
  50. /package/{dist/channel → channel}/eventResponse.js +0 -0
  51. /package/{dist/client → client}/channel.js +0 -0
  52. /package/{dist/client.d.ts → client.d.ts} +0 -0
  53. /package/{dist/client.js → client.js} +0 -0
  54. /package/{dist/endpoint → endpoint}/endpoint.js +0 -0
  55. /package/{dist/endpoint → endpoint}/response.js +0 -0
  56. /package/{dist/enums.js → enums.js} +0 -0
  57. /package/{dist/errors → errors}/pondError.js +0 -0
  58. /package/{dist/express.d.ts → express.d.ts} +0 -0
  59. /package/{dist/express.js → express.js} +0 -0
  60. /package/{dist/index.d.ts → index.d.ts} +0 -0
  61. /package/{dist/index.js → index.js} +0 -0
  62. /package/{dist/lobby → lobby}/joinRequest.js +0 -0
  63. /package/{dist/lobby → lobby}/joinResponse.js +0 -0
  64. /package/{dist/lobby → lobby}/lobby.js +0 -0
  65. /package/{dist/matcher → matcher}/matcher.js +0 -0
  66. /package/{dist/node.d.ts → node.d.ts} +0 -0
  67. /package/{dist/node.js → node.js} +0 -0
  68. /package/{dist/presence → presence}/presence.js +0 -0
  69. /package/{dist/server → server}/pondSocket.js +0 -0
  70. /package/{dist/subjects → subjects}/subject.js +0 -0
  71. /package/{dist/types.d.ts → types.d.ts} +0 -0
@@ -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
- });