@webex/internal-plugin-board 3.0.0-beta.8 → 3.0.0-bnr.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/README.md +1 -3
- package/dist/board.js +28 -108
- package/dist/board.js.map +1 -1
- package/dist/config.js +0 -8
- package/dist/config.js.map +1 -1
- package/dist/index.js +7 -28
- package/dist/index.js.map +1 -1
- package/dist/realtime-channel-collection.js +2 -8
- package/dist/realtime-channel-collection.js.map +1 -1
- package/dist/realtime-channel.js +1 -5
- package/dist/realtime-channel.js.map +1 -1
- package/dist/realtime.js +38 -82
- package/dist/realtime.js.map +1 -1
- package/dist/types/board.d.ts +2 -0
- package/dist/types/config.d.ts +11 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/realtime-channel-collection.d.ts +2 -0
- package/dist/types/realtime-channel.d.ts +2 -0
- package/dist/types/realtime.d.ts +7 -0
- package/package.json +14 -14
- package/src/board.js +257 -205
- package/src/config.js +2 -2
- package/src/index.js +19 -21
- package/src/realtime-channel-collection.js +2 -2
- package/src/realtime-channel.js +8 -9
- package/src/realtime.js +109 -93
- package/test/integration/spec/board.js +347 -221
- package/test/integration/spec/realtime.js +82 -56
- package/test/integration/spec/sharing-mercury.js +154 -73
- package/test/unit/spec/board.js +301 -215
- package/test/unit/spec/encryption.js +152 -120
- package/test/unit/spec/realtime.js +131 -89
|
@@ -27,34 +27,35 @@ describe('plugin-board', () => {
|
|
|
27
27
|
const mockWebSocket = new MockWebSocket();
|
|
28
28
|
const channel = {
|
|
29
29
|
channelId: '1234-channel-id',
|
|
30
|
-
defaultEncryptionKeyUrl: fakeURL
|
|
30
|
+
defaultEncryptionKeyUrl: fakeURL,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
beforeEach(() => {
|
|
34
34
|
webex = new MockWebex({
|
|
35
35
|
children: {
|
|
36
36
|
board: Board,
|
|
37
|
-
mercury: Mercury
|
|
37
|
+
mercury: Mercury,
|
|
38
38
|
},
|
|
39
39
|
config: {
|
|
40
|
-
board: config.board
|
|
41
|
-
}
|
|
40
|
+
board: config.board,
|
|
41
|
+
},
|
|
42
42
|
});
|
|
43
43
|
Object.assign(webex.internal, {
|
|
44
44
|
encryption: {
|
|
45
|
-
encryptText: sinon.stub().returns(Promise.resolve(encryptedData))
|
|
45
|
+
encryptText: sinon.stub().returns(Promise.resolve(encryptedData)),
|
|
46
46
|
},
|
|
47
47
|
metrics: {
|
|
48
|
-
submitClientMetrics: sinon.stub()
|
|
49
|
-
}
|
|
48
|
+
submitClientMetrics: sinon.stub(),
|
|
49
|
+
},
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
registrationRes = {
|
|
53
53
|
id: '14d6abda-16de-4e02-bf7c-6d2a0e77ec38',
|
|
54
54
|
url: 'https://mercury-api-a.wbx2.com/v1/apps/wx2/registrations/14d6abda-16de-4e02-bf7c-6d2a0e77ec38',
|
|
55
55
|
bindings: ['board.0609e520.a21a.11e6.912e.e9562ab65926'],
|
|
56
|
-
webSocketUrl:
|
|
57
|
-
|
|
56
|
+
webSocketUrl:
|
|
57
|
+
'wss://mercury-connection-a.wbx2.com/v1/apps/wx2/registrations/14d6abda-16de-4e02-bf7c-6d2a0e77ec38/messages',
|
|
58
|
+
messageTtl: 900000,
|
|
58
59
|
};
|
|
59
60
|
|
|
60
61
|
sinon.stub(Socket, 'getWebSocketConstructor').returns(() => mockWebSocket);
|
|
@@ -63,7 +64,7 @@ describe('plugin-board', () => {
|
|
|
63
64
|
mockRealtimeChannel = new RealtimeChannel({
|
|
64
65
|
socketUrl: registrationRes.webSocketUrl,
|
|
65
66
|
binding: registrationRes.bindings[0],
|
|
66
|
-
channelId: channel.channelId
|
|
67
|
+
channelId: channel.channelId,
|
|
67
68
|
});
|
|
68
69
|
|
|
69
70
|
mockRealtimeChannel.socket = mockWebSocket;
|
|
@@ -79,7 +80,9 @@ describe('plugin-board', () => {
|
|
|
79
80
|
return promise;
|
|
80
81
|
});
|
|
81
82
|
|
|
82
|
-
sinon
|
|
83
|
+
sinon
|
|
84
|
+
.stub(webex.internal.board.realtime.realtimeChannels, 'get')
|
|
85
|
+
.returns(mockRealtimeChannel);
|
|
83
86
|
sinon.stub(webex.internal.board.realtime.realtimeChannels, 'add');
|
|
84
87
|
sinon.stub(webex.internal.board.realtime.realtimeChannels, 'remove');
|
|
85
88
|
|
|
@@ -104,10 +107,9 @@ describe('plugin-board', () => {
|
|
|
104
107
|
describe('#publish()', () => {
|
|
105
108
|
const message = {
|
|
106
109
|
payload: {
|
|
107
|
-
data: 'fake'
|
|
110
|
+
data: 'fake',
|
|
108
111
|
},
|
|
109
|
-
envelope: {
|
|
110
|
-
}
|
|
112
|
+
envelope: {},
|
|
111
113
|
};
|
|
112
114
|
|
|
113
115
|
beforeEach(() => {
|
|
@@ -126,20 +128,22 @@ describe('plugin-board', () => {
|
|
|
126
128
|
assert.calledWith(mockRealtimeChannel.socket.send, {
|
|
127
129
|
id: uuid.v4(),
|
|
128
130
|
type: 'publishRequest',
|
|
129
|
-
recipients: [
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
recipients: [
|
|
132
|
+
{
|
|
133
|
+
alertType: 'none',
|
|
134
|
+
route: mockRealtimeChannel.binding,
|
|
135
|
+
headers: {},
|
|
136
|
+
},
|
|
137
|
+
],
|
|
134
138
|
data: {
|
|
135
139
|
eventType: 'board.activity',
|
|
136
140
|
payload: 'encryptedData',
|
|
137
141
|
envelope: {
|
|
138
142
|
encryptionKeyUrl: 'fakeURL',
|
|
139
|
-
channelId: mockRealtimeChannel.channelId
|
|
143
|
+
channelId: mockRealtimeChannel.channelId,
|
|
140
144
|
},
|
|
141
|
-
contentType: 'STRING'
|
|
142
|
-
}
|
|
145
|
+
contentType: 'STRING',
|
|
146
|
+
},
|
|
143
147
|
});
|
|
144
148
|
});
|
|
145
149
|
});
|
|
@@ -148,10 +152,14 @@ describe('plugin-board', () => {
|
|
|
148
152
|
beforeEach(() => {
|
|
149
153
|
sinon.stub(uuid, 'v4').returns('stubbedUUIDv4');
|
|
150
154
|
|
|
151
|
-
return webex.internal.board.realtime.publishEncrypted(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
return webex.internal.board.realtime.publishEncrypted(
|
|
156
|
+
channel,
|
|
157
|
+
{
|
|
158
|
+
encryptedData: 'encryptedData',
|
|
159
|
+
encryptedKeyUrl: 'fakeURL',
|
|
160
|
+
},
|
|
161
|
+
'STRING'
|
|
162
|
+
);
|
|
155
163
|
});
|
|
156
164
|
|
|
157
165
|
afterEach(() => {
|
|
@@ -165,20 +173,22 @@ describe('plugin-board', () => {
|
|
|
165
173
|
assert.calledWith(mockRealtimeChannel.socket.send, {
|
|
166
174
|
id: uuid.v4(),
|
|
167
175
|
type: 'publishRequest',
|
|
168
|
-
recipients: [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
176
|
+
recipients: [
|
|
177
|
+
{
|
|
178
|
+
alertType: 'none',
|
|
179
|
+
headers: {},
|
|
180
|
+
route: mockRealtimeChannel.binding,
|
|
181
|
+
},
|
|
182
|
+
],
|
|
173
183
|
data: {
|
|
174
184
|
contentType: 'STRING',
|
|
175
185
|
eventType: 'board.activity',
|
|
176
186
|
envelope: {
|
|
177
187
|
encryptionKeyUrl: 'fakeURL',
|
|
178
|
-
channelId: channel.channelId
|
|
188
|
+
channelId: channel.channelId,
|
|
179
189
|
},
|
|
180
|
-
payload: 'encryptedData'
|
|
181
|
-
}
|
|
190
|
+
payload: 'encryptedData',
|
|
191
|
+
},
|
|
182
192
|
});
|
|
183
193
|
});
|
|
184
194
|
|
|
@@ -187,36 +197,42 @@ describe('plugin-board', () => {
|
|
|
187
197
|
mockRealtimeChannel.socket.send = sinon.stub().returns(Promise.resolve());
|
|
188
198
|
webex.internal.board.realtime.realtimeChannels.get.returns(null);
|
|
189
199
|
|
|
190
|
-
return assert.isRejected(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
200
|
+
return assert.isRejected(
|
|
201
|
+
webex.internal.board.realtime.publishEncrypted(
|
|
202
|
+
{
|
|
203
|
+
encryptedData: 'encryptedData',
|
|
204
|
+
encryptedKeyUrl: 'fakeURL',
|
|
205
|
+
},
|
|
206
|
+
'STRING'
|
|
207
|
+
)
|
|
208
|
+
);
|
|
194
209
|
});
|
|
195
210
|
});
|
|
196
211
|
|
|
197
212
|
describe('#connectByOpenNewMercuryConnection()', () => {
|
|
198
|
-
it('opens new connections using the provided socket urls', () =>
|
|
199
|
-
.then(() => {
|
|
213
|
+
it('opens new connections using the provided socket urls', () =>
|
|
214
|
+
webex.internal.board.realtime.connectByOpenNewMercuryConnection(channel).then(() => {
|
|
200
215
|
assert.calledWith(webex.internal.board.realtime.realtimeChannels.get, channel.channelId);
|
|
201
216
|
assert.called(mockRealtimeChannel.socket.open);
|
|
202
217
|
}));
|
|
203
218
|
|
|
204
219
|
it('creates new channel if realtime channel not found', () => {
|
|
205
220
|
webex.internal.board.realtime.realtimeChannels.get
|
|
206
|
-
.onFirstCall()
|
|
207
|
-
.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
assert.calledWith(webex.internal.board.realtime.realtimeChannels.get, channel.channelId);
|
|
218
|
-
assert.called(mockRealtimeChannel.socket.open);
|
|
221
|
+
.onFirstCall()
|
|
222
|
+
.returns(null)
|
|
223
|
+
.onSecondCall()
|
|
224
|
+
.returns(mockRealtimeChannel);
|
|
225
|
+
|
|
226
|
+
return webex.internal.board.realtime.connectByOpenNewMercuryConnection(channel).then(() => {
|
|
227
|
+
assert.calledWith(webex.internal.board.realtime.realtimeChannels.add, {
|
|
228
|
+
channelId: channel.channelId,
|
|
229
|
+
socketUrl: registrationRes.webSocketUrl,
|
|
230
|
+
binding: registrationRes.bindings[0],
|
|
219
231
|
});
|
|
232
|
+
|
|
233
|
+
assert.calledWith(webex.internal.board.realtime.realtimeChannels.get, channel.channelId);
|
|
234
|
+
assert.called(mockRealtimeChannel.socket.open);
|
|
235
|
+
});
|
|
220
236
|
});
|
|
221
237
|
});
|
|
222
238
|
|
|
@@ -224,11 +240,10 @@ describe('plugin-board', () => {
|
|
|
224
240
|
it('disconnects the mercury connection', () => {
|
|
225
241
|
sinon.stub(mockRealtimeChannel, 'disconnect').returns(Promise.resolve());
|
|
226
242
|
|
|
227
|
-
return webex.internal.board.realtime.disconnectMercuryConnection(channel)
|
|
228
|
-
.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
});
|
|
243
|
+
return webex.internal.board.realtime.disconnectMercuryConnection(channel).then(() => {
|
|
244
|
+
assert.called(mockRealtimeChannel.disconnect);
|
|
245
|
+
assert.called(webex.internal.board.realtime.realtimeChannels.remove);
|
|
246
|
+
});
|
|
232
247
|
});
|
|
233
248
|
|
|
234
249
|
it('rejects if channel not found', () => {
|
|
@@ -246,20 +261,26 @@ describe('plugin-board', () => {
|
|
|
246
261
|
replaceBindingRes = {
|
|
247
262
|
mercuryConnectionServiceClusterUrl: 'https://mercury-connection-a5.wbx2.com/v1',
|
|
248
263
|
binding: 'board.a85e2f70-528d-11e6-ad98-bd2acefef905',
|
|
249
|
-
webSocketUrl:
|
|
264
|
+
webSocketUrl:
|
|
265
|
+
'wss://mercury-connection-a.wbx2.com/v1/apps/wx2/registrations/14d6abda-16de-4e02-bf7c-6d2a0e77ec38/messages',
|
|
250
266
|
sharedWebSocket: true,
|
|
251
|
-
action: 'ADD'
|
|
267
|
+
action: 'ADD',
|
|
252
268
|
};
|
|
253
269
|
|
|
254
270
|
removeBindingRes = {
|
|
255
271
|
binding: 'board.a85e2f70-528d-11e6-ad98-bd2acefef905',
|
|
256
|
-
webSocketUrl:
|
|
272
|
+
webSocketUrl:
|
|
273
|
+
'wss://mercury-connection-a.wbx2.com/v1/apps/wx2/registrations/14d6abda-16de-4e02-bf7c-6d2a0e77ec38/messages',
|
|
257
274
|
sharedWebSocket: false,
|
|
258
|
-
action: 'REMOVE'
|
|
275
|
+
action: 'REMOVE',
|
|
259
276
|
};
|
|
260
277
|
|
|
261
|
-
sinon
|
|
262
|
-
|
|
278
|
+
sinon
|
|
279
|
+
.stub(webex.internal.board, 'registerToShareMercury')
|
|
280
|
+
.returns(Promise.resolve(replaceBindingRes));
|
|
281
|
+
sinon
|
|
282
|
+
.stub(webex.internal.board, 'unregisterFromSharedMercury')
|
|
283
|
+
.returns(Promise.resolve(removeBindingRes));
|
|
263
284
|
});
|
|
264
285
|
|
|
265
286
|
afterEach(() => {
|
|
@@ -267,8 +288,8 @@ describe('plugin-board', () => {
|
|
|
267
288
|
});
|
|
268
289
|
|
|
269
290
|
describe('#connectToSharedMercury', () => {
|
|
270
|
-
it('registers and gets board binding', () =>
|
|
271
|
-
.then((res) => {
|
|
291
|
+
it('registers and gets board binding', () =>
|
|
292
|
+
webex.internal.board.realtime.connectToSharedMercury(channel).then((res) => {
|
|
272
293
|
assert.isTrue(mockRealtimeChannel.isSharingMercury);
|
|
273
294
|
assert.deepEqual(res, replaceBindingRes);
|
|
274
295
|
}));
|
|
@@ -277,16 +298,21 @@ describe('plugin-board', () => {
|
|
|
277
298
|
it('opens a second socket with provided webSocketUrl', () => {
|
|
278
299
|
replaceBindingRes.sharedWebSocket = false;
|
|
279
300
|
|
|
280
|
-
return webex.internal.board.realtime
|
|
301
|
+
return webex.internal.board.realtime
|
|
302
|
+
.connectToSharedMercury(channel)
|
|
281
303
|
.then((res) => {
|
|
282
304
|
assert.isFalse(mockRealtimeChannel.isSharingMercury);
|
|
283
305
|
assert.deepEqual(res, replaceBindingRes);
|
|
284
306
|
assert.match(socketOpenStub.args[0][0], new RegExp(replaceBindingRes.webSocketUrl));
|
|
285
|
-
assert.calledWith(
|
|
307
|
+
assert.calledWith(
|
|
308
|
+
socketOpenStub,
|
|
309
|
+
sinon.match(replaceBindingRes.webSocketUrl),
|
|
310
|
+
sinon.match.any
|
|
311
|
+
);
|
|
286
312
|
})
|
|
287
313
|
.then(() => {
|
|
288
314
|
const channel2 = Object.assign({}, channel, {
|
|
289
|
-
channelId: 'channel2-id'
|
|
315
|
+
channelId: 'channel2-id',
|
|
290
316
|
});
|
|
291
317
|
|
|
292
318
|
sinon.stub(mockRealtimeChannel, 'connect').returns(Promise.resolve());
|
|
@@ -304,19 +330,22 @@ describe('plugin-board', () => {
|
|
|
304
330
|
});
|
|
305
331
|
|
|
306
332
|
describe('#disconnectFromSharedMercury()', () => {
|
|
307
|
-
it('requests to remove board bindings', () =>
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
333
|
+
it('requests to remove board bindings', () =>
|
|
334
|
+
webex.internal.board.realtime
|
|
335
|
+
.connectToSharedMercury(channel)
|
|
336
|
+
.then(() => webex.internal.board.realtime.disconnectFromSharedMercury(channel))
|
|
337
|
+
.then((res) => {
|
|
338
|
+
assert.deepEqual(res, removeBindingRes);
|
|
339
|
+
assert.called(webex.internal.board.realtime.realtimeChannels.remove);
|
|
340
|
+
}));
|
|
313
341
|
|
|
314
342
|
describe('when a second connection is open', () => {
|
|
315
343
|
it('disconnects the second socket', () => {
|
|
316
344
|
sinon.stub(mockRealtimeChannel, 'disconnect').returns(Promise.resolve());
|
|
317
345
|
replaceBindingRes.sharedWebSocket = false;
|
|
318
346
|
|
|
319
|
-
return webex.internal.board.realtime
|
|
347
|
+
return webex.internal.board.realtime
|
|
348
|
+
.connectToSharedMercury(channel)
|
|
320
349
|
.then(() => {
|
|
321
350
|
assert.isFalse(mockRealtimeChannel.isSharingMercury);
|
|
322
351
|
|
|
@@ -334,15 +363,26 @@ describe('plugin-board', () => {
|
|
|
334
363
|
|
|
335
364
|
describe('#_boardChannelIdToMercuryBinding', () => {
|
|
336
365
|
it('adds board. binding prefix', () => {
|
|
337
|
-
assert.equal(
|
|
366
|
+
assert.equal(
|
|
367
|
+
webex.internal.board.realtime._boardChannelIdToMercuryBinding('test'),
|
|
368
|
+
'board.test'
|
|
369
|
+
);
|
|
338
370
|
});
|
|
339
371
|
|
|
340
|
-
it(
|
|
341
|
-
assert.equal(
|
|
372
|
+
it("replaces '-' with '.' and '_' with '#'", () => {
|
|
373
|
+
assert.equal(
|
|
374
|
+
webex.internal.board.realtime._boardChannelIdToMercuryBinding('abc-1234_bcd'),
|
|
375
|
+
'board.abc.1234#bcd'
|
|
376
|
+
);
|
|
342
377
|
});
|
|
343
378
|
|
|
344
379
|
it('leaves strings without - and _ alone', () => {
|
|
345
|
-
assert.equal(
|
|
380
|
+
assert.equal(
|
|
381
|
+
webex.internal.board.realtime._boardChannelIdToMercuryBinding(
|
|
382
|
+
'abcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()+='
|
|
383
|
+
),
|
|
384
|
+
'board.abcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()+='
|
|
385
|
+
);
|
|
346
386
|
});
|
|
347
387
|
});
|
|
348
388
|
|
|
@@ -354,19 +394,20 @@ describe('plugin-board', () => {
|
|
|
354
394
|
data: {
|
|
355
395
|
eventType: 'board.activity',
|
|
356
396
|
actor: {
|
|
357
|
-
id: 'actorId'
|
|
397
|
+
id: 'actorId',
|
|
358
398
|
},
|
|
359
399
|
envelope: {
|
|
360
|
-
channelId: '1'
|
|
361
|
-
}
|
|
362
|
-
}
|
|
400
|
+
channelId: '1',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
363
403
|
};
|
|
364
404
|
|
|
365
405
|
webex.internal.board.realtime.realtimeChannels.get.restore();
|
|
366
406
|
webex.internal.board.realtime.realtimeChannels.add.restore();
|
|
367
407
|
webex.internal.board.realtime.realtimeChannels.remove.restore();
|
|
368
408
|
|
|
369
|
-
return webex.internal.board.realtime
|
|
409
|
+
return webex.internal.board.realtime
|
|
410
|
+
.createRealtimeChannel({channelId: '1'})
|
|
370
411
|
.then((realtimeChannel) => {
|
|
371
412
|
realtime1 = realtimeChannel;
|
|
372
413
|
|
|
@@ -400,19 +441,20 @@ describe('plugin-board', () => {
|
|
|
400
441
|
data: {
|
|
401
442
|
eventType: 'board.activity',
|
|
402
443
|
actor: {
|
|
403
|
-
id: 'actorId'
|
|
444
|
+
id: 'actorId',
|
|
404
445
|
},
|
|
405
|
-
conversationId: uuid.v4()
|
|
446
|
+
conversationId: uuid.v4(),
|
|
406
447
|
},
|
|
407
448
|
timestamp: Date.now(),
|
|
408
|
-
trackingId: `suffix_${uuid.v4()}_${Date.now()}
|
|
449
|
+
trackingId: `suffix_${uuid.v4()}_${Date.now()}`,
|
|
409
450
|
};
|
|
410
451
|
});
|
|
411
452
|
|
|
412
453
|
it('emits message', () => {
|
|
413
454
|
const spy = sinon.spy();
|
|
414
455
|
|
|
415
|
-
return webex.internal.board.realtime
|
|
456
|
+
return webex.internal.board.realtime
|
|
457
|
+
.createRealtimeChannel(channel)
|
|
416
458
|
.then((realtimeChannel) => {
|
|
417
459
|
realtimeChannel.on('event:board.activity', spy);
|
|
418
460
|
})
|