@webex/plugin-meetings 3.5.0-next.2 → 3.5.0-next.21

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.
Files changed (35) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +1 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/interpretation/index.js +1 -1
  6. package/dist/interpretation/siLanguage.js +1 -1
  7. package/dist/media/index.js.map +1 -1
  8. package/dist/meeting/in-meeting-actions.js +3 -1
  9. package/dist/meeting/in-meeting-actions.js.map +1 -1
  10. package/dist/meeting/index.js +6 -3
  11. package/dist/meeting/index.js.map +1 -1
  12. package/dist/meetings/index.js +71 -21
  13. package/dist/meetings/index.js.map +1 -1
  14. package/dist/types/constants.d.ts +2 -1
  15. package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
  16. package/dist/types/meetings/index.d.ts +26 -1
  17. package/dist/webinar/index.js +1 -1
  18. package/package.json +22 -22
  19. package/src/constants.ts +1 -0
  20. package/src/media/index.ts +1 -1
  21. package/src/meeting/in-meeting-actions.ts +3 -0
  22. package/src/meeting/index.ts +6 -2
  23. package/src/meetings/index.ts +91 -32
  24. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
  25. package/test/unit/spec/meeting/index.js +11 -8
  26. package/test/unit/spec/meetings/index.js +100 -9
  27. package/dist/rtcMetrics/constants.js +0 -11
  28. package/dist/rtcMetrics/constants.js.map +0 -1
  29. package/dist/rtcMetrics/index.js +0 -197
  30. package/dist/rtcMetrics/index.js.map +0 -1
  31. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  32. package/dist/types/rtcMetrics/index.d.ts +0 -71
  33. package/src/rtcMetrics/constants.ts +0 -3
  34. package/src/rtcMetrics/index.ts +0 -186
  35. package/test/unit/spec/rtcMetrics/index.ts +0 -154
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
62
62
  updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
63
63
  this.set('canManageWebcast', canManageWebcast);
64
64
  },
65
- version: "3.5.0-next.2"
65
+ version: "3.5.0-next.21"
66
66
  });
67
67
  var _default = exports.default = Webinar;
68
68
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,13 +43,13 @@
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.5.0-next.2",
47
- "@webex/plugin-rooms": "3.5.0-next.2",
48
- "@webex/test-helper-chai": "3.5.0-next.2",
49
- "@webex/test-helper-mocha": "3.5.0-next.2",
50
- "@webex/test-helper-mock-webex": "3.5.0-next.2",
51
- "@webex/test-helper-retry": "3.5.0-next.2",
52
- "@webex/test-helper-test-users": "3.5.0-next.2",
46
+ "@webex/plugin-meetings": "3.5.0-next.21",
47
+ "@webex/plugin-rooms": "3.5.0-next.17",
48
+ "@webex/test-helper-chai": "3.5.0-next.15",
49
+ "@webex/test-helper-mocha": "3.5.0-next.15",
50
+ "@webex/test-helper-mock-webex": "3.5.0-next.15",
51
+ "@webex/test-helper-retry": "3.5.0-next.15",
52
+ "@webex/test-helper-test-users": "3.5.0-next.15",
53
53
  "chai": "^4.3.4",
54
54
  "chai-as-promised": "^7.1.1",
55
55
  "eslint": "^8.24.0",
@@ -61,21 +61,21 @@
61
61
  "typescript": "^4.7.4"
62
62
  },
63
63
  "dependencies": {
64
- "@webex/common": "3.5.0-next.2",
65
- "@webex/internal-media-core": "2.11.1",
66
- "@webex/internal-plugin-conversation": "3.5.0-next.2",
67
- "@webex/internal-plugin-device": "3.5.0-next.2",
68
- "@webex/internal-plugin-llm": "3.5.0-next.2",
69
- "@webex/internal-plugin-mercury": "3.5.0-next.2",
70
- "@webex/internal-plugin-metrics": "3.5.0-next.2",
71
- "@webex/internal-plugin-support": "3.5.0-next.2",
72
- "@webex/internal-plugin-user": "3.5.0-next.2",
73
- "@webex/internal-plugin-voicea": "3.5.0-next.2",
74
- "@webex/media-helpers": "3.5.0-next.2",
75
- "@webex/plugin-people": "3.5.0-next.2",
76
- "@webex/plugin-rooms": "3.5.0-next.2",
64
+ "@webex/common": "3.5.0-next.15",
65
+ "@webex/internal-media-core": "2.11.3",
66
+ "@webex/internal-plugin-conversation": "3.5.0-next.17",
67
+ "@webex/internal-plugin-device": "3.5.0-next.15",
68
+ "@webex/internal-plugin-llm": "3.5.0-next.15",
69
+ "@webex/internal-plugin-mercury": "3.5.0-next.15",
70
+ "@webex/internal-plugin-metrics": "3.5.0-next.15",
71
+ "@webex/internal-plugin-support": "3.5.0-next.17",
72
+ "@webex/internal-plugin-user": "3.5.0-next.15",
73
+ "@webex/internal-plugin-voicea": "3.5.0-next.21",
74
+ "@webex/media-helpers": "3.5.0-next.16",
75
+ "@webex/plugin-people": "3.5.0-next.15",
76
+ "@webex/plugin-rooms": "3.5.0-next.17",
77
77
  "@webex/web-capabilities": "^1.4.0",
78
- "@webex/webex-core": "3.5.0-next.2",
78
+ "@webex/webex-core": "3.5.0-next.15",
79
79
  "ampersand-collection": "^2.0.2",
80
80
  "bowser": "^2.11.0",
81
81
  "btoa": "^1.2.1",
@@ -91,5 +91,5 @@
91
91
  "//": [
92
92
  "TODO: upgrade jwt-decode when moving to node 18"
93
93
  ],
94
- "version": "3.5.0-next.2"
94
+ "version": "3.5.0-next.21"
95
95
  }
package/src/constants.ts CHANGED
@@ -879,6 +879,7 @@ export enum SELF_POLICY {
879
879
  SUPPORT_HDV = 'supportHDV',
880
880
  SUPPORT_PARTICIPANT_LIST = 'supportParticipantList',
881
881
  SUPPORT_VOIP = 'supportVoIP',
882
+ SUPPORT_POLLING_AND_QA = 'supportPollingAndQA',
882
883
  }
883
884
 
884
885
  export const DISPLAY_HINTS = {
@@ -15,12 +15,12 @@ import {
15
15
  LocalSystemAudioStream,
16
16
  LocalMicrophoneStream,
17
17
  } from '@webex/media-helpers';
18
+ import {RtcMetrics} from '@webex/internal-plugin-metrics';
18
19
  import LoggerProxy from '../common/logs/logger-proxy';
19
20
  import {MEDIA_TRACK_CONSTRAINT} from '../constants';
20
21
  import Config from '../config';
21
22
  import StaticConfig from '../common/config';
22
23
  import BrowserDetection from '../common/browser-detection';
23
- import RtcMetrics from '../rtcMetrics';
24
24
 
25
25
  const {isBrowser} = BrowserDetection();
26
26
 
@@ -82,6 +82,7 @@ interface IInMeetingActions {
82
82
  supportHDV?: boolean;
83
83
  canShareWhiteBoard?: boolean;
84
84
  enforceVirtualBackground?: boolean;
85
+ canPollingAndQA?: boolean;
85
86
  }
86
87
 
87
88
  /**
@@ -236,6 +237,7 @@ export default class InMeetingActions implements IInMeetingActions {
236
237
 
237
238
  canShareWhiteBoard = null;
238
239
 
240
+ canPollingAndQA = null;
239
241
  /**
240
242
  * Returns all meeting action options
241
243
  * @returns {Object}
@@ -314,6 +316,7 @@ export default class InMeetingActions implements IInMeetingActions {
314
316
  supportHQV: this.supportHQV,
315
317
  supportHDV: this.supportHDV,
316
318
  canShareWhiteBoard: this.canShareWhiteBoard,
319
+ canPollingAndQA: this.canPollingAndQA,
317
320
  });
318
321
 
319
322
  /**
@@ -10,6 +10,7 @@ import {
10
10
  ClientEventLeaveReason,
11
11
  CallDiagnosticUtils,
12
12
  CALL_DIAGNOSTIC_CONFIG,
13
+ RtcMetrics,
13
14
  } from '@webex/internal-plugin-metrics';
14
15
  import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
15
16
 
@@ -155,7 +156,6 @@ import ControlsOptionsManager from '../controls-options-manager';
155
156
  import PermissionError from '../common/errors/permission';
156
157
  import {LocusMediaRequest} from './locusMediaRequest';
157
158
  import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
158
- import RtcMetrics from '../rtcMetrics';
159
159
 
160
160
  // default callback so we don't call an undefined function, but in practice it should never be used
161
161
  const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
@@ -1604,7 +1604,7 @@ export default class Meeting extends StatelessWebexPlugin {
1604
1604
  * @returns {string}
1605
1605
  */
1606
1606
  get sessionCorrelationId() {
1607
- return this.callStateForMetrics.correlationId;
1607
+ return this.callStateForMetrics.sessionCorrelationId;
1608
1608
  }
1609
1609
 
1610
1610
  /**
@@ -3826,6 +3826,10 @@ export default class Meeting extends StatelessWebexPlugin {
3826
3826
  requiredPolicies: [SELF_POLICY.SUPPORT_CHAT],
3827
3827
  policies: this.selfUserPolicies,
3828
3828
  }),
3829
+ canPollingAndQA: ControlsOptionsUtil.hasPolicies({
3830
+ requiredPolicies: [SELF_POLICY.SUPPORT_POLLING_AND_QA],
3831
+ policies: this.selfUserPolicies,
3832
+ }),
3829
3833
  canShareApplication:
3830
3834
  (ControlsOptionsUtil.hasHints({
3831
3835
  requiredHints: [DISPLAY_HINTS.SHARE_APPLICATION],
@@ -1,11 +1,12 @@
1
1
  /* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
2
- import {union} from 'lodash';
2
+ import {cloneDeep} from 'lodash';
3
3
  import '@webex/internal-plugin-mercury';
4
4
  import '@webex/internal-plugin-conversation';
5
5
  import '@webex/internal-plugin-metrics';
6
6
  // @ts-ignore
7
7
  import {WebexPlugin} from '@webex/webex-core';
8
8
  import {setLogger} from '@webex/internal-media-core';
9
+ import {DeviceRegistrationOptions} from '@webex/internal-plugin-device';
9
10
 
10
11
  import * as mediaHelpersModule from '@webex/media-helpers';
11
12
 
@@ -133,6 +134,21 @@ class MediaLogger {
133
134
  * @memberof Meetings
134
135
  */
135
136
 
137
+ /**
138
+ * Object containing only the most basic information about a meeting.
139
+ * This is the information that is kept even after the meeting is deleted from the MeetingCollection
140
+ */
141
+ export type BasicMeetingInformation = {
142
+ allowMediaInLobby: boolean;
143
+ correlationId: string;
144
+ environment: string;
145
+ id: string;
146
+ locusUrl: string;
147
+ locusInfo: any; // it's only a very small subset of the locus info, see what's populated in the destroy() method
148
+ meetingInfo: any;
149
+ sessionCorrelationId: string;
150
+ };
151
+
136
152
  /**
137
153
  * Maintain a cache of meetings and sync with services.
138
154
  * @class
@@ -141,6 +157,7 @@ export default class Meetings extends WebexPlugin {
141
157
  loggerRequest: any;
142
158
  media: any;
143
159
  meetingCollection: any;
160
+ deletedMeetings: Map<string, BasicMeetingInformation>;
144
161
  personalMeetingRoom: any;
145
162
  preferredWebexSite: any;
146
163
  reachability: Reachability;
@@ -191,6 +208,8 @@ export default class Meetings extends WebexPlugin {
191
208
  // @ts-ignore
192
209
  this.loggerRequest = new LoggerRequest({webex: this.webex});
193
210
  this.meetingCollection = new MeetingCollection();
211
+ this.deletedMeetings = new Map();
212
+
194
213
  /**
195
214
  * The PersonalMeetingRoom object to interact with server
196
215
  * @instance
@@ -740,11 +759,12 @@ export default class Meetings extends WebexPlugin {
740
759
  * Explicitly sets up the meetings plugin by registering
741
760
  * the device, connecting to mercury, and listening for locus events.
742
761
  *
762
+ * @param {DeviceRegistrationOptions} [deviceRegistrationOptions] - The options for registering the device (optional)
743
763
  * @returns {Promise}
744
764
  * @public
745
765
  * @memberof Meetings
746
766
  */
747
- public register() {
767
+ public register(deviceRegistrationOptions?: DeviceRegistrationOptions): Promise<any> {
748
768
  // @ts-ignore
749
769
  if (!this.webex.canAuthorize) {
750
770
  LoggerProxy.logger.error(
@@ -770,7 +790,7 @@ export default class Meetings extends WebexPlugin {
770
790
  }),
771
791
  // @ts-ignore
772
792
  this.webex.internal.device
773
- .register()
793
+ .register(deviceRegistrationOptions)
774
794
  // @ts-ignore
775
795
  .then(() =>
776
796
  LoggerProxy.logger.info(
@@ -996,35 +1016,45 @@ export default class Meetings extends WebexPlugin {
996
1016
  * @memberof Meetings
997
1017
  */
998
1018
  fetchUserPreferredWebexSite() {
999
- return this.request.getMeetingPreferences().then((res) => {
1000
- if (res) {
1001
- const preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
1002
- this.preferredWebexSite = preferredWebexSite;
1003
- // @ts-ignore
1004
- this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
1005
- }
1019
+ // @ts-ignore
1020
+ return this.webex.people._getMe().then((me) => {
1021
+ const isGuestUser = me.type === 'appuser';
1022
+ if (!isGuestUser) {
1023
+ return this.request.getMeetingPreferences().then((res) => {
1024
+ if (res) {
1025
+ const preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
1026
+ this.preferredWebexSite = preferredWebexSite;
1027
+ // @ts-ignore
1028
+ this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
1029
+ }
1006
1030
 
1007
- // fall back to getting the preferred site from the user information
1008
- if (!this.preferredWebexSite) {
1009
- // @ts-ignore
1010
- return this.webex.internal.user
1011
- .get()
1012
- .then((user) => {
1013
- const preferredWebexSite =
1014
- user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
1015
- if (preferredWebexSite) {
1016
- this.preferredWebexSite = preferredWebexSite;
1017
- // @ts-ignore
1018
- this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
1019
- } else {
1020
- throw new Error('site not found');
1021
- }
1022
- })
1023
- .catch(() => {
1024
- LoggerProxy.logger.error(
1025
- 'Failed to fetch preferred site from user - no site will be set'
1026
- );
1027
- });
1031
+ // fall back to getting the preferred site from the user information
1032
+ if (!this.preferredWebexSite) {
1033
+ // @ts-ignore
1034
+ return this.webex.internal.user
1035
+ .get()
1036
+ .then((user) => {
1037
+ const preferredWebexSite =
1038
+ user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
1039
+ if (preferredWebexSite) {
1040
+ this.preferredWebexSite = preferredWebexSite;
1041
+ // @ts-ignore
1042
+ this.webex.internal.services
1043
+ ._getCatalog()
1044
+ .addAllowedDomains([preferredWebexSite]);
1045
+ } else {
1046
+ throw new Error('site not found');
1047
+ }
1048
+ })
1049
+ .catch(() => {
1050
+ LoggerProxy.logger.error(
1051
+ 'Failed to fetch preferred site from user - no site will be set'
1052
+ );
1053
+ });
1054
+ }
1055
+
1056
+ return Promise.resolve();
1057
+ });
1028
1058
  }
1029
1059
 
1030
1060
  return Promise.resolve();
@@ -1037,11 +1067,21 @@ export default class Meetings extends WebexPlugin {
1037
1067
  * @public
1038
1068
  * @memberof Meetings
1039
1069
  */
1040
-
1041
1070
  getPersonalMeetingRoom() {
1042
1071
  return this.personalMeetingRoom;
1043
1072
  }
1044
1073
 
1074
+ /**
1075
+ * Returns basic information about a meeting that exists or
1076
+ * used to exist in the MeetingCollection
1077
+ *
1078
+ * @param {string} meetingId
1079
+ * @returns {BasicMeetingInformation|undefined}
1080
+ */
1081
+ public getBasicMeetingInformation(meetingId: string): BasicMeetingInformation {
1082
+ return this.meetingCollection.get(meetingId) || this.deletedMeetings.get(meetingId);
1083
+ }
1084
+
1045
1085
  /**
1046
1086
  * @param {Meeting} meeting
1047
1087
  * @param {Object} reason
@@ -1052,6 +1092,25 @@ export default class Meetings extends WebexPlugin {
1052
1092
  */
1053
1093
  private destroy(meeting: Meeting, reason: object) {
1054
1094
  MeetingUtil.cleanUp(meeting);
1095
+ // keep some basic info about the deleted meeting forever
1096
+ this.deletedMeetings.set(meeting.id, {
1097
+ id: meeting.id,
1098
+ allowMediaInLobby: meeting.allowMediaInLobby,
1099
+ correlationId: meeting.correlationId,
1100
+ sessionCorrelationId: meeting.sessionCorrelationId,
1101
+ environment: meeting.environment,
1102
+ locusUrl: meeting.locusUrl,
1103
+ meetingInfo: cloneDeep(meeting.meetingInfo),
1104
+ locusInfo: {
1105
+ // locusInfo can be quite big, so keep just the minimal info
1106
+ sequence: meeting.locusInfo?.sequence,
1107
+ url: meeting.locusInfo?.url,
1108
+ fullState: {
1109
+ lastActive: meeting.locusInfo?.fullState?.lastActive,
1110
+ sessionId: meeting.locusInfo?.fullState?.sessionId,
1111
+ },
1112
+ },
1113
+ });
1055
1114
  this.meetingCollection.delete(meeting.id);
1056
1115
  Trigger.trigger(
1057
1116
  this,
@@ -78,6 +78,7 @@ describe('plugin-meetings', () => {
78
78
  supportHDV: null,
79
79
  canShareWhiteBoard: null,
80
80
  enforceVirtualBackground: null,
81
+ canPollingAndQA: null,
81
82
  ...expected,
82
83
  };
83
84
 
@@ -161,6 +162,7 @@ describe('plugin-meetings', () => {
161
162
  'supportHDV',
162
163
  'canShareWhiteBoard',
163
164
  'enforceVirtualBackground',
165
+ 'canPollingAndQA',
164
166
  ].forEach((key) => {
165
167
  it(`get and set for ${key} work as expected`, () => {
166
168
  const inMeetingActions = new InMeetingActions();
@@ -5,7 +5,6 @@ import 'jsdom-global/register';
5
5
  import {cloneDeep, forEach, isEqual, isUndefined} from 'lodash';
6
6
  import sinon from 'sinon';
7
7
  import * as InternalMediaCoreModule from '@webex/internal-media-core';
8
- import * as RtcMetricsModule from '@webex/plugin-meetings/src/rtcMetrics';
9
8
  import * as RemoteMediaManagerModule from '@webex/plugin-meetings/src/multistream/remoteMediaManager';
10
9
  import StateMachine from 'javascript-state-machine';
11
10
  import uuid from 'uuid';
@@ -428,6 +427,7 @@ describe('plugin-meetings', () => {
428
427
  }
429
428
  );
430
429
  assert.exists(newMeeting.sessionCorrelationId);
430
+ assert.equal(newMeeting.sessionCorrelationId, uuid1);
431
431
  assert.deepEqual(newMeeting.callStateForMetrics, {
432
432
  correlationId: uuid4,
433
433
  sessionCorrelationId: uuid1,
@@ -2486,8 +2486,8 @@ describe('plugin-meetings', () => {
2486
2486
  });
2487
2487
 
2488
2488
  it('should create rtcMetrics and pass them to Media.createMediaConnection()', async () => {
2489
- const fakeRtcMetrics = {id: 'fake rtc metrics object'};
2490
- const rtcMetricsCtor = sinon.stub(RtcMetricsModule, 'default').returns(fakeRtcMetrics);
2489
+ const setIntervalOriginal = window.setInterval;
2490
+ window.setInterval = sinon.stub().returns(1);
2491
2491
 
2492
2492
  // setup the minimum mocks required for multistream connection
2493
2493
  fakeMediaConnection.createSendSlot = sinon.stub().returns({
@@ -2508,8 +2508,6 @@ describe('plugin-meetings', () => {
2508
2508
  mediaSettings: {},
2509
2509
  });
2510
2510
 
2511
- assert.calledOnceWithExactly(rtcMetricsCtor, webex, meeting.id, meeting.correlationId);
2512
-
2513
2511
  // check that rtcMetrics was passed to Media.createMediaConnection
2514
2512
  assert.calledOnce(Media.createMediaConnection);
2515
2513
  assert.calledWith(
@@ -2517,10 +2515,10 @@ describe('plugin-meetings', () => {
2517
2515
  true,
2518
2516
  meeting.getMediaConnectionDebugId(),
2519
2517
  meeting.id,
2520
- sinon.match({
2521
- rtcMetrics: fakeRtcMetrics,
2522
- })
2518
+ sinon.match.hasNested('rtcMetrics.webex', webex)
2523
2519
  );
2520
+
2521
+ window.setInterval = setIntervalOriginal;
2524
2522
  });
2525
2523
 
2526
2524
  it('should pass the turn server info to the peer connection', async () => {
@@ -9870,6 +9868,11 @@ describe('plugin-meetings', () => {
9870
9868
  requiredDisplayHints: [],
9871
9869
  requiredPolicies: [SELF_POLICY.SUPPORT_ANNOTATION],
9872
9870
  },
9871
+ {
9872
+ actionName: 'canPollingAndQA',
9873
+ requiredDisplayHints: [],
9874
+ requiredPolicies: [SELF_POLICY.SUPPORT_POLLING_AND_QA],
9875
+ },
9873
9876
  ],
9874
9877
  ({
9875
9878
  actionName,
@@ -8,6 +8,7 @@ import {Crypto} from '@peculiar/webcrypto';
8
8
  global.crypto = new Crypto();
9
9
 
10
10
  import Device from '@webex/internal-plugin-device';
11
+ import {CatalogDetails} from '@webex/internal-plugin-device';
11
12
  import Mercury from '@webex/internal-plugin-mercury';
12
13
  import {assert} from '@webex/test-helper-chai';
13
14
  import MockWebex from '@webex/test-helper-mock-webex';
@@ -128,6 +129,11 @@ describe('plugin-meetings', () => {
128
129
 
129
130
  Object.assign(webex, {
130
131
  logger,
132
+ people: {
133
+ _getMe: sinon.stub().resolves({
134
+ type: 'validuser',
135
+ }),
136
+ }
131
137
  });
132
138
 
133
139
  startReachabilityStub = sinon.stub(webex.meetings, 'startReachability').resolves();
@@ -196,6 +202,43 @@ describe('plugin-meetings', () => {
196
202
  assert.calledOnce(MeetingsUtil.checkH264Support);
197
203
  });
198
204
 
205
+ describe('#getBasicMeetingInformation', () => {
206
+ beforeEach(() => {
207
+ sinon.stub(MeetingUtil, 'cleanUp');
208
+ });
209
+
210
+ it('returns correct meeting information', async () => {
211
+ const meeting = await webex.meetings.createMeeting('test', 'test');
212
+
213
+ const meetingIds = {
214
+ meetingId: meeting.id,
215
+ correlationId: meeting.correlationId,
216
+ };
217
+
218
+ // before meeting is destroyed - it should return information from the meetingCollection
219
+ assert.equal(
220
+ webex.meetings.getBasicMeetingInformation(meetingIds.meetingId).id,
221
+ meetingIds.meetingId
222
+ );
223
+ assert.equal(
224
+ webex.meetings.getBasicMeetingInformation(meetingIds.meetingId).correlationId,
225
+ meetingIds.correlationId
226
+ );
227
+
228
+ webex.meetings.destroy(meeting, test1);
229
+
230
+ // and it should still return the information after the meeting is destroyed
231
+ assert.equal(
232
+ webex.meetings.getBasicMeetingInformation(meetingIds.meetingId).id,
233
+ meetingIds.meetingId
234
+ );
235
+ assert.equal(
236
+ webex.meetings.getBasicMeetingInformation(meetingIds.meetingId).correlationId,
237
+ meetingIds.correlationId
238
+ );
239
+ });
240
+ });
241
+
199
242
  describe('#startReachability', () => {
200
243
  let gatherReachabilitySpy;
201
244
  let fakeResult = {id: 'fake-result'};
@@ -346,12 +389,21 @@ describe('plugin-meetings', () => {
346
389
  webex.canAuthorize = true;
347
390
  webex.meetings.registered = false;
348
391
  await webex.meetings.register();
349
- assert.called(webex.internal.device.register);
392
+ assert.calledOnceWithExactly(webex.internal.device.register, undefined);
350
393
  assert.called(webex.internal.services.getMeetingPreferences);
351
394
  assert.called(webex.internal.services.fetchClientRegionInfo);
352
395
  assert.called(webex.internal.mercury.connect);
353
396
  assert.isTrue(webex.meetings.registered);
354
397
  });
398
+
399
+ it('passes on the device registration options', async () => {
400
+ webex.canAuthorize = true;
401
+ webex.meetings.registered = false;
402
+ await webex.meetings.register({includeDetails: CatalogDetails.features});
403
+ assert.calledOnceWithExactly(webex.internal.device.register, {
404
+ includeDetails: CatalogDetails.features,
405
+ });
406
+ });
355
407
  });
356
408
 
357
409
  describe('#unregister', () => {
@@ -820,7 +872,7 @@ describe('plugin-meetings', () => {
820
872
  undefined,
821
873
  meetingInfo,
822
874
  'meetingLookupURL',
823
- sessionCorrelationId
875
+ sessionCorrelationId,
824
876
  ],
825
877
  [
826
878
  test1,
@@ -1820,7 +1872,10 @@ describe('plugin-meetings', () => {
1820
1872
  });
1821
1873
 
1822
1874
  it('creates the meeting avoiding meeting info fetch by passing type as DESTINATION_TYPE.ONE_ON_ONE_CALL', async () => {
1823
- const meeting = await webex.meetings.createMeeting('test destination', DESTINATION_TYPE.ONE_ON_ONE_CALL);
1875
+ const meeting = await webex.meetings.createMeeting(
1876
+ 'test destination',
1877
+ DESTINATION_TYPE.ONE_ON_ONE_CALL
1878
+ );
1824
1879
 
1825
1880
  assert.instanceOf(
1826
1881
  meeting,
@@ -1830,7 +1885,6 @@ describe('plugin-meetings', () => {
1830
1885
 
1831
1886
  assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
1832
1887
  });
1833
-
1834
1888
  });
1835
1889
 
1836
1890
  describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
@@ -1904,17 +1958,23 @@ describe('plugin-meetings', () => {
1904
1958
  assert.exists(webex.meetings.destroy);
1905
1959
  });
1906
1960
  describe('correctly established meeting', () => {
1961
+ let deleteSpy;
1907
1962
  beforeEach(() => {
1908
- webex.meetings.meetingCollection.delete = sinon.stub().returns(true);
1963
+ deleteSpy = sinon.spy(webex.meetings.meetingCollection, 'delete');
1909
1964
  });
1910
1965
 
1911
- it('tests the destroy removal from the collection', async () => {
1966
+ it('tests the destroy removal from the collection and storing basic info in deletedMeetings', async () => {
1912
1967
  const meeting = await webex.meetings.createMeeting('test', 'test');
1913
1968
 
1969
+ const meetingIds = {
1970
+ meetingId: meeting.id,
1971
+ correlationId: meeting.correlationId,
1972
+ };
1973
+
1914
1974
  webex.meetings.destroy(meeting, test1);
1915
1975
 
1916
- assert.calledOnce(webex.meetings.meetingCollection.delete);
1917
- assert.calledWith(webex.meetings.meetingCollection.delete, meeting.id);
1976
+ assert.calledOnce(deleteSpy);
1977
+ assert.calledWith(deleteSpy, meeting.id);
1918
1978
  assert.calledWith(
1919
1979
  TriggerProxy.trigger,
1920
1980
  sinon.match.instanceOf(Meetings),
@@ -1928,6 +1988,23 @@ describe('plugin-meetings', () => {
1928
1988
  reason: test1,
1929
1989
  }
1930
1990
  );
1991
+
1992
+ // check that the meeting is stored in deletedMeetings and removed from meetingCollection
1993
+ assert.equal(webex.meetings.deletedMeetings.get(meeting.id).id, meetingIds.meetingId);
1994
+ assert.equal(
1995
+ webex.meetings.deletedMeetings.get(meeting.id).correlationId,
1996
+ meetingIds.correlationId
1997
+ );
1998
+
1999
+ assert.equal(webex.meetings.meetingCollection.get(meeting.id), undefined);
2000
+
2001
+ // and that getBasicMeetingInformation() still returns the meeting info
2002
+ const deletedMeetingInfo = webex.meetings.getBasicMeetingInformation(
2003
+ meetingIds.meetingId
2004
+ );
2005
+
2006
+ assert.equal(deletedMeetingInfo.id, meetingIds.meetingId);
2007
+ assert.equal(deletedMeetingInfo.correlationId, meetingIds.correlationId);
1931
2008
  });
1932
2009
  });
1933
2010
 
@@ -1984,7 +2061,7 @@ describe('plugin-meetings', () => {
1984
2061
  ]);
1985
2062
  });
1986
2063
 
1987
- const setup = ({user} = {}) => {
2064
+ const setup = ({me = { type: 'validuser'}, user} = {}) => {
1988
2065
  loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
1989
2066
  assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), []);
1990
2067
 
@@ -1997,8 +2074,22 @@ describe('plugin-meetings', () => {
1997
2074
  Object.assign(webex.internal.services, {
1998
2075
  getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
1999
2076
  });
2077
+
2078
+ Object.assign(webex.people, {
2079
+ _getMe: sinon.stub().returns(Promise.resolve(me)),
2080
+ });
2000
2081
  };
2001
2082
 
2083
+ it('should not call request.getMeetingPreferences if user is a guest', async () => {
2084
+ setup({me: {type: 'appuser'}});
2085
+
2086
+ await webex.meetings.fetchUserPreferredWebexSite();
2087
+
2088
+ assert.equal(webex.meetings.preferredWebexSite, '');
2089
+ assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), []);
2090
+ assert.notCalled(webex.internal.services.getMeetingPreferences);
2091
+ });
2092
+
2002
2093
  it('should not fail if UserPreferred info is not fetched ', async () => {
2003
2094
  setup();
2004
2095
 
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
- _Object$defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = void 0;
8
- var RTC_METRICS = exports.default = {
9
- APP_ID: 'FFB51ED5-4319-4C55-8303-B1F2FCCDE231'
10
- };
11
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["RTC_METRICS","exports","default","APP_ID"],"sources":["constants.ts"],"sourcesContent":["const RTC_METRICS = {APP_ID: 'FFB51ED5-4319-4C55-8303-B1F2FCCDE231'};\n\nexport {RTC_METRICS as default};\n"],"mappings":";;;;;;;AAAA,IAAMA,WAAW,GAAAC,OAAA,CAAAC,OAAA,GAAG;EAACC,MAAM,EAAE;AAAsC,CAAC"}