@webex/plugin-meetings 3.7.0-next.41 → 3.7.0-next.43

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.
@@ -11,3 +11,11 @@ export declare const MEETING_KEY: {
11
11
  readonly CORRELATION_ID: "correlationId";
12
12
  };
13
13
  export type MEETING_KEY = Enum<typeof MEETING_KEY>;
14
+ export type MeetingRegistrationStatus = {
15
+ fetchWebexSite: boolean;
16
+ getGeoHint: boolean;
17
+ startReachability: boolean;
18
+ deviceRegister: boolean;
19
+ mercuryConnect: boolean;
20
+ checkH264Support: boolean;
21
+ };
@@ -458,7 +458,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
458
458
  }, _callee7);
459
459
  }))();
460
460
  },
461
- version: "3.7.0-next.41"
461
+ version: "3.7.0-next.43"
462
462
  });
463
463
  var _default = exports.default = Webinar;
464
464
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.7.0-next.41",
46
+ "@webex/plugin-meetings": "3.7.0-next.43",
47
47
  "@webex/plugin-rooms": "3.7.0-next.17",
48
48
  "@webex/test-helper-chai": "3.7.0-next.12",
49
49
  "@webex/test-helper-mocha": "3.7.0-next.12",
@@ -71,7 +71,7 @@
71
71
  "@webex/internal-plugin-metrics": "3.7.0-next.12",
72
72
  "@webex/internal-plugin-support": "3.7.0-next.18",
73
73
  "@webex/internal-plugin-user": "3.7.0-next.12",
74
- "@webex/internal-plugin-voicea": "3.7.0-next.41",
74
+ "@webex/internal-plugin-voicea": "3.7.0-next.43",
75
75
  "@webex/media-helpers": "3.7.0-next.16",
76
76
  "@webex/plugin-people": "3.7.0-next.15",
77
77
  "@webex/plugin-rooms": "3.7.0-next.17",
@@ -92,5 +92,5 @@
92
92
  "//": [
93
93
  "TODO: upgrade jwt-decode when moving to node 18"
94
94
  ],
95
- "version": "3.7.0-next.41"
95
+ "version": "3.7.0-next.43"
96
96
  }
package/src/constants.ts CHANGED
@@ -1389,3 +1389,12 @@ export const DESTINATION_TYPE = {
1389
1389
  } as const;
1390
1390
 
1391
1391
  export type DESTINATION_TYPE = Enum<typeof DESTINATION_TYPE>;
1392
+
1393
+ export const INITIAL_REGISTRATION_STATUS = {
1394
+ fetchWebexSite: false,
1395
+ getGeoHint: false,
1396
+ startReachability: false,
1397
+ deviceRegister: false,
1398
+ mercuryConnect: false,
1399
+ checkH264Support: false,
1400
+ };
@@ -1,5 +1,5 @@
1
1
  /* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
2
- import {cloneDeep} from 'lodash';
2
+ import {cloneDeep, clone} from 'lodash';
3
3
  import '@webex/internal-plugin-mercury';
4
4
  import '@webex/internal-plugin-conversation';
5
5
  import '@webex/internal-plugin-metrics';
@@ -42,6 +42,7 @@ import {
42
42
  _ON_HOLD_LOBBY_,
43
43
  _WAIT_,
44
44
  DESTINATION_TYPE,
45
+ INITIAL_REGISTRATION_STATUS,
45
46
  } from '../constants';
46
47
  import BEHAVIORAL_METRICS from '../metrics/constants';
47
48
  import MeetingInfo from '../meeting-info';
@@ -53,7 +54,12 @@ import Request from './request';
53
54
  import PasswordError from '../common/errors/password-error';
54
55
  import CaptchaError from '../common/errors/captcha-error';
55
56
  import MeetingCollection from './collection';
56
- import {MEETING_KEY, INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
57
+ import {
58
+ MEETING_KEY,
59
+ INoiseReductionEffect,
60
+ IVirtualBackgroundEffect,
61
+ MeetingRegistrationStatus,
62
+ } from './meetings.types';
57
63
  import MeetingsUtil from './util';
58
64
  import PermissionError from '../common/errors/permission';
59
65
  import JoinWebinarError from '../common/errors/join-webinar-error';
@@ -179,6 +185,7 @@ export default class Meetings extends WebexPlugin {
179
185
  mediaHelpers: any;
180
186
  breakoutLocusForHandleLater: any;
181
187
  namespace = MEETINGS;
188
+ registrationStatus: MeetingRegistrationStatus;
182
189
 
183
190
  /**
184
191
  * Initializes the Meetings Plugin
@@ -785,6 +792,18 @@ export default class Meetings extends WebexPlugin {
785
792
  }
786
793
  }
787
794
 
795
+ /**
796
+ * Executes a registration step and updates the registration status.
797
+ * @param {Function} step - The registration step to execute.
798
+ * @param {string} stepName - The name of the registration step.
799
+ * @returns {Promise} A promise that resolves when the step is completed.
800
+ */
801
+ executeRegistrationStep(step: () => Promise<any>, stepName: string) {
802
+ return step().then(() => {
803
+ this.registrationStatus[stepName] = true;
804
+ });
805
+ }
806
+
788
807
  /**
789
808
  * Explicitly sets up the meetings plugin by registering
790
809
  * the device, connecting to mercury, and listening for locus events.
@@ -795,6 +814,8 @@ export default class Meetings extends WebexPlugin {
795
814
  * @memberof Meetings
796
815
  */
797
816
  public register(deviceRegistrationOptions?: DeviceRegistrationOptions): Promise<any> {
817
+ this.registrationStatus = clone(INITIAL_REGISTRATION_STATUS);
818
+
798
819
  // @ts-ignore
799
820
  if (!this.webex.canAuthorize) {
800
821
  LoggerProxy.logger.error(
@@ -813,24 +834,39 @@ export default class Meetings extends WebexPlugin {
813
834
  }
814
835
 
815
836
  return Promise.all([
816
- this.fetchUserPreferredWebexSite(),
817
- this.getGeoHint(),
818
- this.startReachability('registration').catch((error) => {
819
- LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
820
- }),
821
- // @ts-ignore
822
- this.webex.internal.device
823
- .register(deviceRegistrationOptions)
824
- // @ts-ignore
825
- .then(() =>
826
- LoggerProxy.logger.info(
837
+ this.executeRegistrationStep(() => this.fetchUserPreferredWebexSite(), 'fetchWebexSite'),
838
+ this.executeRegistrationStep(() => this.getGeoHint(), 'getGeoHint'),
839
+ this.executeRegistrationStep(
840
+ () =>
841
+ this.startReachability('registration').catch((error) => {
842
+ LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
843
+ }),
844
+ 'startReachability'
845
+ ),
846
+ this.executeRegistrationStep(
847
+ () =>
848
+ // @ts-ignore
849
+ this.webex.internal.device
850
+ .register(deviceRegistrationOptions)
827
851
  // @ts-ignore
828
- `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
829
- )
852
+ .then(() => {
853
+ LoggerProxy.logger.info(
854
+ // @ts-ignore
855
+ `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
856
+ );
857
+ }),
858
+ 'deviceRegister'
859
+ ).then(() =>
860
+ this.executeRegistrationStep(
861
+ // @ts-ignore
862
+ () => this.webex.internal.mercury.connect(),
863
+ 'mercuryConnect'
830
864
  )
831
- // @ts-ignore
832
- .then(() => this.webex.internal.mercury.connect()),
833
- MeetingsUtil.checkH264Support.call(this),
865
+ ),
866
+ this.executeRegistrationStep(
867
+ () => Promise.resolve(MeetingsUtil.checkH264Support.call(this)),
868
+ 'checkH264Support'
869
+ ),
834
870
  ])
835
871
  .then(() => {
836
872
  this.listenForEvents();
@@ -894,6 +930,7 @@ export default class Meetings extends WebexPlugin {
894
930
  EVENT_TRIGGERS.MEETINGS_UNREGISTERED
895
931
  );
896
932
  this.registered = false;
933
+ this.registrationStatus = clone(INITIAL_REGISTRATION_STATUS);
897
934
  })
898
935
  );
899
936
  }
@@ -21,3 +21,13 @@ export const MEETING_KEY = {
21
21
  } as const;
22
22
 
23
23
  export type MEETING_KEY = Enum<typeof MEETING_KEY>;
24
+
25
+ // finer grained status for registration steps
26
+ export type MeetingRegistrationStatus = {
27
+ fetchWebexSite: boolean;
28
+ getGeoHint: boolean;
29
+ startReachability: boolean;
30
+ deviceRegister: boolean;
31
+ mercuryConnect: boolean;
32
+ checkH264Support: boolean;
33
+ };
@@ -37,6 +37,7 @@ import {
37
37
  LOCUSINFO,
38
38
  EVENT_TRIGGERS,
39
39
  DESTINATION_TYPE,
40
+ INITIAL_REGISTRATION_STATUS,
40
41
  } from '../../../../src/constants';
41
42
  import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
42
43
  import {forEach} from 'lodash';
@@ -375,21 +376,21 @@ describe('plugin-meetings', () => {
375
376
  assert.isTrue(webex.meetings.registered);
376
377
  });
377
378
 
378
- it('rejects when SDK canAuthorize is false', () => {
379
+ it('rejects when SDK canAuthorize is false', async () => {
379
380
  webex.canAuthorize = false;
380
- assert.isRejected(webex.meetings.register());
381
+ await assert.isRejected(webex.meetings.register());
381
382
  });
382
383
 
383
- it('rejects when device.register fails', () => {
384
+ it('rejects when device.register fails', async () => {
384
385
  webex.canAuthorize = true;
385
386
  webex.internal.device.register = sinon.stub().returns(Promise.reject());
386
- assert.isRejected(webex.meetings.register());
387
+ await assert.isRejected(webex.meetings.register());
387
388
  });
388
389
 
389
- it('rejects when mercury.connect fails', () => {
390
+ it('rejects when mercury.connect fails', async () => {
390
391
  webex.canAuthorize = true;
391
392
  webex.internal.mercury.connect = sinon.stub().returns(Promise.reject());
392
- assert.isRejected(webex.meetings.register());
393
+ await assert.isRejected(webex.meetings.register());
393
394
  });
394
395
 
395
396
  it('resolves immediately if already registered', async () => {
@@ -420,6 +421,100 @@ describe('plugin-meetings', () => {
420
421
  includeDetails: CatalogDetails.features,
421
422
  });
422
423
  });
424
+
425
+ it('updates registration status as expected', async () => {
426
+ const clock = sinon.useFakeTimers();
427
+
428
+ const delay = (secs) => () =>
429
+ new Promise((resolve) => {
430
+ setTimeout(resolve, secs * 1000);
431
+ });
432
+
433
+ let i = 1;
434
+ sinon.stub(webex.meetings, 'fetchUserPreferredWebexSite').callsFake(delay(i++));
435
+ MeetingsUtil.checkH264Support.callsFake(delay(i++));
436
+ webex.meetings.startReachability.callsFake(delay(i++));
437
+ webex.internal.device.register.callsFake(delay(i++));
438
+ sinon.stub(webex.meetings, 'getGeoHint').callsFake(delay(i++));
439
+ webex.internal.mercury.connect.callsFake(delay(i++));
440
+
441
+ webex.canAuthorize = true;
442
+ webex.meetings.registered = false;
443
+
444
+ const registerPromise = webex.meetings.register({
445
+ includeDetails: CatalogDetails.features,
446
+ });
447
+
448
+ await clock.tick(1000);
449
+ await webex.meetings.fetchUserPreferredWebexSite;
450
+ assert.deepEqual(webex.meetings.registrationStatus, {
451
+ fetchWebexSite: true,
452
+ getGeoHint: false,
453
+ startReachability: false,
454
+ deviceRegister: false,
455
+ mercuryConnect: false,
456
+ checkH264Support: false,
457
+ });
458
+
459
+ await clock.tick(1000);
460
+ await MeetingsUtil.checkH264Support;
461
+ assert.deepEqual(webex.meetings.registrationStatus, {
462
+ fetchWebexSite: true,
463
+ getGeoHint: false,
464
+ startReachability: false,
465
+ deviceRegister: false,
466
+ mercuryConnect: false,
467
+ checkH264Support: true,
468
+ });
469
+
470
+ await clock.tick(1000);
471
+ await webex.meetings.startReachability;
472
+ assert.deepEqual(webex.meetings.registrationStatus, {
473
+ fetchWebexSite: true,
474
+ getGeoHint: false,
475
+ startReachability: true,
476
+ deviceRegister: false,
477
+ mercuryConnect: false,
478
+ checkH264Support: true,
479
+ });
480
+
481
+ await clock.tick(1000);
482
+ await webex.internal.device.register;
483
+ assert.deepEqual(webex.meetings.registrationStatus, {
484
+ fetchWebexSite: true,
485
+ getGeoHint: false,
486
+ startReachability: true,
487
+ deviceRegister: true,
488
+ mercuryConnect: false,
489
+ checkH264Support: true,
490
+ });
491
+
492
+ await clock.tick(1000);
493
+ await webex.meetings.getGeoHint;
494
+ assert.deepEqual(webex.meetings.registrationStatus, {
495
+ fetchWebexSite: true,
496
+ getGeoHint: true,
497
+ startReachability: true,
498
+ deviceRegister: true,
499
+ mercuryConnect: false,
500
+ checkH264Support: true,
501
+ });
502
+
503
+ await clock.tick(6000);
504
+ await webex.internal.mercury.connect;
505
+ assert.deepEqual(webex.meetings.registrationStatus, {
506
+ fetchWebexSite: true,
507
+ getGeoHint: true,
508
+ startReachability: true,
509
+ deviceRegister: true,
510
+ mercuryConnect: true,
511
+ checkH264Support: true,
512
+ });
513
+
514
+ await registerPromise;
515
+
516
+ clock.restore();
517
+ });
423
518
  });
424
519
 
425
520
  describe('#unregister', () => {
@@ -440,27 +535,36 @@ describe('plugin-meetings', () => {
440
535
  });
441
536
  });
442
537
 
443
- it('rejects when device.unregister fails', () => {
538
+ it('rejects when device.unregister fails', async () => {
444
539
  webex.meetings.registered = true;
445
540
  webex.internal.device.unregister = sinon.stub().returns(Promise.reject());
446
- assert.isRejected(webex.meetings.unregister());
541
+ await assert.isRejected(webex.meetings.unregister());
447
542
  });
448
543
 
449
- it('rejects when mercury.disconnect fails', () => {
544
+ it('rejects when mercury.disconnect fails', async () => {
450
545
  webex.meetings.registered = true;
451
546
  webex.internal.mercury.disconnect = sinon.stub().returns(Promise.reject());
452
- assert.isRejected(webex.meetings.unregister());
547
+ await assert.isRejected(webex.meetings.unregister());
453
548
  });
454
549
 
455
- it('resolves immediately if already registered', (done) => {
550
+ it('resolves immediately if not registered', (done) => {
456
551
  webex.meetings.registered = false;
457
552
  webex.meetings.unregister().then(() => {
458
- assert.notCalled(webex.internal.device.register);
459
- assert.notCalled(webex.internal.mercury.connect);
553
+ assert.notCalled(webex.internal.device.unregister);
554
+ assert.notCalled(webex.internal.mercury.disconnect);
460
555
  assert.isFalse(webex.meetings.registered);
461
556
  done();
462
557
  });
463
558
  });
559
+
560
+ it('resets registration status', (done) => {
561
+ webex.meetings.registered = true;
562
+ webex.meetings.registrationStatus = {foo: 'bar'};
563
+ webex.meetings.unregister().then(() => {
564
+ assert.deepEqual(webex.meetings.registrationStatus, INITIAL_REGISTRATION_STATUS);
565
+ done();
566
+ });
567
+ });
464
568
  });
465
569
 
466
570
  describe('virtual background effect', () => {