@webex/plugin-meetings 3.8.0-next.27 → 3.8.0-next.28

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.
@@ -7,10 +7,7 @@ import sinon from 'sinon';
7
7
  import MockWebex from '@webex/test-helper-mock-webex';
8
8
  import Device from '@webex/internal-plugin-device';
9
9
  import Mercury from '@webex/internal-plugin-mercury';
10
- import {
11
- DESTINATION_TYPE,
12
- WBXAPPAPI_SERVICE,
13
- } from '@webex/plugin-meetings/src/constants';
10
+ import {DESTINATION_TYPE, WBXAPPAPI_SERVICE} from '@webex/plugin-meetings/src/constants';
14
11
 
15
12
  import Meetings from '@webex/plugin-meetings/src/meetings';
16
13
  import MeetingInfo, {
@@ -20,6 +17,8 @@ import MeetingInfo, {
20
17
  MeetingInfoV2PolicyError,
21
18
  MeetingInfoV2JoinWebinarError,
22
19
  MeetingInfoV2JoinForbiddenError,
20
+ MeetingInfoV2MeetingIsInProgressError,
21
+ MeetingInfoV2StaticMeetingLinkAlreadyExists,
23
22
  } from '@webex/plugin-meetings/src/meeting-info/meeting-info-v2';
24
23
  import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
25
24
  import Metrics from '@webex/plugin-meetings/src/metrics';
@@ -93,6 +92,139 @@ describe('plugin-meetings', () => {
93
92
  meetingInfo = new MeetingInfo(webex);
94
93
  });
95
94
 
95
+ describe('#enableStaticMeetingLink', () => {
96
+ const setup = () => {
97
+ const invitee = [];
98
+
99
+ invitee.push({
100
+ email: conversation.participants.items[0].emailAddress,
101
+ ciUserUuid: conversation.participants.items[0].entryUUID,
102
+ });
103
+
104
+ invitee.push({
105
+ email: conversation.participants.items[1].emailAddress,
106
+ ciUserUuid: conversation.participants.items[1].entryUUID,
107
+ });
108
+
109
+ return {invitee};
110
+ };
111
+
112
+ it('should enable static meeting link', async () => {
113
+ const {invitee} = setup();
114
+ const installedOrgID = '12345';
115
+ const conversationUrl = 'conv.fakeconversationurl.com';
116
+ webex.request.resolves({
117
+ statusCode: 200,
118
+ body: conversation,
119
+ });
120
+ const result = await meetingInfo.enableStaticMeetingLink(conversationUrl);
121
+
122
+ assert.calledWith(webex.request, {
123
+ uri: conversationUrl,
124
+ qs: {includeParticipants: true},
125
+ disableTransform: true,
126
+ });
127
+
128
+ assert.calledWith(webex.request, {
129
+ method: 'POST',
130
+ uri: `https://${webex.meetings.preferredWebexSite}/wbxappapi/v2/meetings/spaceInstant`,
131
+ body: {
132
+ title: conversation.displayName,
133
+ spaceUrl: conversation.url,
134
+ keyUrl: conversation.encryptionKeyUrl,
135
+ kroUrl: conversation.kmsResourceObjectUrl,
136
+ invitees: invitee,
137
+ installedOrgID: undefined,
138
+ schedule: true,
139
+ },
140
+ });
141
+
142
+ assert(Metrics.sendBehavioralMetric.calledOnce);
143
+ assert.calledWith(
144
+ Metrics.sendBehavioralMetric,
145
+ BEHAVIORAL_METRICS.ENABLE_STATIC_METTING_LINK_SUCCESS
146
+ );
147
+
148
+ assert.deepEqual(result, {
149
+ body: conversation,
150
+ statusCode: 200,
151
+ });
152
+ });
153
+
154
+ it('should not enable static meeting link for given conversation url if no preferred webex site', async () => {
155
+ webex.meetings.preferredWebexSite = undefined;
156
+
157
+ const conversationUrl = 'conv.fakeconversationurl.com';
158
+ try {
159
+ await meetingInfo.enableStaticMeetingLink(conversationUrl);
160
+
161
+ assert.calledWith(webex.request, {
162
+ method: 'POST',
163
+ uri: `https://${webex.meetings.preferredWebexSite}/wbxappapi/v2/meetings/spaceInstant`,
164
+ body,
165
+ });
166
+ } catch (err) {
167
+ assert.deepEqual(err.message, 'No preferred webex site found');
168
+ assert.notCalled(webex.request);
169
+ }
170
+ });
171
+
172
+ it('handles error for MeetingInfoV2MeetingIsInProgressError', async () => {
173
+ const conversationUrl = 'conv.fakeconversationurl.com';
174
+ webex.request = sinon
175
+ .stub()
176
+ .rejects({stack: 'a stack', message: 'a message', statusCode: 403, body: {code: 33003}});
177
+ try {
178
+ await meetingInfo.enableStaticMeetingLink(conversationUrl);
179
+ } catch (err) {
180
+ assert.equal(err.wbxAppApiCode, 33003);
181
+ assert.instanceOf(err, MeetingInfoV2MeetingIsInProgressError);
182
+ assert.deepEqual(err.message, 'Meeting is in progress, code=33003, enable=true');
183
+ assert.calledWith(
184
+ Metrics.sendBehavioralMetric,
185
+ BEHAVIORAL_METRICS.MEETING_IS_IN_PROGRESS_ERROR,
186
+ {reason: 'a message', stack: 'a stack'}
187
+ );
188
+ }
189
+ });
190
+
191
+ it('handles error for MeetingInfoV2StaticMeetingLinkAlreadyExists', async () => {
192
+ const conversationUrl = 'conv.fakeconversationurl.com';
193
+ webex.request = sinon
194
+ .stub()
195
+ .rejects({stack: 'a stack', message: 'a message', statusCode: 409, body: {code: 409000}});
196
+ try {
197
+ await meetingInfo.enableStaticMeetingLink(conversationUrl);
198
+ } catch (err) {
199
+ assert.equal(err.wbxAppApiCode, 409000);
200
+ assert.instanceOf(err, MeetingInfoV2StaticMeetingLinkAlreadyExists);
201
+ assert.deepEqual(err.message, 'Static meeting link already exists, code=409000');
202
+ assert.calledWith(
203
+ Metrics.sendBehavioralMetric,
204
+ BEHAVIORAL_METRICS.STATIC_MEETING_LINK_ALREADY_EXISTS_ERROR,
205
+ {reason: 'a message', stack: 'a stack'}
206
+ );
207
+ }
208
+ });
209
+
210
+ it('handles generic error when enabling static link', async () => {
211
+ const conversationUrl = 'conv.fakeconversationurl.com';
212
+ webex.request = sinon
213
+ .stub()
214
+ .rejects({stack: 'a stack', message: 'a message', statusCode: 500, body: {code: 400000}});
215
+ try {
216
+ await meetingInfo.enableStaticMeetingLink(conversationUrl);
217
+ } catch (err) {
218
+ assert(Metrics.sendBehavioralMetric.calledOnce);
219
+ assert.calledWith(
220
+ Metrics.sendBehavioralMetric,
221
+ BEHAVIORAL_METRICS.ENABLE_STATIC_METTING_LINK_FAILURE,
222
+ {reason: 'a message', stack: 'a stack'}
223
+ );
224
+ }
225
+ });
226
+ });
227
+
96
228
  describe('#fetchMeetingInfo', () => {
97
229
  it('should fetch meeting info for the destination type', async () => {
98
230
  const body = {meetingKey: '1234323'};
@@ -151,14 +283,20 @@ describe('plugin-meetings', () => {
151
283
  const body = {meetingKey: '1234323'};
152
284
  const requestResponse = {statusCode: 200, body};
153
285
 
154
- sinon
155
- .stub(MeetingInfoUtil, 'getDestinationType')
156
- .returns(Promise.resolve({type: DESTINATION_TYPE.SIP_URI, destination: 'example@something.webex.com'}));
286
+ sinon.stub(MeetingInfoUtil, 'getDestinationType').returns(
287
+ Promise.resolve({
288
+ type: DESTINATION_TYPE.SIP_URI,
289
+ destination: 'example@something.webex.com',
290
+ })
291
+ );
157
292
  sinon.stub(MeetingInfoUtil, 'getRequestBody').returns(Promise.resolve(body));
158
293
  sinon.stub(MeetingInfoUtil, 'getDirectMeetingInfoURI').returns('https://example.com');
159
294
  webex.request.resolves(requestResponse);
160
295
 
161
- const result = await meetingInfo.fetchMeetingInfo('example@something.webex.com', DESTINATION_TYPE.SIP_URI);
296
+ const result = await meetingInfo.fetchMeetingInfo(
297
+ 'example@something.webex.com',
298
+ DESTINATION_TYPE.SIP_URI
299
+ );
162
300
 
163
301
  assert.calledWith(MeetingInfoUtil.getDestinationType, {
164
302
  destination: 'example@something.webex.com',
@@ -186,10 +324,15 @@ describe('plugin-meetings', () => {
186
324
 
187
325
  webex.request.resolves(requestResponse);
188
326
 
189
- const result = await meetingInfo.fetchMeetingInfo('1234323', DESTINATION_TYPE.MEETING_ID, 'abc', {
190
- id: '999',
191
- code: 'aabbcc11',
192
- });
327
+ const result = await meetingInfo.fetchMeetingInfo(
328
+ '1234323',
329
+ DESTINATION_TYPE.MEETING_ID,
330
+ 'abc',
331
+ {
332
+ id: '999',
333
+ code: 'aabbcc11',
334
+ }
335
+ );
193
336
 
194
337
  assert.calledWith(webex.request, {
195
338
  method: 'POST',
@@ -218,7 +361,13 @@ describe('plugin-meetings', () => {
218
361
 
219
362
  webex.request.resolves(requestResponse);
220
363
 
221
- const result = await meetingInfo.fetchMeetingInfo('1234323', DESTINATION_TYPE.MEETING_ID, null, null, installedOrgID);
364
+ const result = await meetingInfo.fetchMeetingInfo(
365
+ '1234323',
366
+ DESTINATION_TYPE.MEETING_ID,
367
+ null,
368
+ null,
369
+ installedOrgID
370
+ );
222
371
 
223
372
  assert.calledWith(webex.request, {
224
373
  method: 'POST',
@@ -245,7 +394,14 @@ describe('plugin-meetings', () => {
245
394
 
246
395
  webex.request.resolves(requestResponse);
247
396
 
248
- const result = await meetingInfo.fetchMeetingInfo('1234323', DESTINATION_TYPE.MEETING_ID, null, null, null, locusId);
397
+ const result = await meetingInfo.fetchMeetingInfo(
398
+ '1234323',
399
+ DESTINATION_TYPE.MEETING_ID,
400
+ null,
401
+ null,
402
+ null,
403
+ locusId
404
+ );
249
405
 
250
406
  assert.calledWith(webex.request, {
251
407
  method: 'POST',
@@ -268,11 +424,19 @@ describe('plugin-meetings', () => {
268
424
 
269
425
  it('should fetch meeting info with provided extraParams', async () => {
270
426
  const requestResponse = {statusCode: 200, body: {meetingKey: '1234323'}};
271
- const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'}
427
+ const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
272
428
 
273
429
  webex.request.resolves(requestResponse);
274
430
 
275
- const result = await meetingInfo.fetchMeetingInfo('1234323', DESTINATION_TYPE.MEETING_ID, null, null, null, null, extraParams);
431
+ const result = await meetingInfo.fetchMeetingInfo(
432
+ '1234323',
433
+ DESTINATION_TYPE.MEETING_ID,
434
+ null,
435
+ null,
436
+ null,
437
+ null,
438
+ extraParams
439
+ );
276
440
 
277
441
  assert.calledWith(webex.request, {
278
442
  method: 'POST',
@@ -305,7 +469,7 @@ describe('plugin-meetings', () => {
305
469
  it('create adhoc meeting when conversationUrl and installedOrgID passed with enableAdhocMeetings toggle', async () => {
306
470
  sinon.stub(meetingInfo, 'createAdhocSpaceMeeting').returns(Promise.resolve());
307
471
 
308
- const installedOrgID = '12345'
472
+ const installedOrgID = '12345';
309
473
 
310
474
  await meetingInfo.fetchMeetingInfo(
311
475
  'conversationUrl',
@@ -324,7 +488,6 @@ describe('plugin-meetings', () => {
324
488
  meetingInfo.createAdhocSpaceMeeting.restore();
325
489
  });
326
490
 
327
-
328
491
  it('should not call createAdhocSpaceMeeting if enableAdhocMeetings toggle is off', async () => {
329
492
  webex.config.meetings.experimental.enableAdhocMeetings = false;
330
493
  sinon.stub(meetingInfo, 'createAdhocSpaceMeeting').returns(Promise.resolve());
@@ -350,7 +513,9 @@ describe('plugin-meetings', () => {
350
513
  it('should throw an error MeetingInfoV2AdhocMeetingError if not able to start adhoc meeting for a conversation', async () => {
351
514
  webex.config.meetings.experimental.enableAdhocMeetings = true;
352
515
 
353
- webex.request = sinon.stub().rejects({stack: 'a stack', message: 'a message', statusCode: 403, body: {code: 400000}});
516
+ webex.request = sinon
517
+ .stub()
518
+ .rejects({stack: 'a stack', message: 'a message', statusCode: 403, body: {code: 400000}});
354
519
  try {
355
520
  await meetingInfo.createAdhocSpaceMeeting('conversationUrl');
356
521
  } catch (err) {
@@ -416,7 +581,8 @@ describe('plugin-meetings', () => {
416
581
  );
417
582
  assert.fail('fetchMeetingInfo should have thrown, but has not done that');
418
583
  } catch (err) {
419
- const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
584
+ const submitInternalEventCalls =
585
+ webex.internal.newMetrics.submitInternalEvent.getCalls();
420
586
  const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
421
587
 
422
588
  if (sendCAevents) {
@@ -427,7 +593,7 @@ describe('plugin-meetings', () => {
427
593
  assert.deepEqual(submitClientEventCalls[0].args[0], {
428
594
  name: 'client.meetinginfo.request',
429
595
  options: {
430
- meetingId: 'meeting-id'
596
+ meetingId: 'meeting-id',
431
597
  },
432
598
  });
433
599
 
@@ -480,11 +646,14 @@ describe('plugin-meetings', () => {
480
646
  ],
481
647
  ({meetingId, sendCAevents, shouldSendCAevents, confIdStr}) => {
482
648
  it('should send CA metric if meetingId is provided and send CA events is authorized', async () => {
483
- const requestResponse = {statusCode: 200, body: {meetingKey: '1234323', meetingId: '123', confID: '321'}};
649
+ const requestResponse = {
650
+ statusCode: 200,
651
+ body: {meetingKey: '1234323', meetingId: '123', confID: '321'},
652
+ };
484
653
  if (confIdStr) {
485
654
  requestResponse.body.confIdStr = confIdStr;
486
655
  }
487
- const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'}
656
+ const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
488
657
 
489
658
  webex.request.resolves(requestResponse);
490
659
 
@@ -517,10 +686,11 @@ describe('plugin-meetings', () => {
517
686
  BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_SUCCESS
518
687
  );
519
688
 
520
- const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
689
+ const submitInternalEventCalls =
690
+ webex.internal.newMetrics.submitInternalEvent.getCalls();
521
691
  const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
522
692
 
523
- if(shouldSendCAevents) {
693
+ if (shouldSendCAevents) {
524
694
  assert.deepEqual(submitInternalEventCalls[0].args[0], {
525
695
  name: 'internal.client.meetinginfo.request',
526
696
  });
@@ -528,7 +698,7 @@ describe('plugin-meetings', () => {
528
698
  name: 'client.meetinginfo.request',
529
699
  options: {
530
700
  meetingId,
531
- }
701
+ },
532
702
  });
533
703
 
534
704
  assert.deepEqual(submitInternalEventCalls[1].args[0], {
@@ -544,20 +714,25 @@ describe('plugin-meetings', () => {
544
714
  options: {
545
715
  meetingId,
546
716
  globalMeetingId: requestResponse.body?.meetingId,
547
- webexConferenceIdStr: confIdStr ? requestResponse.body?.confIdStr : requestResponse.body?.confID,
548
- }
717
+ webexConferenceIdStr: confIdStr
718
+ ? requestResponse.body?.confIdStr
719
+ : requestResponse.body?.confID,
720
+ },
549
721
  });
550
722
  } else {
551
723
  assert.notCalled(webex.internal.newMetrics.submitClientEvent);
552
724
  assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
553
725
  }
554
- })
726
+ });
555
727
  }
556
- )
728
+ );
557
729
 
558
730
  it('should send CA metric if meetingId is provided and send CA events is authorized', async () => {
559
- const requestResponse = {statusCode: 200, body: {meetingKey: '1234323', confID: '123', meetingId: '321'}};
560
- const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'}
731
+ const requestResponse = {
732
+ statusCode: 200,
733
+ body: {meetingKey: '1234323', confID: '123', meetingId: '321'},
734
+ };
735
+ const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
561
736
 
562
737
  webex.request.resolves(requestResponse);
563
738
 
@@ -600,7 +775,7 @@ describe('plugin-meetings', () => {
600
775
  name: 'client.meetinginfo.request',
601
776
  options: {
602
777
  meetingId: 'meetingId',
603
- }
778
+ },
604
779
  });
605
780
 
606
781
  assert.deepEqual(submitInternalEventCalls[1].args[0], {
@@ -617,47 +792,41 @@ describe('plugin-meetings', () => {
617
792
  meetingId: 'meetingId',
618
793
  globalMeetingId: requestResponse.body?.meetingId,
619
794
  webexConferenceIdStr: requestResponse.body?.confID,
620
- }
795
+ },
621
796
  });
622
797
  });
623
798
 
624
- forEach(
625
- [
626
- {sendCAevents: true},
627
- {sendCAevents: false},
628
- ],
629
- ({sendCAevents}) => {
630
- it(`should not send CA metric if meetingId is not provided disregarding if sendCAevents is ${sendCAevents}`, async () => {
631
- const message = 'a message';
632
- const meetingInfoData = 'meeting info';
799
+ forEach([{sendCAevents: true}, {sendCAevents: false}], ({sendCAevents}) => {
800
+ it(`should not send CA metric if meetingId is not provided disregarding if sendCAevents is ${sendCAevents}`, async () => {
801
+ const message = 'a message';
802
+ const meetingInfoData = 'meeting info';
633
803
 
634
- webex.request = sinon.stub().rejects({
635
- statusCode: 403,
636
- body: {message, code: 403102, data: {meetingInfo: meetingInfoData}},
637
- url: 'http://api-url.com',
638
- });
639
- try {
640
- await meetingInfo.fetchMeetingInfo(
641
- '1234323',
642
- DESTINATION_TYPE.MEETING_ID,
643
- 'abc',
644
- {
645
- id: '999',
646
- code: 'aabbcc11',
647
- },
648
- null,
649
- null,
650
- undefined,
651
- {meetingId: undefined, sendCAevents}
652
- );
653
- assert.fail('fetchMeetingInfo should have thrown, but has not done that');
654
- } catch (err) {
655
- assert.notCalled(webex.internal.newMetrics.submitClientEvent);
656
- assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
657
- }
804
+ webex.request = sinon.stub().rejects({
805
+ statusCode: 403,
806
+ body: {message, code: 403102, data: {meetingInfo: meetingInfoData}},
807
+ url: 'http://api-url.com',
658
808
  });
659
- }
660
- );
809
+ try {
810
+ await meetingInfo.fetchMeetingInfo(
811
+ '1234323',
812
+ DESTINATION_TYPE.MEETING_ID,
813
+ 'abc',
814
+ {
815
+ id: '999',
816
+ code: 'aabbcc11',
817
+ },
818
+ null,
819
+ null,
820
+ undefined,
821
+ {meetingId: undefined, sendCAevents}
822
+ );
823
+ assert.fail('fetchMeetingInfo should have thrown, but has not done that');
824
+ } catch (err) {
825
+ assert.notCalled(webex.internal.newMetrics.submitClientEvent);
826
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
827
+ }
828
+ });
829
+ });
661
830
 
662
831
  it('should throw MeetingInfoV2PasswordError for 403 response', async () => {
663
832
  const FAKE_MEETING_INFO = {blablabla: 'some_fake_meeting_info'};
@@ -786,23 +955,24 @@ describe('plugin-meetings', () => {
786
955
  ciUserUuid: conversation.participants.items[1].entryUUID,
787
956
  });
788
957
 
789
- return {invitee}
790
- }
958
+ return {invitee};
959
+ };
791
960
 
792
961
  it('Make a request to /spaceInstant when conversationUrl', async () => {
793
962
  const {invitee} = setup();
794
963
 
795
964
  webex.request.resolves({
796
965
  statusCode: 200,
797
- body: conversation
966
+ body: conversation,
798
967
  });
799
968
 
800
- const result = await meetingInfo.createAdhocSpaceMeeting(conversationUrl,installedOrgID);
969
+ const result = await meetingInfo.createAdhocSpaceMeeting(conversationUrl, installedOrgID);
801
970
 
802
- assert.calledWith(
803
- webex.request,
804
- {uri:conversationUrl, qs: {includeParticipants: true}, disableTransform: true}
805
- )
971
+ assert.calledWith(webex.request, {
972
+ uri: conversationUrl,
973
+ qs: {includeParticipants: true},
974
+ disableTransform: true,
975
+ });
806
976
 
807
977
  assert.calledWith(webex.request, {
808
978
  method: 'POST',
@@ -813,14 +983,15 @@ describe('plugin-meetings', () => {
813
983
  keyUrl: conversation.encryptionKeyUrl,
814
984
  kroUrl: conversation.kmsResourceObjectUrl,
815
985
  invitees: invitee,
816
- installedOrgID: installedOrgID
986
+ installedOrgID: installedOrgID,
987
+ schedule: false,
817
988
  },
818
989
  });
819
990
  assert.calledOnce(Metrics.sendBehavioralMetric);
820
991
  assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS);
821
992
  assert.deepEqual(result, {
822
993
  body: conversation,
823
- statusCode: 200
994
+ statusCode: 200,
824
995
  });
825
996
  });
826
997
  it('Make a request to /spaceInstant when conversationUrl with installed org ID', async () => {
@@ -845,13 +1016,13 @@ describe('plugin-meetings', () => {
845
1016
  kroUrl: conversation.kmsResourceObjectUrl,
846
1017
  invitees: invitee,
847
1018
  installedOrgID,
1019
+ schedule: false,
848
1020
  },
849
1021
  });
850
1022
  assert(Metrics.sendBehavioralMetric.calledOnce);
851
1023
  assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS);
852
1024
  });
853
1025
 
854
-
855
1026
  forEach(
856
1027
  [
857
1028
  {errorCode: 403049},
@@ -885,7 +1056,6 @@ describe('plugin-meetings', () => {
885
1056
  BEHAVIORAL_METRICS.MEETING_INFO_POLICY_ERROR,
886
1057
  {code: errorCode}
887
1058
  );
888
-
889
1059
  }
890
1060
  });
891
1061
  }
@@ -926,47 +1096,40 @@ describe('plugin-meetings', () => {
926
1096
  BEHAVIORAL_METRICS.JOIN_WEBINAR_ERROR,
927
1097
  {code: errorCode}
928
1098
  );
929
-
930
1099
  }
931
1100
  });
932
1101
  }
933
1102
  );
934
1103
 
935
- forEach(
936
- [
937
- {errorCode: 403003},
938
- ],
939
- ({errorCode}) => {
940
- it(`should throw a MeetingInfoV2JoinForbiddenError for error code ${errorCode}`, async () => {
941
- const message = 'a message';
942
- const meetingInfoData = 'meeting info';
1104
+ forEach([{errorCode: 403003}], ({errorCode}) => {
1105
+ it(`should throw a MeetingInfoV2JoinForbiddenError for error code ${errorCode}`, async () => {
1106
+ const message = 'a message';
1107
+ const meetingInfoData = 'meeting info';
943
1108
 
944
- webex.request = sinon.stub().rejects({
945
- statusCode: 403,
946
- body: {message, code: errorCode, data: {meetingInfo: meetingInfoData}},
1109
+ webex.request = sinon.stub().rejects({
1110
+ statusCode: 403,
1111
+ body: {message, code: errorCode, data: {meetingInfo: meetingInfoData}},
1112
+ });
1113
+ try {
1114
+ await meetingInfo.fetchMeetingInfo('1234323', DESTINATION_TYPE.MEETING_ID, 'abc', {
1115
+ id: '999',
1116
+ code: 'aabbcc11',
947
1117
  });
948
- try {
949
- await meetingInfo.fetchMeetingInfo('1234323', DESTINATION_TYPE.MEETING_ID, 'abc', {
950
- id: '999',
951
- code: 'aabbcc11',
952
- });
953
- } catch (err) {
954
- assert.instanceOf(err, MeetingInfoV2JoinForbiddenError);
955
- assert.deepEqual(err.message, `${message}, code=${errorCode}`);
956
- assert.equal(err.wbxAppApiCode, errorCode);
957
- assert.deepEqual(err.meetingInfo, meetingInfoData);
958
-
959
- assert(Metrics.sendBehavioralMetric.calledOnce);
960
- assert.calledWith(
961
- Metrics.sendBehavioralMetric,
962
- BEHAVIORAL_METRICS.JOIN_FORBIDDEN_ERROR,
963
- {code: errorCode}
964
- );
1118
+ } catch (err) {
1119
+ assert.instanceOf(err, MeetingInfoV2JoinForbiddenError);
1120
+ assert.deepEqual(err.message, `${message}, code=${errorCode}`);
1121
+ assert.equal(err.wbxAppApiCode, errorCode);
1122
+ assert.deepEqual(err.meetingInfo, meetingInfoData);
965
1123
 
966
- }
967
- });
968
- }
969
- );
1124
+ assert(Metrics.sendBehavioralMetric.calledOnce);
1125
+ assert.calledWith(
1126
+ Metrics.sendBehavioralMetric,
1127
+ BEHAVIORAL_METRICS.JOIN_FORBIDDEN_ERROR,
1128
+ {code: errorCode}
1129
+ );
1130
+ }
1131
+ });
1132
+ });
970
1133
  });
971
1134
  });
972
1135
  });
@@ -285,7 +285,8 @@ describe('plugin-meetings', () => {
285
285
 
286
286
  describe('failure', () => {
287
287
  it('should not accept non-number input', () => {
288
- const logUploadIntervalMultiplicationFactor = webex.meetings.config.logUploadIntervalMultiplicationFactor;
288
+ const logUploadIntervalMultiplicationFactor =
289
+ webex.meetings.config.logUploadIntervalMultiplicationFactor;
289
290
 
290
291
  webex.meetings._setLogUploadIntervalMultiplicationFactor('test');
291
292
  assert.equal(
@@ -931,6 +932,27 @@ describe('plugin-meetings', () => {
931
932
  });
932
933
  });
933
934
  });
935
+ describe('#enableStaticMeetingLink', () => {
936
+ const conversationUrl = 'conv.fakeconversationurl.com';
937
+
938
+ afterEach(() => {
939
+ sinon.restore();
940
+ });
941
+
942
+ it('should have #enableStaticMeetingLink', () => {
943
+ assert.exists(webex.meetings.enableStaticMeetingLink);
944
+ });
945
+
946
+ it('should call MeetingInfo#enableStaticMeetingLink() with proper params', () => {
947
+ webex.meetings.meetingInfo.enableStaticMeetingLink = sinon
948
+ .stub()
949
+ .resolves(conversationUrl);
950
+
951
+ return webex.meetings.enableStaticMeetingLink(conversationUrl).then(() => {
952
+ assert.calledWith(webex.meetings.meetingInfo.enableStaticMeetingLink, conversationUrl);
953
+ });
954
+ });
955
+ });
934
956
  describe('#create', () => {
935
957
  let infoOptions;
936
958