@fluid-internal/presence-runtime 2.102.0 → 2.110.0
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/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/runtime/extension/containerPresence.d.ts +1 -1
- package/dist/runtime/presenceDatastoreManager.d.ts +2 -2
- package/dist/runtime/presenceDatastoreManager.d.ts.map +1 -1
- package/dist/runtime/presenceDatastoreManager.js.map +1 -1
- package/dist/runtime/presenceManager.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/runtime/extension/containerPresence.d.ts +1 -1
- package/lib/runtime/presenceDatastoreManager.d.ts +2 -2
- package/lib/runtime/presenceDatastoreManager.d.ts.map +1 -1
- package/lib/runtime/presenceDatastoreManager.js.map +1 -1
- package/lib/runtime/presenceManager.js.map +1 -1
- package/package.json +15 -15
- package/dist/runtime/test/presenceDatastoreManager.spec.js +0 -618
- package/dist/runtime/test/presenceDatastoreManager.spec.js.map +0 -1
- package/dist/runtime/test/presenceManager.spec.js +0 -651
- package/dist/runtime/test/presenceManager.spec.js.map +0 -1
- package/dist/states/test/batching.spec.js +0 -843
- package/dist/states/test/batching.spec.js.map +0 -1
- package/dist/states/test/broadcastControlsTests.js +0 -60
- package/dist/states/test/broadcastControlsTests.js.map +0 -1
- package/dist/states/test/eventing.spec.js +0 -576
- package/dist/states/test/eventing.spec.js.map +0 -1
- package/dist/states/test/latestMapValueManager.spec.js +0 -210
- package/dist/states/test/latestMapValueManager.spec.js.map +0 -1
- package/dist/states/test/latestValueManager.spec.js +0 -193
- package/dist/states/test/latestValueManager.spec.js.map +0 -1
- package/dist/states/test/mockEphemeralRuntime.js +0 -11
- package/dist/states/test/mockEphemeralRuntime.js.map +0 -1
- package/dist/states/test/notificationsManager.spec.js +0 -460
- package/dist/states/test/notificationsManager.spec.js.map +0 -1
- package/dist/states/test/presenceStates.spec.js +0 -73
- package/dist/states/test/presenceStates.spec.js.map +0 -1
- package/dist/states/test/schemaValidation/protocol.spec.js +0 -246
- package/dist/states/test/schemaValidation/protocol.spec.js.map +0 -1
- package/dist/states/test/schemaValidation/valueManagers.spec.js +0 -784
- package/dist/states/test/schemaValidation/valueManagers.spec.js.map +0 -1
- package/dist/states/test/testUtils.js +0 -21
- package/dist/states/test/testUtils.js.map +0 -1
- package/dist/test/mockEphemeralRuntime.js +0 -175
- package/dist/test/mockEphemeralRuntime.js.map +0 -1
- package/dist/test/testUtils.js +0 -262
- package/dist/test/testUtils.js.map +0 -1
- package/dist/test/utils/index.js +0 -27
- package/dist/test/utils/index.js.map +0 -1
- package/dist/utils/test/timerManager.spec.js +0 -93
- package/dist/utils/test/timerManager.spec.js.map +0 -1
- package/lib/runtime/test/presenceDatastoreManager.spec.js +0 -616
- package/lib/runtime/test/presenceDatastoreManager.spec.js.map +0 -1
- package/lib/runtime/test/presenceManager.spec.js +0 -649
- package/lib/runtime/test/presenceManager.spec.js.map +0 -1
- package/lib/states/test/batching.spec.js +0 -841
- package/lib/states/test/batching.spec.js.map +0 -1
- package/lib/states/test/broadcastControlsTests.js +0 -56
- package/lib/states/test/broadcastControlsTests.js.map +0 -1
- package/lib/states/test/eventing.spec.js +0 -574
- package/lib/states/test/eventing.spec.js.map +0 -1
- package/lib/states/test/latestMapValueManager.spec.js +0 -206
- package/lib/states/test/latestMapValueManager.spec.js.map +0 -1
- package/lib/states/test/latestValueManager.spec.js +0 -189
- package/lib/states/test/latestValueManager.spec.js.map +0 -1
- package/lib/states/test/mockEphemeralRuntime.js +0 -6
- package/lib/states/test/mockEphemeralRuntime.js.map +0 -1
- package/lib/states/test/notificationsManager.spec.js +0 -456
- package/lib/states/test/notificationsManager.spec.js.map +0 -1
- package/lib/states/test/presenceStates.spec.js +0 -69
- package/lib/states/test/presenceStates.spec.js.map +0 -1
- package/lib/states/test/schemaValidation/protocol.spec.js +0 -244
- package/lib/states/test/schemaValidation/protocol.spec.js.map +0 -1
- package/lib/states/test/schemaValidation/valueManagers.spec.js +0 -782
- package/lib/states/test/schemaValidation/valueManagers.spec.js.map +0 -1
- package/lib/states/test/testUtils.js +0 -6
- package/lib/states/test/testUtils.js.map +0 -1
- package/lib/test/mockEphemeralRuntime.js +0 -171
- package/lib/test/mockEphemeralRuntime.js.map +0 -1
- package/lib/test/testUtils.js +0 -251
- package/lib/test/testUtils.js.map +0 -1
- package/lib/test/utils/index.js +0 -8
- package/lib/test/utils/index.js.map +0 -1
- package/lib/utils/test/timerManager.spec.js +0 -91
- package/lib/utils/test/timerManager.spec.js.map +0 -1
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*!
|
|
3
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const node_assert_1 = require("node:assert");
|
|
8
|
-
const internal_1 = require("@fluidframework/test-runtime-utils/internal");
|
|
9
|
-
const internal_2 = require("@fluidframework/test-utils/internal");
|
|
10
|
-
const sinon_1 = require("sinon");
|
|
11
|
-
const test_utils_1 = require("@fluid-internal/presence-runtime/internal/test-utils");
|
|
12
|
-
const utils_1 = require("@fluid-internal/presence-runtime/utils");
|
|
13
|
-
const presenceDatastoreManager_js_1 = require("../presenceDatastoreManager.js");
|
|
14
|
-
const presenceManager_js_1 = require("../presenceManager.js");
|
|
15
|
-
const attendee0SystemWorkspaceDatastore = {
|
|
16
|
-
"clientToSessionId": {
|
|
17
|
-
["client0"]: {
|
|
18
|
-
"rev": 0,
|
|
19
|
-
"timestamp": 0,
|
|
20
|
-
"value": (0, test_utils_1.createSpecificAttendeeId)("attendeeId-0"),
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
const attendee4SystemWorkspaceDatastore = {
|
|
25
|
-
"clientToSessionId": {
|
|
26
|
-
["client4"]: {
|
|
27
|
-
"rev": 0,
|
|
28
|
-
"timestamp": 700,
|
|
29
|
-
"value": (0, test_utils_1.createSpecificAttendeeId)("attendeeId-4"),
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
const attendee5SystemWorkspaceDatastore = {
|
|
34
|
-
"clientToSessionId": {
|
|
35
|
-
["client5"]: {
|
|
36
|
-
"rev": 0,
|
|
37
|
-
"timestamp": 800,
|
|
38
|
-
"value": (0, test_utils_1.createSpecificAttendeeId)("attendeeId-5"),
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
describe("Presence/Runtime", () => {
|
|
43
|
-
describe("protocol handling", () => {
|
|
44
|
-
let runtime;
|
|
45
|
-
let logger;
|
|
46
|
-
const initialTime = 1000;
|
|
47
|
-
let clock;
|
|
48
|
-
before(async () => {
|
|
49
|
-
clock = (0, sinon_1.useFakeTimers)();
|
|
50
|
-
});
|
|
51
|
-
beforeEach(() => {
|
|
52
|
-
logger = new internal_2.EventAndErrorTrackingLogger();
|
|
53
|
-
runtime = new test_utils_1.MockEphemeralRuntime(logger);
|
|
54
|
-
clock.setSystemTime(initialTime);
|
|
55
|
-
});
|
|
56
|
-
afterEach(function (done) {
|
|
57
|
-
clock.reset();
|
|
58
|
-
// If the test passed so far, check final expectations.
|
|
59
|
-
if (this.currentTest?.state === "passed") {
|
|
60
|
-
(0, test_utils_1.assertFinalExpectations)(runtime, logger);
|
|
61
|
-
}
|
|
62
|
-
done();
|
|
63
|
-
});
|
|
64
|
-
after(() => {
|
|
65
|
-
clock.restore();
|
|
66
|
-
});
|
|
67
|
-
it("does not signal when disconnected during initialization", () => {
|
|
68
|
-
// Act & Verify
|
|
69
|
-
(0, presenceManager_js_1.createPresenceManager)(runtime);
|
|
70
|
-
});
|
|
71
|
-
it("sends join when connected during initialization", () => {
|
|
72
|
-
// Setup, Act (call to createPresenceManager), & Verify (post createPresenceManager call)
|
|
73
|
-
(0, test_utils_1.prepareConnectedPresence)(runtime, test_utils_1.localAttendeeId, test_utils_1.initialLocalClientConnectionId, clock, logger);
|
|
74
|
-
});
|
|
75
|
-
describe("handles ClientJoin", () => {
|
|
76
|
-
let processSignal;
|
|
77
|
-
beforeEach(() => {
|
|
78
|
-
({ processSignal } = (0, test_utils_1.prepareConnectedPresence)(runtime, test_utils_1.localAttendeeId, test_utils_1.initialLocalClientConnectionId, clock, logger));
|
|
79
|
-
// Pass a little time (to mimic reality)
|
|
80
|
-
clock.tick(10);
|
|
81
|
-
});
|
|
82
|
-
function joinClients(updateProviders, delayToJoinClient5) {
|
|
83
|
-
// Join client4
|
|
84
|
-
processSignal([], {
|
|
85
|
-
type: "Pres:ClientJoin",
|
|
86
|
-
content: {
|
|
87
|
-
sendTimestamp: clock.now - 50,
|
|
88
|
-
avgLatency: 50,
|
|
89
|
-
data: {
|
|
90
|
-
"system:presence": attendee4SystemWorkspaceDatastore,
|
|
91
|
-
},
|
|
92
|
-
updateProviders,
|
|
93
|
-
},
|
|
94
|
-
clientId: "client4",
|
|
95
|
-
}, false);
|
|
96
|
-
if (delayToJoinClient5 !== undefined) {
|
|
97
|
-
// Advance clock to delay joining client5
|
|
98
|
-
clock.tick(delayToJoinClient5);
|
|
99
|
-
// Join client5
|
|
100
|
-
processSignal([], {
|
|
101
|
-
type: "Pres:ClientJoin",
|
|
102
|
-
content: {
|
|
103
|
-
sendTimestamp: clock.now - 50,
|
|
104
|
-
avgLatency: 50,
|
|
105
|
-
data: {
|
|
106
|
-
"system:presence": attendee5SystemWorkspaceDatastore,
|
|
107
|
-
},
|
|
108
|
-
updateProviders,
|
|
109
|
-
},
|
|
110
|
-
clientId: "client5",
|
|
111
|
-
}, false);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function processClient0ResponseForClient4() {
|
|
115
|
-
// Setup
|
|
116
|
-
// client 0 handles client 4 join
|
|
117
|
-
processSignal([], {
|
|
118
|
-
type: "Pres:DatastoreUpdate",
|
|
119
|
-
content: {
|
|
120
|
-
"avgLatency": 10,
|
|
121
|
-
"data": {
|
|
122
|
-
"system:presence": {
|
|
123
|
-
"clientToSessionId": {
|
|
124
|
-
...attendee0SystemWorkspaceDatastore.clientToSessionId,
|
|
125
|
-
...attendee4SystemWorkspaceDatastore.clientToSessionId,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
"isComplete": true,
|
|
130
|
-
"joinResponseFor": ["client4"],
|
|
131
|
-
"sendTimestamp": clock.now - 10,
|
|
132
|
-
},
|
|
133
|
-
clientId: "client0",
|
|
134
|
-
}, false);
|
|
135
|
-
}
|
|
136
|
-
it(`when preferred responder ... with broadcast after ${presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.namedResponder}ms`, () => {
|
|
137
|
-
// Setup
|
|
138
|
-
const updateTime = clock.now + presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.namedResponder;
|
|
139
|
-
// #region Part 1 (no response)
|
|
140
|
-
// Act
|
|
141
|
-
// join clients 4 and 5
|
|
142
|
-
joinClients([test_utils_1.initialLocalClientConnectionId], presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.namedResponder / 2);
|
|
143
|
-
// Advance to one tick before expected response time
|
|
144
|
-
clock.tick(updateTime - 1 - clock.now);
|
|
145
|
-
// #endregion
|
|
146
|
-
// #region Part 2 (response after delay)
|
|
147
|
-
// Setup
|
|
148
|
-
logger.registerExpectedEvent({
|
|
149
|
-
eventName: "Presence:JoinResponse",
|
|
150
|
-
details: JSON.stringify({
|
|
151
|
-
type: "broadcastAll",
|
|
152
|
-
attendeeId: test_utils_1.localAttendeeId,
|
|
153
|
-
connectionId: test_utils_1.initialLocalClientConnectionId,
|
|
154
|
-
primaryResponses: JSON.stringify(["client4", "client5"]),
|
|
155
|
-
secondaryResponses: JSON.stringify([]),
|
|
156
|
-
}),
|
|
157
|
-
});
|
|
158
|
-
runtime.signalsExpected.push([
|
|
159
|
-
{
|
|
160
|
-
type: "Pres:DatastoreUpdate",
|
|
161
|
-
content: {
|
|
162
|
-
"avgLatency": 10,
|
|
163
|
-
"data": {
|
|
164
|
-
"system:presence": {
|
|
165
|
-
"clientToSessionId": {
|
|
166
|
-
...attendee4SystemWorkspaceDatastore.clientToSessionId,
|
|
167
|
-
...attendee5SystemWorkspaceDatastore.clientToSessionId,
|
|
168
|
-
[test_utils_1.initialLocalClientConnectionId]: {
|
|
169
|
-
"rev": 0,
|
|
170
|
-
"timestamp": initialTime,
|
|
171
|
-
"value": test_utils_1.localAttendeeId,
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
"isComplete": true,
|
|
177
|
-
"joinResponseFor": ["client4", "client5"],
|
|
178
|
-
"sendTimestamp": clock.now + 1,
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
]);
|
|
182
|
-
// Act
|
|
183
|
-
clock.tick(1);
|
|
184
|
-
// Verify
|
|
185
|
-
(0, test_utils_1.assertFinalExpectations)(runtime, logger);
|
|
186
|
-
// #endregion
|
|
187
|
-
});
|
|
188
|
-
describe("when NOT preferred responder", () => {
|
|
189
|
-
it("and no other responses ... with broadcast after delay", () => {
|
|
190
|
-
// Setup
|
|
191
|
-
const responseOrder = 2;
|
|
192
|
-
// 3 * named length (client0 and client1) + quorum sequence order (third -> 2)
|
|
193
|
-
const responderIndex = 3 * 2 + responseOrder;
|
|
194
|
-
const updateTime = clock.now +
|
|
195
|
-
presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.namedResponder +
|
|
196
|
-
presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.backupResponderIncrement * responderIndex;
|
|
197
|
-
// #region Part 1 (no response)
|
|
198
|
-
// Act
|
|
199
|
-
// join client 4
|
|
200
|
-
joinClients(["client0", "client1"], undefined);
|
|
201
|
-
clock.tick(updateTime - clock.now - 1);
|
|
202
|
-
// #endregion
|
|
203
|
-
// #region Part 2 (response after delay)
|
|
204
|
-
// Setup
|
|
205
|
-
logger.registerExpectedEvent({
|
|
206
|
-
eventName: "Presence:JoinResponse",
|
|
207
|
-
details: JSON.stringify({
|
|
208
|
-
type: "broadcastAll",
|
|
209
|
-
attendeeId: test_utils_1.localAttendeeId,
|
|
210
|
-
connectionId: test_utils_1.initialLocalClientConnectionId,
|
|
211
|
-
primaryResponses: JSON.stringify([]),
|
|
212
|
-
secondaryResponses: JSON.stringify([["client4", responseOrder]]),
|
|
213
|
-
}),
|
|
214
|
-
});
|
|
215
|
-
runtime.signalsExpected.push([
|
|
216
|
-
{
|
|
217
|
-
type: "Pres:DatastoreUpdate",
|
|
218
|
-
content: {
|
|
219
|
-
"avgLatency": 10,
|
|
220
|
-
"data": {
|
|
221
|
-
"system:presence": {
|
|
222
|
-
"clientToSessionId": {
|
|
223
|
-
...attendee4SystemWorkspaceDatastore.clientToSessionId,
|
|
224
|
-
[test_utils_1.initialLocalClientConnectionId]: {
|
|
225
|
-
"rev": 0,
|
|
226
|
-
"timestamp": initialTime,
|
|
227
|
-
"value": test_utils_1.localAttendeeId,
|
|
228
|
-
},
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
"isComplete": true,
|
|
233
|
-
"joinResponseFor": ["client4"],
|
|
234
|
-
"sendTimestamp": clock.now + 1,
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
]);
|
|
238
|
-
// Act
|
|
239
|
-
clock.tick(1);
|
|
240
|
-
// Verify
|
|
241
|
-
(0, test_utils_1.assertFinalExpectations)(runtime, logger);
|
|
242
|
-
// #endregion
|
|
243
|
-
});
|
|
244
|
-
it("and other has fully responded ... without broadcast", () => {
|
|
245
|
-
// Setup
|
|
246
|
-
// join client 4
|
|
247
|
-
joinClients(["client0", "client1"], undefined);
|
|
248
|
-
clock.tick(presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.namedResponder);
|
|
249
|
-
// Act
|
|
250
|
-
// client 0 handles client 4 join
|
|
251
|
-
processClient0ResponseForClient4();
|
|
252
|
-
clock.runAll();
|
|
253
|
-
// Verify
|
|
254
|
-
(0, test_utils_1.assertFinalExpectations)(runtime, logger);
|
|
255
|
-
});
|
|
256
|
-
it("and other has partially responded ... with broadcast after delay", () => {
|
|
257
|
-
// Setup
|
|
258
|
-
const responseOrder = 2;
|
|
259
|
-
// 3 * named length (client0 and client1) + quorum sequence order (third -> 2)
|
|
260
|
-
const responderIndex = 3 * 2 + responseOrder;
|
|
261
|
-
const client4ResponseDelay = presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.namedResponder +
|
|
262
|
-
presenceDatastoreManager_js_1.broadcastJoinResponseDelaysMs.backupResponderIncrement * responderIndex;
|
|
263
|
-
const client4UpdateTime = clock.now + client4ResponseDelay;
|
|
264
|
-
const delayToJoinClient5 = client4ResponseDelay / 2;
|
|
265
|
-
const client5UpdateTime = client4UpdateTime + delayToJoinClient5;
|
|
266
|
-
// join clients 4 and 5
|
|
267
|
-
joinClients(["client0", "client1"], delayToJoinClient5);
|
|
268
|
-
clock.tick(client4UpdateTime - clock.now - 1);
|
|
269
|
-
// client 0 handles client 4 join
|
|
270
|
-
processClient0ResponseForClient4();
|
|
271
|
-
clock.tick(client5UpdateTime - clock.now - 1);
|
|
272
|
-
logger.registerExpectedEvent({
|
|
273
|
-
eventName: "Presence:JoinResponse",
|
|
274
|
-
details: JSON.stringify({
|
|
275
|
-
type: "broadcastAll",
|
|
276
|
-
attendeeId: test_utils_1.localAttendeeId,
|
|
277
|
-
connectionId: test_utils_1.initialLocalClientConnectionId,
|
|
278
|
-
primaryResponses: JSON.stringify([]),
|
|
279
|
-
secondaryResponses: JSON.stringify([["client5", responseOrder]]),
|
|
280
|
-
}),
|
|
281
|
-
});
|
|
282
|
-
runtime.signalsExpected.push([
|
|
283
|
-
{
|
|
284
|
-
type: "Pres:DatastoreUpdate",
|
|
285
|
-
content: {
|
|
286
|
-
"avgLatency": 10,
|
|
287
|
-
"data": {
|
|
288
|
-
"system:presence": {
|
|
289
|
-
"clientToSessionId": {
|
|
290
|
-
...attendee0SystemWorkspaceDatastore.clientToSessionId,
|
|
291
|
-
...attendee4SystemWorkspaceDatastore.clientToSessionId,
|
|
292
|
-
...attendee5SystemWorkspaceDatastore.clientToSessionId,
|
|
293
|
-
[test_utils_1.initialLocalClientConnectionId]: {
|
|
294
|
-
"rev": 0,
|
|
295
|
-
"timestamp": initialTime,
|
|
296
|
-
"value": test_utils_1.localAttendeeId,
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
},
|
|
300
|
-
},
|
|
301
|
-
"isComplete": true,
|
|
302
|
-
// Only responding for client5 (client4 has been handled)
|
|
303
|
-
"joinResponseFor": ["client5"],
|
|
304
|
-
"sendTimestamp": clock.now + 1,
|
|
305
|
-
},
|
|
306
|
-
},
|
|
307
|
-
]);
|
|
308
|
-
// Act
|
|
309
|
-
clock.tick(1);
|
|
310
|
-
// Verify
|
|
311
|
-
(0, test_utils_1.assertFinalExpectations)(runtime, logger);
|
|
312
|
-
// #endregion
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
describe("receiving DatastoreUpdate", () => {
|
|
317
|
-
let presence;
|
|
318
|
-
let processSignal;
|
|
319
|
-
const systemWorkspaceUpdate = {
|
|
320
|
-
"clientToSessionId": {
|
|
321
|
-
"client1": {
|
|
322
|
-
"rev": 0,
|
|
323
|
-
"timestamp": 0,
|
|
324
|
-
"value": test_utils_1.attendeeId1,
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
};
|
|
328
|
-
const statesWorkspaceUpdate = {
|
|
329
|
-
"latest": {
|
|
330
|
-
[test_utils_1.attendeeId1]: {
|
|
331
|
-
"rev": 1,
|
|
332
|
-
"timestamp": 0,
|
|
333
|
-
"value": (0, utils_1.toOpaqueJson)({}),
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
};
|
|
337
|
-
const notificationsWorkspaceUpdate = {
|
|
338
|
-
"testEvents": {
|
|
339
|
-
[test_utils_1.attendeeId1]: {
|
|
340
|
-
"rev": 0,
|
|
341
|
-
"timestamp": 0,
|
|
342
|
-
"value": (0, utils_1.toOpaqueJson)({}),
|
|
343
|
-
"ignoreUnmonitored": true,
|
|
344
|
-
},
|
|
345
|
-
},
|
|
346
|
-
};
|
|
347
|
-
beforeEach(() => {
|
|
348
|
-
({ presence, processSignal } = (0, test_utils_1.prepareConnectedPresence)(runtime, test_utils_1.localAttendeeId, test_utils_1.initialLocalClientConnectionId, clock, logger));
|
|
349
|
-
// Pass a little time (to mimic reality)
|
|
350
|
-
clock.tick(10);
|
|
351
|
-
});
|
|
352
|
-
it("with unregistered States workspace emits 'workspaceActivated'", () => {
|
|
353
|
-
// Setup
|
|
354
|
-
const listener = (0, sinon_1.spy)();
|
|
355
|
-
presence.events.on("workspaceActivated", listener);
|
|
356
|
-
// Act
|
|
357
|
-
processSignal([], {
|
|
358
|
-
type: "Pres:DatastoreUpdate",
|
|
359
|
-
content: {
|
|
360
|
-
sendTimestamp: clock.now - 10,
|
|
361
|
-
avgLatency: 20,
|
|
362
|
-
data: {
|
|
363
|
-
"system:presence": systemWorkspaceUpdate,
|
|
364
|
-
"s:name:testStateWorkspace": statesWorkspaceUpdate,
|
|
365
|
-
},
|
|
366
|
-
},
|
|
367
|
-
clientId: "client1",
|
|
368
|
-
}, false);
|
|
369
|
-
// Verify
|
|
370
|
-
node_assert_1.strict.strictEqual(listener.calledOnce, true);
|
|
371
|
-
node_assert_1.strict.strictEqual(listener.calledWith("name:testStateWorkspace", "States"), true);
|
|
372
|
-
});
|
|
373
|
-
it("with unregistered Notifications workspace 'workspaceActivated'", () => {
|
|
374
|
-
// Setup
|
|
375
|
-
const listener = (0, sinon_1.spy)();
|
|
376
|
-
presence.events.on("workspaceActivated", listener);
|
|
377
|
-
// Act
|
|
378
|
-
processSignal([], {
|
|
379
|
-
type: "Pres:DatastoreUpdate",
|
|
380
|
-
content: {
|
|
381
|
-
sendTimestamp: clock.now - 10,
|
|
382
|
-
avgLatency: 20,
|
|
383
|
-
data: {
|
|
384
|
-
"system:presence": systemWorkspaceUpdate,
|
|
385
|
-
"n:name:testNotificationWorkspace": notificationsWorkspaceUpdate,
|
|
386
|
-
},
|
|
387
|
-
},
|
|
388
|
-
clientId: "client1",
|
|
389
|
-
}, false);
|
|
390
|
-
// Verify
|
|
391
|
-
node_assert_1.strict.strictEqual(listener.calledOnce, true);
|
|
392
|
-
node_assert_1.strict.strictEqual(listener.calledWith("name:testNotificationWorkspace", "Notifications"), true);
|
|
393
|
-
});
|
|
394
|
-
it("with unregistered workspace of unknown type emits 'workspaceActivated'", () => {
|
|
395
|
-
// Setup
|
|
396
|
-
const listener = (0, sinon_1.spy)();
|
|
397
|
-
presence.events.on("workspaceActivated", listener);
|
|
398
|
-
// Act
|
|
399
|
-
processSignal([], {
|
|
400
|
-
type: "Pres:DatastoreUpdate",
|
|
401
|
-
content: {
|
|
402
|
-
sendTimestamp: clock.now - 10,
|
|
403
|
-
avgLatency: 20,
|
|
404
|
-
data: {
|
|
405
|
-
"system:presence": systemWorkspaceUpdate,
|
|
406
|
-
["u:name:testUnknownWorkspace"]: {
|
|
407
|
-
"latest": {
|
|
408
|
-
[test_utils_1.attendeeId1]: {
|
|
409
|
-
"rev": 1,
|
|
410
|
-
"timestamp": 0,
|
|
411
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 1, y: 1, z: 1 }),
|
|
412
|
-
},
|
|
413
|
-
},
|
|
414
|
-
},
|
|
415
|
-
},
|
|
416
|
-
},
|
|
417
|
-
clientId: "client1",
|
|
418
|
-
}, false);
|
|
419
|
-
// Verify
|
|
420
|
-
node_assert_1.strict.strictEqual(listener.calledOnce, true);
|
|
421
|
-
node_assert_1.strict.strictEqual(listener.calledWith("name:testUnknownWorkspace", "Unknown"), true);
|
|
422
|
-
});
|
|
423
|
-
it("with registered workspace does NOT emit 'workspaceActivated'", () => {
|
|
424
|
-
// Setup
|
|
425
|
-
const listener = (0, sinon_1.spy)();
|
|
426
|
-
presence.events.on("workspaceActivated", listener);
|
|
427
|
-
presence.states.getWorkspace("name:testStateWorkspace", {});
|
|
428
|
-
presence.notifications.getWorkspace("name:testNotificationWorkspace", {});
|
|
429
|
-
// Act
|
|
430
|
-
processSignal([], {
|
|
431
|
-
type: "Pres:DatastoreUpdate",
|
|
432
|
-
content: {
|
|
433
|
-
sendTimestamp: clock.now - 10,
|
|
434
|
-
avgLatency: 20,
|
|
435
|
-
data: {
|
|
436
|
-
"system:presence": systemWorkspaceUpdate,
|
|
437
|
-
"s:name:testStateWorkspace": statesWorkspaceUpdate,
|
|
438
|
-
"n:name:testNotificationWorkspace": notificationsWorkspaceUpdate,
|
|
439
|
-
},
|
|
440
|
-
},
|
|
441
|
-
clientId: "client1",
|
|
442
|
-
}, false);
|
|
443
|
-
// Verify
|
|
444
|
-
node_assert_1.strict.strictEqual(listener.called, false);
|
|
445
|
-
});
|
|
446
|
-
it("with workspace that has an unrecognized internal address does NOT emit 'workspaceActivated'", () => {
|
|
447
|
-
// Setup
|
|
448
|
-
const listener = (0, sinon_1.spy)();
|
|
449
|
-
presence.events.on("workspaceActivated", listener);
|
|
450
|
-
// Act
|
|
451
|
-
processSignal([], {
|
|
452
|
-
type: "Pres:DatastoreUpdate",
|
|
453
|
-
content: {
|
|
454
|
-
sendTimestamp: clock.now - 10,
|
|
455
|
-
avgLatency: 20,
|
|
456
|
-
data: {
|
|
457
|
-
"system:presence": systemWorkspaceUpdate,
|
|
458
|
-
// Unrecognized internal address
|
|
459
|
-
["sn:name:testStateWorkspace"]: statesWorkspaceUpdate,
|
|
460
|
-
},
|
|
461
|
-
},
|
|
462
|
-
clientId: "client1",
|
|
463
|
-
}, false);
|
|
464
|
-
// Verify
|
|
465
|
-
node_assert_1.strict.strictEqual(listener.called, false);
|
|
466
|
-
});
|
|
467
|
-
it("with workspace that has an invalid public address does NOT emit 'workspaceActivated'", () => {
|
|
468
|
-
// Setup
|
|
469
|
-
const listener = (0, sinon_1.spy)();
|
|
470
|
-
presence.events.on("workspaceActivated", listener);
|
|
471
|
-
// Act
|
|
472
|
-
processSignal([], {
|
|
473
|
-
type: "Pres:DatastoreUpdate",
|
|
474
|
-
content: {
|
|
475
|
-
sendTimestamp: clock.now - 10,
|
|
476
|
-
avgLatency: 20,
|
|
477
|
-
data: {
|
|
478
|
-
"system:presence": systemWorkspaceUpdate,
|
|
479
|
-
// Invalid public address (must be `${string}:${string}`)
|
|
480
|
-
["s:testStateWorkspace"]: statesWorkspaceUpdate,
|
|
481
|
-
},
|
|
482
|
-
},
|
|
483
|
-
clientId: "client1",
|
|
484
|
-
}, false);
|
|
485
|
-
// Verify
|
|
486
|
-
node_assert_1.strict.strictEqual(listener.called, false);
|
|
487
|
-
});
|
|
488
|
-
it("with workspace that has already been seen does NOT emit 'workspaceActivated'", () => {
|
|
489
|
-
// Setup
|
|
490
|
-
const listener = (0, sinon_1.spy)();
|
|
491
|
-
presence.events.on("workspaceActivated", listener);
|
|
492
|
-
// Act
|
|
493
|
-
processSignal([], {
|
|
494
|
-
type: "Pres:DatastoreUpdate",
|
|
495
|
-
content: {
|
|
496
|
-
sendTimestamp: clock.now - 20,
|
|
497
|
-
avgLatency: 20,
|
|
498
|
-
data: {
|
|
499
|
-
"system:presence": systemWorkspaceUpdate,
|
|
500
|
-
"s:name:testStateWorkspace": statesWorkspaceUpdate,
|
|
501
|
-
},
|
|
502
|
-
},
|
|
503
|
-
clientId: "client1",
|
|
504
|
-
}, false);
|
|
505
|
-
processSignal([], {
|
|
506
|
-
type: "Pres:DatastoreUpdate",
|
|
507
|
-
content: {
|
|
508
|
-
sendTimestamp: clock.now - 10,
|
|
509
|
-
avgLatency: 20,
|
|
510
|
-
data: {
|
|
511
|
-
"system:presence": systemWorkspaceUpdate,
|
|
512
|
-
"s:name:testStateWorkspace": statesWorkspaceUpdate,
|
|
513
|
-
},
|
|
514
|
-
},
|
|
515
|
-
clientId: "client1",
|
|
516
|
-
}, false);
|
|
517
|
-
// Verify
|
|
518
|
-
node_assert_1.strict.strictEqual(listener.callCount, 1);
|
|
519
|
-
});
|
|
520
|
-
it("with acknowledgementId sends targeted acknowledgment message back to requestor", () => {
|
|
521
|
-
// We expect to send a targeted acknowledgment back to the requestor
|
|
522
|
-
runtime.signalsExpected.push([
|
|
523
|
-
{
|
|
524
|
-
type: "Pres:Ack",
|
|
525
|
-
content: { id: "ackID" },
|
|
526
|
-
targetClientId: "client4",
|
|
527
|
-
},
|
|
528
|
-
]);
|
|
529
|
-
// Act - send generic datastore update with acknowledgement id specified
|
|
530
|
-
processSignal([], {
|
|
531
|
-
type: "Pres:DatastoreUpdate",
|
|
532
|
-
content: {
|
|
533
|
-
sendTimestamp: clock.now - 10,
|
|
534
|
-
avgLatency: 20,
|
|
535
|
-
data: {
|
|
536
|
-
"system:presence": systemWorkspaceUpdate,
|
|
537
|
-
"s:name:testStateWorkspace": statesWorkspaceUpdate,
|
|
538
|
-
},
|
|
539
|
-
acknowledgementId: "ackID",
|
|
540
|
-
},
|
|
541
|
-
clientId: "client4",
|
|
542
|
-
}, false);
|
|
543
|
-
// Verify
|
|
544
|
-
(0, test_utils_1.assertFinalExpectations)(runtime, logger);
|
|
545
|
-
});
|
|
546
|
-
});
|
|
547
|
-
describe("receiving unrecognized message", () => {
|
|
548
|
-
let presence;
|
|
549
|
-
let processSignal;
|
|
550
|
-
const systemWorkspaceUpdate = {
|
|
551
|
-
"clientToSessionId": {
|
|
552
|
-
"client1": {
|
|
553
|
-
"rev": 0,
|
|
554
|
-
"timestamp": 0,
|
|
555
|
-
"value": test_utils_1.attendeeId1,
|
|
556
|
-
},
|
|
557
|
-
},
|
|
558
|
-
};
|
|
559
|
-
const statesWorkspaceUpdate = {
|
|
560
|
-
"latest": {
|
|
561
|
-
[test_utils_1.attendeeId1]: {
|
|
562
|
-
"rev": 1,
|
|
563
|
-
"timestamp": 0,
|
|
564
|
-
"value": (0, utils_1.toOpaqueJson)({}),
|
|
565
|
-
},
|
|
566
|
-
},
|
|
567
|
-
};
|
|
568
|
-
beforeEach(() => {
|
|
569
|
-
({ presence, processSignal } = (0, test_utils_1.prepareConnectedPresence)(runtime, test_utils_1.localAttendeeId, test_utils_1.initialLocalClientConnectionId, clock, logger));
|
|
570
|
-
// Pass a little time (to mimic reality)
|
|
571
|
-
clock.tick(10);
|
|
572
|
-
});
|
|
573
|
-
/**
|
|
574
|
-
* Use to pretend any general inbound message is an unverified Presence message
|
|
575
|
-
*/
|
|
576
|
-
function markUnverifiedIncomingMessage(
|
|
577
|
-
// make sure message "was" at least serializable
|
|
578
|
-
message) {
|
|
579
|
-
return message;
|
|
580
|
-
}
|
|
581
|
-
function processUnrecognizedMessage({ optional }) {
|
|
582
|
-
// Mocked to look very much like a Presence message, but with an unrecognized type.
|
|
583
|
-
const unrecognizedMessage = {
|
|
584
|
-
type: "Pres: Unrecognized Message",
|
|
585
|
-
content: {
|
|
586
|
-
sendTimestamp: clock.now - 10,
|
|
587
|
-
avgLatency: 20,
|
|
588
|
-
data: {
|
|
589
|
-
"system:presence": systemWorkspaceUpdate,
|
|
590
|
-
"s:name:testStateWorkspace": statesWorkspaceUpdate,
|
|
591
|
-
},
|
|
592
|
-
},
|
|
593
|
-
clientId: "client1",
|
|
594
|
-
};
|
|
595
|
-
processSignal(optional ? ["?"] : [], markUnverifiedIncomingMessage(unrecognizedMessage), false);
|
|
596
|
-
}
|
|
597
|
-
it("that is NOT optional, throws", () => {
|
|
598
|
-
// Setup
|
|
599
|
-
const listener = (0, sinon_1.spy)();
|
|
600
|
-
presence.events.on("workspaceActivated", listener);
|
|
601
|
-
// Act & Verify
|
|
602
|
-
node_assert_1.strict.throws(() => processUnrecognizedMessage({ optional: false }), (0, internal_1.validateAssertionError)("0xcbc"));
|
|
603
|
-
// Verify
|
|
604
|
-
node_assert_1.strict.strictEqual(listener.called, false);
|
|
605
|
-
});
|
|
606
|
-
it("that is optional, ignores message and does NOT throw", () => {
|
|
607
|
-
// Setup
|
|
608
|
-
const listener = (0, sinon_1.spy)();
|
|
609
|
-
presence.events.on("workspaceActivated", listener);
|
|
610
|
-
// Act & Verify
|
|
611
|
-
processUnrecognizedMessage({ optional: true });
|
|
612
|
-
// Verify
|
|
613
|
-
node_assert_1.strict.strictEqual(listener.called, false);
|
|
614
|
-
});
|
|
615
|
-
});
|
|
616
|
-
});
|
|
617
|
-
});
|
|
618
|
-
//# sourceMappingURL=presenceDatastoreManager.spec.js.map
|