@webex/internal-plugin-calendar 2.59.1 → 2.59.3-next.1

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.
@@ -1,624 +1,624 @@
1
- /*!
2
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
- */
4
-
5
- /* eslint camelcase: [0] */
6
-
7
- import '@webex/internal-plugin-calendar';
8
- import WebexCore from '@webex/webex-core';
9
- import {assert} from '@webex/test-helper-chai';
10
- import retry from '@webex/test-helper-retry';
11
- import testUsers from '@webex/test-helper-test-users';
12
- import uuid from 'uuid';
13
-
14
- /**
15
- * produces a mock meeting object
16
- * @param {Object} params
17
- * @returns {Meeting}
18
- */
19
- function makeMockMeetingPayload(params) {
20
- const payload = {
21
- id: params.meetingId,
22
- seriesId: params.seriesId,
23
- start: params.start,
24
- durationMinutes: params.durationMinutes,
25
- organizer: params.organizer.id,
26
- encryptionKeyUrl: '',
27
- encryptedSubject: params.title,
28
- isRecurring: params.isRecurring,
29
- links: [
30
- {
31
- href: `https://calendar-example.com/calendar/api/v1/${params.locusId}`,
32
- rel: 'self',
33
- },
34
- ],
35
- encryptedNotes: params.body,
36
- encryptedLocation: params.location,
37
- webexURI: params.webexURI,
38
- webexURL: params.webexURL,
39
- spaceMeetURL: params.spaceMeetURL,
40
- spaceURI: params.spaceURI,
41
- spaceURL: params.spaceURL,
42
- meetingJoinInfo: {
43
- meetingJoinURI: params.meetingJoinInfo.meetingJoinURI,
44
- meetingJoinURL: params.meetingJoinInfo.meetingJoinURI,
45
- },
46
- encryptedParticipants: [
47
- {
48
- id: params.participants.participant1.id,
49
- type: 'PERSON',
50
- responseType: 'NO_RESPONSE',
51
- participantType: 'OPTIONAL',
52
- orgId: params.participants.participant1.orgId,
53
- encryptedEmailAddress: params.participants.participant1.emailAddress,
54
- encryptedName: params.participants.participant1.name,
55
- },
56
- {
57
- id: params.participants.participant2.id,
58
- type: 'PERSON',
59
- responseType: 'UNKNOWN_RESPONSE',
60
- participantType: 'REQUIRED',
61
- orgId: params.participants.participant2.orgId,
62
- encryptedEmailAddress: params.participants.participant2.emailAddress,
63
- encryptedName: params.participants.participant2.name,
64
- },
65
- ],
66
- };
67
-
68
- return payload;
69
- }
70
-
71
- /**
72
- * produces a mock notes object
73
- * @param {Object} params
74
- * @returns {Notes}
75
- */
76
- function makeMockNotesPayload(params) {
77
- const payload = {
78
- id: params.meetingId,
79
- seriesId: params.seriesId,
80
- links: [
81
- {
82
- href: `https://calendar-example.com/calendar/api/v1/${params.locusId}`,
83
- rel: 'self',
84
- },
85
- ],
86
- encryptedNotes: params.meetingNotes,
87
- };
88
-
89
- return payload;
90
- }
91
-
92
- /**
93
- * produces a mock participants object
94
- * @param {Object} params
95
- * @returns {Participants}
96
- */
97
- function makeMockParticipantsPayload(params) {
98
- const payload = {
99
- id: params.meetingId,
100
- seriesId: params.seriesId,
101
- links: [
102
- {
103
- href: `https://calendar-example.com/calendar/api/v1/${params.locusId}`,
104
- rel: 'self',
105
- },
106
- ],
107
- encryptedParticipants: [
108
- {
109
- id: params.participants.participant1.id,
110
- type: 'PERSON',
111
- responseType: 'NO_RESPONSE',
112
- participantType: 'OPTIONAL',
113
- orgId: params.participants.participant1.orgId,
114
- encryptedEmailAddress: params.participants.participant1.emailAddress,
115
- encryptedName: params.participants.participant1.name,
116
- },
117
- {
118
- id: params.participants.participant2.id,
119
- type: 'PERSON',
120
- responseType: 'UNKNOWN_RESPONSE',
121
- participantType: 'REQUIRED',
122
- orgId: params.participants.participant2.orgId,
123
- encryptedEmailAddress: params.participants.participant2.emailAddress,
124
- encryptedName: params.participants.participant2.name,
125
- },
126
- ],
127
- };
128
-
129
- return payload;
130
- }
131
-
132
- function postToWhistler(webex, type, payload) {
133
- return retry(() =>
134
- webex
135
- .request({
136
- method: 'POST',
137
- uri: `${process.env.WHISTLER_API_SERVICE_URL}/calendarEvent`,
138
- body: payload,
139
- qs: {
140
- changeType: type,
141
- useProduction:
142
- typeof process.env.WDM_SERVICE_URL === 'undefined' ||
143
- process.env.WDM_SERVICE_URL.includes('wdm-a.wbx2.com'),
144
- },
145
- })
146
- .then((res) => {
147
- // Test response is using our parameters
148
- const createdMeeting = res.body;
149
-
150
- assert.isDefined(createdMeeting);
151
- assert.equal(createdMeeting.meeting.itemId, payload.id);
152
- assert.equal(createdMeeting.userUUID, payload.organizer);
153
- assert.equal(createdMeeting.meeting.startDate, payload.start);
154
- assert.equal(createdMeeting.meeting.duration, payload.durationMinutes);
155
-
156
- return res;
157
- })
158
- );
159
- }
160
-
161
- function postNotesToWhistler(webex, type, payload) {
162
- return retry(() =>
163
- webex
164
- .request({
165
- method: 'POST',
166
- uri: `${process.env.WHISTLER_API_SERVICE_URL}/calendarEvent`,
167
- body: payload,
168
- qs: {
169
- changeType: type,
170
- useProduction:
171
- typeof process.env.WDM_SERVICE_URL === 'undefined' ||
172
- process.env.WDM_SERVICE_URL.includes('wdm-a.wbx2.com'),
173
- },
174
- })
175
- .then((res) => res.body)
176
- );
177
- }
178
-
179
- function postParticipantsToWhistler(webex, type, payload) {
180
- return retry(() =>
181
- webex
182
- .request({
183
- method: 'POST',
184
- uri: `${process.env.WHISTLER_API_SERVICE_URL}/calendarEvent`,
185
- body: payload,
186
- qs: {
187
- changeType: type,
188
- useProduction:
189
- typeof process.env.WDM_SERVICE_URL === 'undefined' ||
190
- process.env.WDM_SERVICE_URL.includes('wdm-a.wbx2.com'),
191
- },
192
- })
193
- .then((res) => res.body)
194
- );
195
- }
196
-
197
- describe.skip('plugin-calendar', () => {
198
- describe('Calendar', () => {
199
- describe('#list()', function () {
200
- this.timeout(retry.timeout(20000));
201
- let creator, mccoy, webex, spock;
202
-
203
- before('create test users', () =>
204
- testUsers
205
- .create({
206
- count: 3,
207
- config: {
208
- entitlements: [
209
- 'sparkCompliance',
210
- 'sparkAdmin',
211
- 'spark',
212
- 'squaredCallInitiation',
213
- 'squaredRoomModeration',
214
- 'squaredInviter',
215
- 'webExSquared',
216
- 'squaredFusionCal',
217
- ],
218
- },
219
- })
220
- .then((users) => {
221
- [creator, spock, mccoy] = users;
222
-
223
- webex = new WebexCore({
224
- credentials: {
225
- authorization: creator.token,
226
- },
227
- config: {
228
- device: {
229
- preDiscoveryServices: {
230
- whistlerServiceUrl:
231
- process.env.WHISTLER_API_SERVICE_URL ||
232
- 'https://calendar-whistler.allnint.ciscospark.com:8084/api/v1',
233
- },
234
- },
235
- },
236
- });
237
- })
238
- );
239
-
240
- before('register to wdm, set features, and connect to mercury', () =>
241
- webex.internal.device
242
- .register()
243
- .then(() => webex.internal.feature.setFeature('developer', 'calsvc_calendar_view', true))
244
- .then(() => webex.internal.mercury.connect())
245
- );
246
-
247
- after(() => webex && webex.internal.mercury.disconnect());
248
-
249
- it('retrieves the meeting list for the default date range', () => {
250
- const hour = 1000 * 60 * 60;
251
- const startInterval = new Date(new Date().getTime() + hour * 2).toISOString();
252
- const duration = 60;
253
- const meetingID = uuid.v4();
254
- const locusID = uuid.v4();
255
- const seriesID = uuid.v4();
256
-
257
- const meetingParams = {
258
- meetingId: meetingID,
259
- seriesId: seriesID,
260
- start: startInterval,
261
- durationMinutes: duration,
262
- title: `test-plugin-calendar-meeting-${meetingID}`,
263
- locusId: locusID,
264
- hasAttachments: false,
265
- isRecurring: false,
266
- organizer: creator,
267
- participants: {
268
- participant1: mccoy,
269
- participant2: spock,
270
- },
271
- location: '@webex',
272
- body: 'Test Agenda',
273
- };
274
-
275
- return postToWhistler(webex, 'CREATE', makeMockMeetingPayload(meetingParams)).then(
276
- (res) => {
277
- const createdMeeting = res.body;
278
-
279
- return webex.internal.calendar.list().then((meetings) => {
280
- const testMeeting = meetings.find(
281
- (meeting) => meeting.seriesId === createdMeeting.meeting.meetingSeriesId
282
- );
283
-
284
- assert.isDefined(testMeeting);
285
- assert.equal(createdMeeting.meeting.meetingSeriesId, testMeeting.seriesId);
286
- assert.equal(createdMeeting.userUUID, testMeeting.organizer);
287
- assert.equal(createdMeeting.meeting.startDate, testMeeting.start);
288
- assert.equal(
289
- Math.round(
290
- (new Date(createdMeeting.meeting.endDate).getTime() -
291
- new Date(createdMeeting.meeting.startDate).getTime()) /
292
- 60000
293
- ),
294
- testMeeting.durationMinutes
295
- );
296
-
297
- // Validate decryption of subject, location and agenda
298
- assert.isDefined(testMeeting.encryptedSubject);
299
- assert.equal(meetingParams.title, testMeeting.encryptedSubject);
300
- assert.isDefined(testMeeting.encryptedLocation);
301
- assert.equal(meetingParams.location, testMeeting.encryptedLocation);
302
- assert.isDefined(testMeeting.encryptedNotes);
303
- assert.equal(meetingParams.body, testMeeting.encryptedNotes);
304
- assert.isDefined(testMeeting.webexURI);
305
- assert.equal(meetingParams.location, testMeeting.webexURI);
306
- assert.isDefined(testMeeting.webexURL);
307
- assert.equal(meetingParams.location, testMeeting.webexURL);
308
- assert.isDefined(testMeeting.spaceMeetURL);
309
- assert.equal(meetingParams.location, testMeeting.spaceMeetURL);
310
- assert.isDefined(testMeeting.spaceURI);
311
- assert.equal(meetingParams.location, testMeeting.spaceURI);
312
- assert.isDefined(testMeeting.spaceURL);
313
- assert.equal(meetingParams.location, testMeeting.spaceURL);
314
- assert.isDefined(testMeeting.encryptedParticipants);
315
- const encryptedParticipant1 = testMeeting.encryptedParticipants.find(
316
- (participant) => participant.id === meetingParams.participants.participant1.id
317
- );
318
- const encryptedParticipant2 = testMeeting.encryptedParticipants.find(
319
- (participant) => participant.id === meetingParams.participants.participant2.id
320
- );
321
-
322
- assert.equal(
323
- meetingParams.participants.participant1.emailAddress,
324
- encryptedParticipant1.encryptedEmailAddress
325
- );
326
- assert.equal(
327
- meetingParams.participants.participant1.name,
328
- encryptedParticipant1.encryptedName
329
- );
330
- assert.equal(
331
- meetingParams.participants.participant2.emailAddress,
332
- encryptedParticipant2.encryptedEmailAddress
333
- );
334
- assert.equal(
335
- meetingParams.participants.participant2.name,
336
- encryptedParticipant2.encryptedName
337
- );
338
- });
339
- }
340
- );
341
- });
342
-
343
- it('receives a mercury event for a new meeting', () => {
344
- const hour = 1000 * 60 * 60;
345
- const startInterval = new Date(new Date().getTime() + hour * 2).toISOString();
346
- const duration = 60;
347
- const meetingID = uuid.v4();
348
- const locusID = uuid.v4();
349
- const seriesID = uuid.v4();
350
-
351
- const meetingParams = {
352
- meetingId: meetingID,
353
- seriesId: seriesID,
354
- start: startInterval,
355
- durationMinutes: duration,
356
- title: `test-plugin-calendar-meeting-${meetingID}`,
357
- locusId: locusID,
358
- hasAttachments: false,
359
- isRecurring: false,
360
- organizer: creator,
361
- participants: {
362
- participant1: mccoy,
363
- participant2: spock,
364
- },
365
- location: '@webex',
366
- body: 'Test Agenda',
367
- };
368
-
369
- const mercuryPromise = new Promise((resolve) => {
370
- webex.internal.mercury.on('event:calendar.meeting.create', (event) => {
371
- resolve(event.data.calendarMeetingExternal);
372
- });
373
- });
374
-
375
- return postToWhistler(webex, 'CREATE', makeMockMeetingPayload(meetingParams)).then(
376
- (res) => {
377
- const createdMeeting = res.body;
378
-
379
- return mercuryPromise.then((calendarMeetingExternal) => {
380
- assert.equal(
381
- createdMeeting.meeting.meetingSeriesId,
382
- calendarMeetingExternal.seriesId
383
- );
384
- assert.equal(createdMeeting.userUUID, calendarMeetingExternal.organizer);
385
- assert.equal(createdMeeting.meeting.startDate, calendarMeetingExternal.start);
386
- assert.equal(
387
- Math.round(
388
- (new Date(createdMeeting.meeting.endDate).getTime() -
389
- new Date(createdMeeting.meeting.startDate).getTime()) /
390
- 60000
391
- ),
392
- calendarMeetingExternal.durationMinutes
393
- );
394
-
395
- // Validate decryption of subject, location and agenda
396
- assert.isDefined(calendarMeetingExternal.encryptedSubject);
397
- assert.equal(meetingParams.title, calendarMeetingExternal.encryptedSubject);
398
- assert.isDefined(calendarMeetingExternal.encryptedLocation);
399
- assert.equal(meetingParams.location, calendarMeetingExternal.encryptedLocation);
400
- assert.isDefined(calendarMeetingExternal.encryptedNotes);
401
- assert.equal(meetingParams.body, calendarMeetingExternal.encryptedNotes);
402
- assert.isDefined(calendarMeetingExternal.webexURI);
403
- assert.equal(meetingParams.body, calendarMeetingExternal.webexURI);
404
- assert.isDefined(calendarMeetingExternal.webexURL);
405
- assert.equal(meetingParams.body, calendarMeetingExternal.webexURL);
406
- assert.isDefined(calendarMeetingExternal.spaceMeetURL);
407
- assert.equal(meetingParams.body, calendarMeetingExternal.spaceMeetURL);
408
- assert.isDefined(calendarMeetingExternal.spaceURI);
409
- assert.equal(meetingParams.body, calendarMeetingExternal.spaceURI);
410
- assert.isDefined(calendarMeetingExternal.spaceURL);
411
- assert.equal(meetingParams.body, calendarMeetingExternal.spaceURL);
412
- assert.isDefined(calendarMeetingExternal.meetingJoinInfo.meetingJoinURI);
413
- assert.equal(
414
- meetingParams.body,
415
- calendarMeetingExternal.meetingJoinInfo.meetingJoinURI
416
- );
417
- assert.isDefined(calendarMeetingExternal.meetingJoinInfo.meetingJoinURL);
418
- assert.equal(
419
- meetingParams.body,
420
- calendarMeetingExternal.meetingJoinInfo.meetingJoinURL
421
- );
422
- assert.isDefined(calendarMeetingExternal.encryptedParticipants);
423
- const encryptedParticipant1 = calendarMeetingExternal.encryptedParticipants.find(
424
- (participant) => participant.id === meetingParams.participants.participant1.id
425
- );
426
- const encryptedParticipant2 = calendarMeetingExternal.encryptedParticipants.find(
427
- (participant) => participant.id === meetingParams.participants.participant2.id
428
- );
429
-
430
- assert.equal(
431
- meetingParams.participants.participant1.emailAddress,
432
- encryptedParticipant1.encryptedEmailAddress
433
- );
434
- assert.equal(
435
- meetingParams.participants.participant1.name,
436
- encryptedParticipant1.encryptedName
437
- );
438
- assert.equal(
439
- meetingParams.participants.participant2.emailAddress,
440
- encryptedParticipant2.encryptedEmailAddress
441
- );
442
- assert.equal(
443
- meetingParams.participants.participant2.name,
444
- encryptedParticipant2.encryptedName
445
- );
446
- });
447
- }
448
- );
449
- });
450
- });
451
-
452
- describe('#getNotes()', () => {
453
- let creator, webex;
454
-
455
- before('create test users', () =>
456
- testUsers
457
- .create({
458
- count: 3,
459
- config: {
460
- entitlements: [
461
- 'sparkCompliance',
462
- 'sparkAdmin',
463
- 'spark',
464
- 'squaredCallInitiation',
465
- 'squaredRoomModeration',
466
- 'squaredInviter',
467
- 'webExSquared',
468
- 'squaredFusionCal',
469
- ],
470
- },
471
- })
472
- .then((users) => {
473
- [creator] = users;
474
-
475
- webex = new WebexCore({
476
- credentials: {
477
- authorization: creator.token,
478
- },
479
- config: {
480
- services: {
481
- discovery: {
482
- whistlerServiceUrl:
483
- process.env.WHISTLER_API_SERVICE_URL ||
484
- 'https://calendar-whistler.allnint.ciscospark.com:8084/api/v1',
485
- },
486
- },
487
- },
488
- });
489
- })
490
- );
491
-
492
- before('register to wdm, set features, and connect to mercury', () =>
493
- webex.internal.device
494
- .register()
495
- .then(() => webex.internal.feature.setFeature('developer', 'calsvc_calendar_view', true))
496
- .then(() => webex.internal.mercury.connect())
497
- );
498
-
499
- after(() => webex && webex.internal.mercury.disconnect());
500
-
501
- it('retrieves the meeting notes for the given meetingId', () => {
502
- const meetingNotes = 'Dummy meeting notes';
503
- const meetingID = uuid.v4();
504
- const locusID = uuid.v4();
505
- const seriesID = uuid.v4();
506
-
507
- const meetingParams = {
508
- meetingId: meetingID,
509
- seriesId: seriesID,
510
- locusId: locusID,
511
- meetingNotes,
512
- };
513
-
514
- return postNotesToWhistler(webex, 'CREATE', makeMockNotesPayload(meetingParams)).then(
515
- (createdMeeting) =>
516
- webex.internal.calendar.getNotes(meetingID).then((response) => {
517
- assert.equal(createdMeeting.meeting.meetingSeriesId, response.seriesId);
518
- assert.equal(meetingParams.meetingNotes, response.encryptedNotes);
519
- })
520
- );
521
- });
522
- });
523
-
524
- describe('#getParticipants()', () => {
525
- let creator, mccoy, webex, spock;
526
-
527
- before('create test users', () =>
528
- testUsers
529
- .create({
530
- count: 3,
531
- config: {
532
- entitlements: [
533
- 'sparkCompliance',
534
- 'sparkAdmin',
535
- 'spark',
536
- 'squaredCallInitiation',
537
- 'squaredRoomModeration',
538
- 'squaredInviter',
539
- 'webExSquared',
540
- 'squaredFusionCal',
541
- ],
542
- },
543
- })
544
- .then((users) => {
545
- [creator, spock, mccoy] = users;
546
-
547
- webex = new WebexCore({
548
- credentials: {
549
- authorization: creator.token,
550
- },
551
- config: {
552
- services: {
553
- discovery: {
554
- whistlerServiceUrl:
555
- process.env.WHISTLER_API_SERVICE_URL ||
556
- 'https://calendar-whistler.allnint.ciscospark.com:8084/api/v1',
557
- },
558
- },
559
- },
560
- });
561
- })
562
- );
563
-
564
- before('register to wdm, set features, and connect to mercury', () =>
565
- webex.internal.device
566
- .register()
567
- .then(() => webex.internal.feature.setFeature('developer', 'calsvc_calendar_view', true))
568
- .then(() => webex.internal.mercury.connect())
569
- );
570
-
571
- after(() => webex && webex.internal.mercury.disconnect());
572
-
573
- it('retrieves the meeting participants for the given meetingId', () => {
574
- const meetingID = uuid.v4();
575
- const locusID = uuid.v4();
576
- const seriesID = uuid.v4();
577
-
578
- const meetingParams = {
579
- meetingId: meetingID,
580
- seriesId: seriesID,
581
- locusId: locusID,
582
- participants: {
583
- participant1: mccoy,
584
- participant2: spock,
585
- },
586
- };
587
-
588
- return postParticipantsToWhistler(
589
- webex,
590
- 'CREATE',
591
- makeMockParticipantsPayload(meetingParams)
592
- ).then((createdMeeting) =>
593
- webex.internal.calendar.getParticipants(meetingID).then((response) => {
594
- assert.equal(createdMeeting.meeting.meetingSeriesId, response.seriesId);
595
-
596
- const encryptedParticipant1 = response.encryptedParticipants.find(
597
- (participant) => participant.id === meetingParams.participants.participant1.id
598
- );
599
- const encryptedParticipant2 = response.encryptedParticipants.find(
600
- (participant) => participant.id === meetingParams.participants.participant2.id
601
- );
602
-
603
- assert.equal(
604
- meetingParams.participants.participant1.emailAddress,
605
- encryptedParticipant1.encryptedEmailAddress
606
- );
607
- assert.equal(
608
- meetingParams.participants.participant1.name,
609
- encryptedParticipant1.encryptedName
610
- );
611
- assert.equal(
612
- meetingParams.participants.participant2.emailAddress,
613
- encryptedParticipant2.encryptedEmailAddress
614
- );
615
- assert.equal(
616
- meetingParams.participants.participant2.name,
617
- encryptedParticipant2.encryptedName
618
- );
619
- })
620
- );
621
- });
622
- });
623
- });
624
- });
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ /* eslint camelcase: [0] */
6
+
7
+ import '@webex/internal-plugin-calendar';
8
+ import WebexCore from '@webex/webex-core';
9
+ import {assert} from '@webex/test-helper-chai';
10
+ import retry from '@webex/test-helper-retry';
11
+ import testUsers from '@webex/test-helper-test-users';
12
+ import uuid from 'uuid';
13
+
14
+ /**
15
+ * produces a mock meeting object
16
+ * @param {Object} params
17
+ * @returns {Meeting}
18
+ */
19
+ function makeMockMeetingPayload(params) {
20
+ const payload = {
21
+ id: params.meetingId,
22
+ seriesId: params.seriesId,
23
+ start: params.start,
24
+ durationMinutes: params.durationMinutes,
25
+ organizer: params.organizer.id,
26
+ encryptionKeyUrl: '',
27
+ encryptedSubject: params.title,
28
+ isRecurring: params.isRecurring,
29
+ links: [
30
+ {
31
+ href: `https://calendar-example.com/calendar/api/v1/${params.locusId}`,
32
+ rel: 'self',
33
+ },
34
+ ],
35
+ encryptedNotes: params.body,
36
+ encryptedLocation: params.location,
37
+ webexURI: params.webexURI,
38
+ webexURL: params.webexURL,
39
+ spaceMeetURL: params.spaceMeetURL,
40
+ spaceURI: params.spaceURI,
41
+ spaceURL: params.spaceURL,
42
+ meetingJoinInfo: {
43
+ meetingJoinURI: params.meetingJoinInfo.meetingJoinURI,
44
+ meetingJoinURL: params.meetingJoinInfo.meetingJoinURI,
45
+ },
46
+ encryptedParticipants: [
47
+ {
48
+ id: params.participants.participant1.id,
49
+ type: 'PERSON',
50
+ responseType: 'NO_RESPONSE',
51
+ participantType: 'OPTIONAL',
52
+ orgId: params.participants.participant1.orgId,
53
+ encryptedEmailAddress: params.participants.participant1.emailAddress,
54
+ encryptedName: params.participants.participant1.name,
55
+ },
56
+ {
57
+ id: params.participants.participant2.id,
58
+ type: 'PERSON',
59
+ responseType: 'UNKNOWN_RESPONSE',
60
+ participantType: 'REQUIRED',
61
+ orgId: params.participants.participant2.orgId,
62
+ encryptedEmailAddress: params.participants.participant2.emailAddress,
63
+ encryptedName: params.participants.participant2.name,
64
+ },
65
+ ],
66
+ };
67
+
68
+ return payload;
69
+ }
70
+
71
+ /**
72
+ * produces a mock notes object
73
+ * @param {Object} params
74
+ * @returns {Notes}
75
+ */
76
+ function makeMockNotesPayload(params) {
77
+ const payload = {
78
+ id: params.meetingId,
79
+ seriesId: params.seriesId,
80
+ links: [
81
+ {
82
+ href: `https://calendar-example.com/calendar/api/v1/${params.locusId}`,
83
+ rel: 'self',
84
+ },
85
+ ],
86
+ encryptedNotes: params.meetingNotes,
87
+ };
88
+
89
+ return payload;
90
+ }
91
+
92
+ /**
93
+ * produces a mock participants object
94
+ * @param {Object} params
95
+ * @returns {Participants}
96
+ */
97
+ function makeMockParticipantsPayload(params) {
98
+ const payload = {
99
+ id: params.meetingId,
100
+ seriesId: params.seriesId,
101
+ links: [
102
+ {
103
+ href: `https://calendar-example.com/calendar/api/v1/${params.locusId}`,
104
+ rel: 'self',
105
+ },
106
+ ],
107
+ encryptedParticipants: [
108
+ {
109
+ id: params.participants.participant1.id,
110
+ type: 'PERSON',
111
+ responseType: 'NO_RESPONSE',
112
+ participantType: 'OPTIONAL',
113
+ orgId: params.participants.participant1.orgId,
114
+ encryptedEmailAddress: params.participants.participant1.emailAddress,
115
+ encryptedName: params.participants.participant1.name,
116
+ },
117
+ {
118
+ id: params.participants.participant2.id,
119
+ type: 'PERSON',
120
+ responseType: 'UNKNOWN_RESPONSE',
121
+ participantType: 'REQUIRED',
122
+ orgId: params.participants.participant2.orgId,
123
+ encryptedEmailAddress: params.participants.participant2.emailAddress,
124
+ encryptedName: params.participants.participant2.name,
125
+ },
126
+ ],
127
+ };
128
+
129
+ return payload;
130
+ }
131
+
132
+ function postToWhistler(webex, type, payload) {
133
+ return retry(() =>
134
+ webex
135
+ .request({
136
+ method: 'POST',
137
+ uri: `${process.env.WHISTLER_API_SERVICE_URL}/calendarEvent`,
138
+ body: payload,
139
+ qs: {
140
+ changeType: type,
141
+ useProduction:
142
+ typeof process.env.WDM_SERVICE_URL === 'undefined' ||
143
+ process.env.WDM_SERVICE_URL.includes('wdm-a.wbx2.com'),
144
+ },
145
+ })
146
+ .then((res) => {
147
+ // Test response is using our parameters
148
+ const createdMeeting = res.body;
149
+
150
+ assert.isDefined(createdMeeting);
151
+ assert.equal(createdMeeting.meeting.itemId, payload.id);
152
+ assert.equal(createdMeeting.userUUID, payload.organizer);
153
+ assert.equal(createdMeeting.meeting.startDate, payload.start);
154
+ assert.equal(createdMeeting.meeting.duration, payload.durationMinutes);
155
+
156
+ return res;
157
+ })
158
+ );
159
+ }
160
+
161
+ function postNotesToWhistler(webex, type, payload) {
162
+ return retry(() =>
163
+ webex
164
+ .request({
165
+ method: 'POST',
166
+ uri: `${process.env.WHISTLER_API_SERVICE_URL}/calendarEvent`,
167
+ body: payload,
168
+ qs: {
169
+ changeType: type,
170
+ useProduction:
171
+ typeof process.env.WDM_SERVICE_URL === 'undefined' ||
172
+ process.env.WDM_SERVICE_URL.includes('wdm-a.wbx2.com'),
173
+ },
174
+ })
175
+ .then((res) => res.body)
176
+ );
177
+ }
178
+
179
+ function postParticipantsToWhistler(webex, type, payload) {
180
+ return retry(() =>
181
+ webex
182
+ .request({
183
+ method: 'POST',
184
+ uri: `${process.env.WHISTLER_API_SERVICE_URL}/calendarEvent`,
185
+ body: payload,
186
+ qs: {
187
+ changeType: type,
188
+ useProduction:
189
+ typeof process.env.WDM_SERVICE_URL === 'undefined' ||
190
+ process.env.WDM_SERVICE_URL.includes('wdm-a.wbx2.com'),
191
+ },
192
+ })
193
+ .then((res) => res.body)
194
+ );
195
+ }
196
+
197
+ describe.skip('plugin-calendar', () => {
198
+ describe('Calendar', () => {
199
+ describe('#list()', function () {
200
+ this.timeout(retry.timeout(20000));
201
+ let creator, mccoy, webex, spock;
202
+
203
+ before('create test users', () =>
204
+ testUsers
205
+ .create({
206
+ count: 3,
207
+ config: {
208
+ entitlements: [
209
+ 'sparkCompliance',
210
+ 'sparkAdmin',
211
+ 'spark',
212
+ 'squaredCallInitiation',
213
+ 'squaredRoomModeration',
214
+ 'squaredInviter',
215
+ 'webExSquared',
216
+ 'squaredFusionCal',
217
+ ],
218
+ },
219
+ })
220
+ .then((users) => {
221
+ [creator, spock, mccoy] = users;
222
+
223
+ webex = new WebexCore({
224
+ credentials: {
225
+ authorization: creator.token,
226
+ },
227
+ config: {
228
+ device: {
229
+ preDiscoveryServices: {
230
+ whistlerServiceUrl:
231
+ process.env.WHISTLER_API_SERVICE_URL ||
232
+ 'https://calendar-whistler.allnint.ciscospark.com:8084/api/v1',
233
+ },
234
+ },
235
+ },
236
+ });
237
+ })
238
+ );
239
+
240
+ before('register to wdm, set features, and connect to mercury', () =>
241
+ webex.internal.device
242
+ .register()
243
+ .then(() => webex.internal.feature.setFeature('developer', 'calsvc_calendar_view', true))
244
+ .then(() => webex.internal.mercury.connect())
245
+ );
246
+
247
+ after(() => webex && webex.internal.mercury.disconnect());
248
+
249
+ it('retrieves the meeting list for the default date range', () => {
250
+ const hour = 1000 * 60 * 60;
251
+ const startInterval = new Date(new Date().getTime() + hour * 2).toISOString();
252
+ const duration = 60;
253
+ const meetingID = uuid.v4();
254
+ const locusID = uuid.v4();
255
+ const seriesID = uuid.v4();
256
+
257
+ const meetingParams = {
258
+ meetingId: meetingID,
259
+ seriesId: seriesID,
260
+ start: startInterval,
261
+ durationMinutes: duration,
262
+ title: `test-plugin-calendar-meeting-${meetingID}`,
263
+ locusId: locusID,
264
+ hasAttachments: false,
265
+ isRecurring: false,
266
+ organizer: creator,
267
+ participants: {
268
+ participant1: mccoy,
269
+ participant2: spock,
270
+ },
271
+ location: '@webex',
272
+ body: 'Test Agenda',
273
+ };
274
+
275
+ return postToWhistler(webex, 'CREATE', makeMockMeetingPayload(meetingParams)).then(
276
+ (res) => {
277
+ const createdMeeting = res.body;
278
+
279
+ return webex.internal.calendar.list().then((meetings) => {
280
+ const testMeeting = meetings.find(
281
+ (meeting) => meeting.seriesId === createdMeeting.meeting.meetingSeriesId
282
+ );
283
+
284
+ assert.isDefined(testMeeting);
285
+ assert.equal(createdMeeting.meeting.meetingSeriesId, testMeeting.seriesId);
286
+ assert.equal(createdMeeting.userUUID, testMeeting.organizer);
287
+ assert.equal(createdMeeting.meeting.startDate, testMeeting.start);
288
+ assert.equal(
289
+ Math.round(
290
+ (new Date(createdMeeting.meeting.endDate).getTime() -
291
+ new Date(createdMeeting.meeting.startDate).getTime()) /
292
+ 60000
293
+ ),
294
+ testMeeting.durationMinutes
295
+ );
296
+
297
+ // Validate decryption of subject, location and agenda
298
+ assert.isDefined(testMeeting.encryptedSubject);
299
+ assert.equal(meetingParams.title, testMeeting.encryptedSubject);
300
+ assert.isDefined(testMeeting.encryptedLocation);
301
+ assert.equal(meetingParams.location, testMeeting.encryptedLocation);
302
+ assert.isDefined(testMeeting.encryptedNotes);
303
+ assert.equal(meetingParams.body, testMeeting.encryptedNotes);
304
+ assert.isDefined(testMeeting.webexURI);
305
+ assert.equal(meetingParams.location, testMeeting.webexURI);
306
+ assert.isDefined(testMeeting.webexURL);
307
+ assert.equal(meetingParams.location, testMeeting.webexURL);
308
+ assert.isDefined(testMeeting.spaceMeetURL);
309
+ assert.equal(meetingParams.location, testMeeting.spaceMeetURL);
310
+ assert.isDefined(testMeeting.spaceURI);
311
+ assert.equal(meetingParams.location, testMeeting.spaceURI);
312
+ assert.isDefined(testMeeting.spaceURL);
313
+ assert.equal(meetingParams.location, testMeeting.spaceURL);
314
+ assert.isDefined(testMeeting.encryptedParticipants);
315
+ const encryptedParticipant1 = testMeeting.encryptedParticipants.find(
316
+ (participant) => participant.id === meetingParams.participants.participant1.id
317
+ );
318
+ const encryptedParticipant2 = testMeeting.encryptedParticipants.find(
319
+ (participant) => participant.id === meetingParams.participants.participant2.id
320
+ );
321
+
322
+ assert.equal(
323
+ meetingParams.participants.participant1.emailAddress,
324
+ encryptedParticipant1.encryptedEmailAddress
325
+ );
326
+ assert.equal(
327
+ meetingParams.participants.participant1.name,
328
+ encryptedParticipant1.encryptedName
329
+ );
330
+ assert.equal(
331
+ meetingParams.participants.participant2.emailAddress,
332
+ encryptedParticipant2.encryptedEmailAddress
333
+ );
334
+ assert.equal(
335
+ meetingParams.participants.participant2.name,
336
+ encryptedParticipant2.encryptedName
337
+ );
338
+ });
339
+ }
340
+ );
341
+ });
342
+
343
+ it('receives a mercury event for a new meeting', () => {
344
+ const hour = 1000 * 60 * 60;
345
+ const startInterval = new Date(new Date().getTime() + hour * 2).toISOString();
346
+ const duration = 60;
347
+ const meetingID = uuid.v4();
348
+ const locusID = uuid.v4();
349
+ const seriesID = uuid.v4();
350
+
351
+ const meetingParams = {
352
+ meetingId: meetingID,
353
+ seriesId: seriesID,
354
+ start: startInterval,
355
+ durationMinutes: duration,
356
+ title: `test-plugin-calendar-meeting-${meetingID}`,
357
+ locusId: locusID,
358
+ hasAttachments: false,
359
+ isRecurring: false,
360
+ organizer: creator,
361
+ participants: {
362
+ participant1: mccoy,
363
+ participant2: spock,
364
+ },
365
+ location: '@webex',
366
+ body: 'Test Agenda',
367
+ };
368
+
369
+ const mercuryPromise = new Promise((resolve) => {
370
+ webex.internal.mercury.on('event:calendar.meeting.create', (event) => {
371
+ resolve(event.data.calendarMeetingExternal);
372
+ });
373
+ });
374
+
375
+ return postToWhistler(webex, 'CREATE', makeMockMeetingPayload(meetingParams)).then(
376
+ (res) => {
377
+ const createdMeeting = res.body;
378
+
379
+ return mercuryPromise.then((calendarMeetingExternal) => {
380
+ assert.equal(
381
+ createdMeeting.meeting.meetingSeriesId,
382
+ calendarMeetingExternal.seriesId
383
+ );
384
+ assert.equal(createdMeeting.userUUID, calendarMeetingExternal.organizer);
385
+ assert.equal(createdMeeting.meeting.startDate, calendarMeetingExternal.start);
386
+ assert.equal(
387
+ Math.round(
388
+ (new Date(createdMeeting.meeting.endDate).getTime() -
389
+ new Date(createdMeeting.meeting.startDate).getTime()) /
390
+ 60000
391
+ ),
392
+ calendarMeetingExternal.durationMinutes
393
+ );
394
+
395
+ // Validate decryption of subject, location and agenda
396
+ assert.isDefined(calendarMeetingExternal.encryptedSubject);
397
+ assert.equal(meetingParams.title, calendarMeetingExternal.encryptedSubject);
398
+ assert.isDefined(calendarMeetingExternal.encryptedLocation);
399
+ assert.equal(meetingParams.location, calendarMeetingExternal.encryptedLocation);
400
+ assert.isDefined(calendarMeetingExternal.encryptedNotes);
401
+ assert.equal(meetingParams.body, calendarMeetingExternal.encryptedNotes);
402
+ assert.isDefined(calendarMeetingExternal.webexURI);
403
+ assert.equal(meetingParams.body, calendarMeetingExternal.webexURI);
404
+ assert.isDefined(calendarMeetingExternal.webexURL);
405
+ assert.equal(meetingParams.body, calendarMeetingExternal.webexURL);
406
+ assert.isDefined(calendarMeetingExternal.spaceMeetURL);
407
+ assert.equal(meetingParams.body, calendarMeetingExternal.spaceMeetURL);
408
+ assert.isDefined(calendarMeetingExternal.spaceURI);
409
+ assert.equal(meetingParams.body, calendarMeetingExternal.spaceURI);
410
+ assert.isDefined(calendarMeetingExternal.spaceURL);
411
+ assert.equal(meetingParams.body, calendarMeetingExternal.spaceURL);
412
+ assert.isDefined(calendarMeetingExternal.meetingJoinInfo.meetingJoinURI);
413
+ assert.equal(
414
+ meetingParams.body,
415
+ calendarMeetingExternal.meetingJoinInfo.meetingJoinURI
416
+ );
417
+ assert.isDefined(calendarMeetingExternal.meetingJoinInfo.meetingJoinURL);
418
+ assert.equal(
419
+ meetingParams.body,
420
+ calendarMeetingExternal.meetingJoinInfo.meetingJoinURL
421
+ );
422
+ assert.isDefined(calendarMeetingExternal.encryptedParticipants);
423
+ const encryptedParticipant1 = calendarMeetingExternal.encryptedParticipants.find(
424
+ (participant) => participant.id === meetingParams.participants.participant1.id
425
+ );
426
+ const encryptedParticipant2 = calendarMeetingExternal.encryptedParticipants.find(
427
+ (participant) => participant.id === meetingParams.participants.participant2.id
428
+ );
429
+
430
+ assert.equal(
431
+ meetingParams.participants.participant1.emailAddress,
432
+ encryptedParticipant1.encryptedEmailAddress
433
+ );
434
+ assert.equal(
435
+ meetingParams.participants.participant1.name,
436
+ encryptedParticipant1.encryptedName
437
+ );
438
+ assert.equal(
439
+ meetingParams.participants.participant2.emailAddress,
440
+ encryptedParticipant2.encryptedEmailAddress
441
+ );
442
+ assert.equal(
443
+ meetingParams.participants.participant2.name,
444
+ encryptedParticipant2.encryptedName
445
+ );
446
+ });
447
+ }
448
+ );
449
+ });
450
+ });
451
+
452
+ describe('#getNotes()', () => {
453
+ let creator, webex;
454
+
455
+ before('create test users', () =>
456
+ testUsers
457
+ .create({
458
+ count: 3,
459
+ config: {
460
+ entitlements: [
461
+ 'sparkCompliance',
462
+ 'sparkAdmin',
463
+ 'spark',
464
+ 'squaredCallInitiation',
465
+ 'squaredRoomModeration',
466
+ 'squaredInviter',
467
+ 'webExSquared',
468
+ 'squaredFusionCal',
469
+ ],
470
+ },
471
+ })
472
+ .then((users) => {
473
+ [creator] = users;
474
+
475
+ webex = new WebexCore({
476
+ credentials: {
477
+ authorization: creator.token,
478
+ },
479
+ config: {
480
+ services: {
481
+ discovery: {
482
+ whistlerServiceUrl:
483
+ process.env.WHISTLER_API_SERVICE_URL ||
484
+ 'https://calendar-whistler.allnint.ciscospark.com:8084/api/v1',
485
+ },
486
+ },
487
+ },
488
+ });
489
+ })
490
+ );
491
+
492
+ before('register to wdm, set features, and connect to mercury', () =>
493
+ webex.internal.device
494
+ .register()
495
+ .then(() => webex.internal.feature.setFeature('developer', 'calsvc_calendar_view', true))
496
+ .then(() => webex.internal.mercury.connect())
497
+ );
498
+
499
+ after(() => webex && webex.internal.mercury.disconnect());
500
+
501
+ it('retrieves the meeting notes for the given meetingId', () => {
502
+ const meetingNotes = 'Dummy meeting notes';
503
+ const meetingID = uuid.v4();
504
+ const locusID = uuid.v4();
505
+ const seriesID = uuid.v4();
506
+
507
+ const meetingParams = {
508
+ meetingId: meetingID,
509
+ seriesId: seriesID,
510
+ locusId: locusID,
511
+ meetingNotes,
512
+ };
513
+
514
+ return postNotesToWhistler(webex, 'CREATE', makeMockNotesPayload(meetingParams)).then(
515
+ (createdMeeting) =>
516
+ webex.internal.calendar.getNotes(meetingID).then((response) => {
517
+ assert.equal(createdMeeting.meeting.meetingSeriesId, response.seriesId);
518
+ assert.equal(meetingParams.meetingNotes, response.encryptedNotes);
519
+ })
520
+ );
521
+ });
522
+ });
523
+
524
+ describe('#getParticipants()', () => {
525
+ let creator, mccoy, webex, spock;
526
+
527
+ before('create test users', () =>
528
+ testUsers
529
+ .create({
530
+ count: 3,
531
+ config: {
532
+ entitlements: [
533
+ 'sparkCompliance',
534
+ 'sparkAdmin',
535
+ 'spark',
536
+ 'squaredCallInitiation',
537
+ 'squaredRoomModeration',
538
+ 'squaredInviter',
539
+ 'webExSquared',
540
+ 'squaredFusionCal',
541
+ ],
542
+ },
543
+ })
544
+ .then((users) => {
545
+ [creator, spock, mccoy] = users;
546
+
547
+ webex = new WebexCore({
548
+ credentials: {
549
+ authorization: creator.token,
550
+ },
551
+ config: {
552
+ services: {
553
+ discovery: {
554
+ whistlerServiceUrl:
555
+ process.env.WHISTLER_API_SERVICE_URL ||
556
+ 'https://calendar-whistler.allnint.ciscospark.com:8084/api/v1',
557
+ },
558
+ },
559
+ },
560
+ });
561
+ })
562
+ );
563
+
564
+ before('register to wdm, set features, and connect to mercury', () =>
565
+ webex.internal.device
566
+ .register()
567
+ .then(() => webex.internal.feature.setFeature('developer', 'calsvc_calendar_view', true))
568
+ .then(() => webex.internal.mercury.connect())
569
+ );
570
+
571
+ after(() => webex && webex.internal.mercury.disconnect());
572
+
573
+ it('retrieves the meeting participants for the given meetingId', () => {
574
+ const meetingID = uuid.v4();
575
+ const locusID = uuid.v4();
576
+ const seriesID = uuid.v4();
577
+
578
+ const meetingParams = {
579
+ meetingId: meetingID,
580
+ seriesId: seriesID,
581
+ locusId: locusID,
582
+ participants: {
583
+ participant1: mccoy,
584
+ participant2: spock,
585
+ },
586
+ };
587
+
588
+ return postParticipantsToWhistler(
589
+ webex,
590
+ 'CREATE',
591
+ makeMockParticipantsPayload(meetingParams)
592
+ ).then((createdMeeting) =>
593
+ webex.internal.calendar.getParticipants(meetingID).then((response) => {
594
+ assert.equal(createdMeeting.meeting.meetingSeriesId, response.seriesId);
595
+
596
+ const encryptedParticipant1 = response.encryptedParticipants.find(
597
+ (participant) => participant.id === meetingParams.participants.participant1.id
598
+ );
599
+ const encryptedParticipant2 = response.encryptedParticipants.find(
600
+ (participant) => participant.id === meetingParams.participants.participant2.id
601
+ );
602
+
603
+ assert.equal(
604
+ meetingParams.participants.participant1.emailAddress,
605
+ encryptedParticipant1.encryptedEmailAddress
606
+ );
607
+ assert.equal(
608
+ meetingParams.participants.participant1.name,
609
+ encryptedParticipant1.encryptedName
610
+ );
611
+ assert.equal(
612
+ meetingParams.participants.participant2.emailAddress,
613
+ encryptedParticipant2.encryptedEmailAddress
614
+ );
615
+ assert.equal(
616
+ meetingParams.participants.participant2.name,
617
+ encryptedParticipant2.encryptedName
618
+ );
619
+ })
620
+ );
621
+ });
622
+ });
623
+ });
624
+ });