@webex/plugin-meetings 3.4.0-next.9 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/interpretation/index.js +1 -1
  4. package/dist/interpretation/siLanguage.js +1 -1
  5. package/dist/meeting/index.js +77 -11
  6. package/dist/meeting/index.js.map +1 -1
  7. package/dist/meeting/util.js +1 -0
  8. package/dist/meeting/util.js.map +1 -1
  9. package/dist/networkQualityMonitor/index.js +227 -0
  10. package/dist/networkQualityMonitor/index.js.map +1 -0
  11. package/dist/types/meeting/index.d.ts +9 -0
  12. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  13. package/dist/webinar/index.js +1 -1
  14. package/package.json +22 -22
  15. package/src/meeting/index.ts +39 -4
  16. package/src/meeting/util.ts +2 -0
  17. package/test/integration/spec/converged-space-meetings.js +1 -1
  18. package/test/unit/spec/breakouts/index.ts +1 -0
  19. package/test/unit/spec/interceptors/locusRetry.ts +11 -10
  20. package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -0
  21. package/test/unit/spec/media/index.ts +1 -0
  22. package/test/unit/spec/media/properties.ts +1 -1
  23. package/test/unit/spec/meeting/connectionStateHandler.ts +1 -0
  24. package/test/unit/spec/meeting/index.js +28 -0
  25. package/test/unit/spec/meeting/locusMediaRequest.ts +3 -2
  26. package/test/unit/spec/meeting/request.js +1 -0
  27. package/test/unit/spec/meeting/utils.js +4 -0
  28. package/test/unit/spec/meeting-info/meetinginfov2.js +10 -11
  29. package/test/unit/spec/meeting-info/request.js +1 -1
  30. package/test/unit/spec/members/request.js +2 -1
  31. package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
  32. package/test/unit/spec/multistream/receiveSlot.ts +1 -0
  33. package/test/unit/spec/multistream/receiveSlotManager.ts +1 -0
  34. package/test/unit/spec/multistream/remoteMedia.ts +1 -0
  35. package/test/unit/spec/multistream/remoteMediaGroup.ts +1 -0
  36. package/test/unit/spec/multistream/remoteMediaManager.ts +1 -0
  37. package/test/unit/spec/multistream/sendSlotManager.ts +1 -0
  38. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +0 -1
  39. package/test/unit/spec/reachability/request.js +1 -0
  40. package/test/unit/spec/roap/request.ts +1 -0
@@ -0,0 +1,70 @@
1
+ import EventsScope from '../common/events/events-scope';
2
+ /**
3
+ * Meeting - network quality event
4
+ * Emitted on each interval of retrieving stats Analyzer data
5
+ * @event network:quality
6
+ * @type {Object}
7
+ * @property {string} mediaType {video|audio}
8
+ * @property {number} networkQualityScore - value determined in determineUplinkNetworkQuality
9
+ * @memberof NetworkQualityMonitor
10
+ */
11
+ /**
12
+ * NetworkQualityMonitor class that will emit events based on detected quality
13
+ *
14
+ * @class NetworkQualityMonitor
15
+ * @extends {EventsScope}
16
+ */
17
+ export default class NetworkQualityMonitor extends EventsScope {
18
+ config: any;
19
+ frequencyTypes: any;
20
+ indicatorTypes: any;
21
+ mediaType: any;
22
+ networkQualityScore: any;
23
+ networkQualityStatus: any;
24
+ /**
25
+ * Creates a new instance of NetworkQualityMonitor
26
+ * @constructor
27
+ * @public
28
+ * @param {Object} config
29
+ * @property {Object} indicatorTypes - network properties used to evaluate network quality used as constants
30
+ * @property {Object} frequencyTypes - frequency properties used as constants {uplink|send} {downlink|receive}
31
+ * @property {number} networkQualityScore - 0|1 1 is acceptable 0 is bad/unknown
32
+ * @property {Object} networkQualityStatus - hash object based on indicatorTypes and frequencyTypes
33
+ * @property {string} mediaType - audio|video
34
+ */
35
+ constructor(config: any);
36
+ /**
37
+ * emits NETWORK_QUALITY event on meeting with payload of media type and uplinkNetworkQuality score
38
+ *
39
+ * @memberof NetworkQualityMonitor
40
+ * @returns {void}
41
+ */
42
+ emitNetworkQuality(): void;
43
+ /**
44
+ * invokes emitNetworkQuality method resets values back to default
45
+ * @returns {void}
46
+ * @memberof NetworkQualityMonitor
47
+ */
48
+ updateNetworkQualityStatus(): void;
49
+ /**
50
+ * filter data to determine uplink network quality, invoked on same interval as stats analyzer remote-inbout-rtp
51
+ * @param {Object} configObj
52
+ * @param {string} configObj.mediaType {audio|video}
53
+ * @param {RTCStats} configObj.remoteRtpResults RTC stats remote obj
54
+ * @param {Object} configObj.statsAnalyzerCurrentStats statsResults
55
+ * @returns {void}
56
+ * @public
57
+ * @memberof NetworkQualityMonitor
58
+ */
59
+ determineUplinkNetworkQuality({ mediaType, remoteRtpResults, statsAnalyzerCurrentStats, }: {
60
+ mediaType: string;
61
+ remoteRtpResults: any;
62
+ statsAnalyzerCurrentStats: object;
63
+ }): void;
64
+ /**
65
+ * Get the current status of network quaility object - networkQualityStatus
66
+ * @returns {Object}
67
+ * @public
68
+ */
69
+ get networkQualityStats(): any;
70
+ }
@@ -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.4.0-next.9"
65
+ version: "3.5.0"
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.4.0-next.9",
47
- "@webex/plugin-rooms": "3.4.0-next.2",
48
- "@webex/test-helper-chai": "3.4.0-next.2",
49
- "@webex/test-helper-mocha": "3.4.0-next.2",
50
- "@webex/test-helper-mock-webex": "3.4.0-next.2",
51
- "@webex/test-helper-retry": "3.4.0-next.2",
52
- "@webex/test-helper-test-users": "3.4.0-next.2",
46
+ "@webex/plugin-meetings": "3.5.0",
47
+ "@webex/plugin-rooms": "3.5.0",
48
+ "@webex/test-helper-chai": "3.5.0",
49
+ "@webex/test-helper-mocha": "3.5.0",
50
+ "@webex/test-helper-mock-webex": "3.5.0",
51
+ "@webex/test-helper-retry": "3.5.0",
52
+ "@webex/test-helper-test-users": "3.5.0",
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.4.0-next.2",
65
- "@webex/internal-media-core": "2.10.2",
66
- "@webex/internal-plugin-conversation": "3.4.0-next.2",
67
- "@webex/internal-plugin-device": "3.4.0-next.2",
68
- "@webex/internal-plugin-llm": "3.4.0-next.2",
69
- "@webex/internal-plugin-mercury": "3.4.0-next.2",
70
- "@webex/internal-plugin-metrics": "3.4.0-next.2",
71
- "@webex/internal-plugin-support": "3.4.0-next.2",
72
- "@webex/internal-plugin-user": "3.4.0-next.2",
73
- "@webex/internal-plugin-voicea": "3.4.0-next.9",
74
- "@webex/media-helpers": "3.4.0-next.3",
75
- "@webex/plugin-people": "3.4.0-next.2",
76
- "@webex/plugin-rooms": "3.4.0-next.2",
64
+ "@webex/common": "3.5.0",
65
+ "@webex/internal-media-core": "2.11.1",
66
+ "@webex/internal-plugin-conversation": "3.5.0",
67
+ "@webex/internal-plugin-device": "3.5.0",
68
+ "@webex/internal-plugin-llm": "3.5.0",
69
+ "@webex/internal-plugin-mercury": "3.5.0",
70
+ "@webex/internal-plugin-metrics": "3.5.0",
71
+ "@webex/internal-plugin-support": "3.5.0",
72
+ "@webex/internal-plugin-user": "3.5.0",
73
+ "@webex/internal-plugin-voicea": "3.5.0",
74
+ "@webex/media-helpers": "3.5.0",
75
+ "@webex/plugin-people": "3.5.0",
76
+ "@webex/plugin-rooms": "3.5.0",
77
77
  "@webex/web-capabilities": "^1.4.0",
78
- "@webex/webex-core": "3.4.0-next.2",
78
+ "@webex/webex-core": "3.5.0",
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.4.0-next.9"
94
+ "version": "3.5.0"
95
95
  }
@@ -538,6 +538,7 @@ export default class Meeting extends StatelessWebexPlugin {
538
538
  id: string;
539
539
  isMultistream: boolean;
540
540
  locusUrl: string;
541
+ #isoLocalClientMeetingJoinTime?: string;
541
542
  mediaConnections: any[];
542
543
  mediaId?: string;
543
544
  meetingFiniteStateMachine: any;
@@ -1521,6 +1522,17 @@ export default class Meeting extends StatelessWebexPlugin {
1521
1522
  * @memberof Meeting
1522
1523
  */
1523
1524
  this.iceCandidatesCount = 0;
1525
+
1526
+ /**
1527
+ * Start time of meeting as an ISO string
1528
+ * based on browser time, so can only be used to compute durations client side
1529
+ * undefined if meeting has not been joined, set once on meeting join, and not updated again
1530
+ * @instance
1531
+ * @type {string}
1532
+ * @private
1533
+ * @memberof Meeting
1534
+ */
1535
+ this.#isoLocalClientMeetingJoinTime = undefined;
1524
1536
  }
1525
1537
 
1526
1538
  /**
@@ -1569,6 +1581,15 @@ export default class Meeting extends StatelessWebexPlugin {
1569
1581
  this.callStateForMetrics.correlationId = correlationId;
1570
1582
  }
1571
1583
 
1584
+ /**
1585
+ * Getter - Returns isoLocalClientMeetingJoinTime
1586
+ * This will be set once on meeting join, and not updated again
1587
+ * @returns {string | undefined}
1588
+ */
1589
+ get isoLocalClientMeetingJoinTime(): string | undefined {
1590
+ return this.#isoLocalClientMeetingJoinTime;
1591
+ }
1592
+
1572
1593
  /**
1573
1594
  * Set meeting info and trigger `MEETING_INFO_AVAILABLE` event
1574
1595
  * @param {any} info
@@ -5232,6 +5253,11 @@ export default class Meeting extends StatelessWebexPlugin {
5232
5253
  this.meetingFiniteStateMachine.join();
5233
5254
  this.setupLocusMediaRequest();
5234
5255
 
5256
+ // @ts-ignore
5257
+ this.webex.internal.device.meetingStarted();
5258
+
5259
+ this.#isoLocalClientMeetingJoinTime = new Date().toISOString();
5260
+
5235
5261
  LoggerProxy.logger.log('Meeting:index#join --> Success');
5236
5262
 
5237
5263
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_SUCCESS, {
@@ -6518,12 +6544,21 @@ export default class Meeting extends StatelessWebexPlugin {
6518
6544
  *
6519
6545
  * @private
6520
6546
  * @static
6547
+ * @param {boolean} isAudioEnabled
6548
+ * @param {boolean} isVideoEnabled
6521
6549
  * @returns {Promise<void>}
6522
6550
  */
6523
- private static async handleDeviceLogging(): Promise<void> {
6524
- try {
6525
- const devices = await getDevices();
6526
6551
 
6552
+ private static async handleDeviceLogging(isAudioEnabled, isVideoEnabled): Promise<void> {
6553
+ try {
6554
+ let devices = [];
6555
+ if (isVideoEnabled && isAudioEnabled) {
6556
+ devices = await getDevices();
6557
+ } else if (isVideoEnabled) {
6558
+ devices = await getDevices(Media.DeviceKind.VIDEO_INPUT);
6559
+ } else if (isAudioEnabled) {
6560
+ devices = await getDevices(Media.DeviceKind.AUDIO_INPUT);
6561
+ }
6527
6562
  MeetingUtil.handleDeviceLogging(devices);
6528
6563
  } catch {
6529
6564
  // getDevices may fail if we don't have browser permissions, that's ok, we still can have a media connection
@@ -7016,7 +7051,7 @@ export default class Meeting extends StatelessWebexPlugin {
7016
7051
  );
7017
7052
 
7018
7053
  if (audioEnabled || videoEnabled) {
7019
- await Meeting.handleDeviceLogging();
7054
+ await Meeting.handleDeviceLogging(audioEnabled, videoEnabled);
7020
7055
  } else {
7021
7056
  LoggerProxy.logger.info(`${LOG_HEADER} device logging not required`);
7022
7057
  }
@@ -170,6 +170,8 @@ const MeetingUtil = {
170
170
  },
171
171
 
172
172
  cleanUp: (meeting) => {
173
+ meeting.getWebexObject().internal.device.meetingEnded();
174
+
173
175
  meeting.breakouts.cleanUp();
174
176
  meeting.simultaneousInterpretation.cleanUp();
175
177
  meeting.locusMediaRequest = undefined;
@@ -1,5 +1,5 @@
1
- import { config } from 'dotenv';
2
1
  import 'jsdom-global/register';
2
+ import {config} from 'dotenv';
3
3
  import {assert} from '@webex/test-helper-chai';
4
4
  import {skipInNode} from '@webex/test-helper-mocha';
5
5
  import BrowserDetection from '@webex/plugin-meetings/dist/common/browser-detection';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import {assert, expect} from '@webex/test-helper-chai';
2
3
  import Breakouts from '@webex/plugin-meetings/src/breakouts';
3
4
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  /* eslint-disable camelcase */
6
+ import 'jsdom-global/register';
6
7
  import {assert} from '@webex/test-helper-chai';
7
8
  import { expect } from "@webex/test-helper-chai";
8
9
  import MockWebex from '@webex/test-helper-mock-webex';
@@ -13,7 +14,7 @@ import sinon from 'sinon';
13
14
 
14
15
  describe('plugin-meetings', () => {
15
16
  describe('Interceptors', () => {
16
- describe('LocusRetryStatusInterceptor', () => {
17
+ describe('LocusRetryStatusInterceptor', () => {
17
18
  let interceptor, webex;
18
19
  beforeEach(() => {
19
20
  webex = new MockWebex({
@@ -24,7 +25,7 @@ describe('plugin-meetings', () => {
24
25
  interceptor = Reflect.apply(LocusRetryStatusInterceptor.create, {
25
26
  sessionId: 'mock-webex_uuid',
26
27
  }, []);
27
- });
28
+ });
28
29
  describe('#onResponseError', () => {
29
30
  const options = {
30
31
  method: 'POST',
@@ -41,7 +42,7 @@ describe('plugin-meetings', () => {
41
42
  headers: {
42
43
  trackingid: 'test',
43
44
  'retry-after': 1000,
44
- },
45
+ },
45
46
  uri: `https://locus-test.webex.com/locus/api/v1/loci/call`,
46
47
  },
47
48
  body: {
@@ -54,7 +55,7 @@ describe('plugin-meetings', () => {
54
55
  headers: {
55
56
  trackingid: 'test',
56
57
  'retry-after': 1000,
57
- },
58
+ },
58
59
  uri: `https://locus-test.webex.com/locus/api/v1/loci/call`,
59
60
  },
60
61
  body: {
@@ -73,7 +74,7 @@ describe('plugin-meetings', () => {
73
74
 
74
75
  return interceptor.onResponseError(options, reason2).then(() => {
75
76
  expect(handleRetryStub.calledWith(options, 1000)).to.be.true;
76
-
77
+
77
78
  });
78
79
  });
79
80
  });
@@ -92,7 +93,7 @@ describe('plugin-meetings', () => {
92
93
  it('returns the correct resolved value when the request is successful', () => {
93
94
  const mockResponse = 'mock response'
94
95
  interceptor.webex.request = sinon.stub().returns(Promise.resolve(mockResponse));
95
-
96
+
96
97
  return interceptor.handleRetryRequestLocusServiceError(options, retryAfterTime)
97
98
  .then((response) => {
98
99
  expect(response).to.equal(mockResponse);
@@ -101,9 +102,9 @@ describe('plugin-meetings', () => {
101
102
 
102
103
  it('rejects the promise when the request is unsuccessful', () => {
103
104
  const rejectionReason = 'Service Unavaialble after retry';
104
-
105
+
105
106
  interceptor.webex.request = sinon.stub().returns(Promise.reject(rejectionReason));
106
-
107
+
107
108
  return interceptor.handleRetryRequestLocusServiceError(options, retryAfterTime)
108
109
  .catch((error) => {
109
110
  expect(error).to.equal(rejectionReason);
@@ -114,10 +115,10 @@ describe('plugin-meetings', () => {
114
115
  let clock;
115
116
  clock = sinon.useFakeTimers();
116
117
  const mockResponse = 'mock response'
117
-
118
+
118
119
  interceptor.webex.request = sinon.stub().returns(Promise.resolve(mockResponse));
119
120
  const promise = interceptor.handleRetryRequestLocusServiceError(options, retryAfterTime);
120
-
121
+
121
122
  clock.tick(retryAfterTime);
122
123
 
123
124
  return promise.then(() => {
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import {assert} from '@webex/test-helper-chai';
2
3
  import sinon from 'sinon';
3
4
  import {ConnectionState, MediaConnectionEventNames} from '@webex/internal-media-core';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import * as InternalMediaCoreModule from '@webex/internal-media-core';
2
3
  import Media from '@webex/plugin-meetings/src/media/index';
3
4
  import {assert} from '@webex/test-helper-chai';
@@ -1,8 +1,8 @@
1
+ import 'jsdom-global/register';
1
2
  import {assert} from '@webex/test-helper-chai';
2
3
  import sinon from 'sinon';
3
4
  import {ConnectionState} from '@webex/internal-media-core';
4
5
  import MediaProperties from '@webex/plugin-meetings/src/media/properties';
5
- import testUtils from '../../../utils/testUtils';
6
6
  import {Defer} from '@webex/common';
7
7
  import MediaConnectionAwaiter from '../../../../src/media/MediaConnectionAwaiter';
8
8
 
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register'
1
2
  import sinon from 'sinon';
2
3
  import {assert} from '@webex/test-helper-chai';
3
4
  import {
@@ -331,6 +331,7 @@ describe('plugin-meetings', () => {
331
331
  assert.isNull(meeting.partner);
332
332
  assert.isNull(meeting.type);
333
333
  assert.isNull(meeting.owner);
334
+ assert.isUndefined(meeting.isoLocalClientMeetingJoinTime);
334
335
  assert.isNull(meeting.hostId);
335
336
  assert.isNull(meeting.policy);
336
337
  assert.instanceOf(meeting.meetingRequest, MeetingRequest);
@@ -1587,6 +1588,10 @@ describe('plugin-meetings', () => {
1587
1588
  sandbox.stub(MeetingUtil, 'joinMeeting').returns(Promise.resolve(joinMeetingResult));
1588
1589
  });
1589
1590
 
1591
+ afterEach(() => {
1592
+ assert.exists(meeting.isoLocalClientMeetingJoinTime);
1593
+ });
1594
+
1590
1595
  it('should join the meeting and return promise', async () => {
1591
1596
  const join = meeting.join({pstnAudioType: 'dial-in'});
1592
1597
  meeting.config.enableAutomaticLLM = true;
@@ -1605,6 +1610,7 @@ describe('plugin-meetings', () => {
1605
1610
  const result = await join;
1606
1611
 
1607
1612
  assert.calledOnce(MeetingUtil.joinMeeting);
1613
+ assert.calledOnce(webex.internal.device.meetingStarted);
1608
1614
  assert.calledOnce(meeting.setLocus);
1609
1615
  assert.equal(result, joinMeetingResult);
1610
1616
  assert.calledWith(webex.internal.llm.on, 'online', meeting.handleLLMOnline);
@@ -4278,6 +4284,20 @@ describe('plugin-meetings', () => {
4278
4284
  assert.calledTwice(locusMediaRequestStub);
4279
4285
  });
4280
4286
 
4287
+ it('addMedia() works correctly when media is disabled with no streams to publish', async () => {
4288
+ const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
4289
+ await meeting.addMedia({audioEnabled: false});
4290
+ //calling handleDeviceLogging with audioEnaled as true adn videoEnabled as false
4291
+ assert.calledWith(handleDeviceLoggingSpy,false,true);
4292
+ });
4293
+
4294
+ it('addMedia() works correctly when video is disabled with no streams to publish', async () => {
4295
+ const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
4296
+ await meeting.addMedia({videoEnabled: false});
4297
+ //calling handleDeviceLogging audioEnabled as true videoEnabled as false
4298
+ assert.calledWith(handleDeviceLoggingSpy,true,false);
4299
+ });
4300
+
4281
4301
  it('addMedia() works correctly when video is disabled with no streams to publish', async () => {
4282
4302
  await meeting.addMedia({videoEnabled: false});
4283
4303
  await simulateRoapOffer();
@@ -4344,6 +4364,14 @@ describe('plugin-meetings', () => {
4344
4364
  assert.calledTwice(locusMediaRequestStub);
4345
4365
  });
4346
4366
 
4367
+
4368
+ it('addMedia() works correctly when both shareAudio and shareVideo is disabled with no streams publish', async () => {
4369
+ const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
4370
+ await meeting.addMedia({shareAudioEnabled: false, shareVideoEnabled: false});
4371
+ //calling handleDeviceLogging with audioEnabled true and videoEnabled as true
4372
+ assert.calledWith(handleDeviceLoggingSpy,true,true);
4373
+ });
4374
+
4347
4375
  describe('publishStreams()/unpublishStreams() calls', () => {
4348
4376
  [
4349
4377
  {mediaEnabled: true, expected: {direction: 'sendrecv', localMuteSentValue: false}},
@@ -1,6 +1,7 @@
1
+ import 'jsdom-global/register';
1
2
  import sinon from 'sinon';
2
3
  import {assert} from '@webex/test-helper-chai';
3
- import { cloneDeep, defer } from 'lodash';
4
+ import { cloneDeep } from 'lodash';
4
5
 
5
6
  import MockWebex from '@webex/test-helper-mock-webex';
6
7
  import Meetings from '@webex/plugin-meetings';
@@ -495,4 +496,4 @@ describe('LocusMediaRequest.send()', () => {
495
496
  });
496
497
 
497
498
  });
498
- })
499
+ })
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import sinon from 'sinon';
2
3
  import {assert} from '@webex/test-helper-chai';
3
4
  import MockWebex from '@webex/test-helper-mock-webex';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import sinon from 'sinon';
2
3
  import {assert} from '@webex/test-helper-chai';
3
4
  import Meetings from '@webex/plugin-meetings';
@@ -71,6 +72,7 @@ describe('plugin-meetings', () => {
71
72
  assert.calledOnce(meeting.updateLLMConnection);
72
73
  assert.calledOnce(meeting.breakouts.cleanUp);
73
74
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
75
+ assert.calledOnce(webex.internal.device.meetingEnded);
74
76
  });
75
77
 
76
78
  it('do clean up on meeting object with LLM disabled', async () => {
@@ -87,6 +89,7 @@ describe('plugin-meetings', () => {
87
89
  assert.notCalled(meeting.updateLLMConnection);
88
90
  assert.calledOnce(meeting.breakouts.cleanUp);
89
91
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
92
+ assert.calledOnce(webex.internal.device.meetingEnded);
90
93
  });
91
94
 
92
95
  it('do clean up on meeting object with no config', async () => {
@@ -102,6 +105,7 @@ describe('plugin-meetings', () => {
102
105
  assert.notCalled(meeting.updateLLMConnection);
103
106
  assert.calledOnce(meeting.breakouts.cleanUp);
104
107
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
108
+ assert.calledOnce(webex.internal.device.meetingEnded);
105
109
  });
106
110
  });
107
111
 
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
-
4
+ import 'jsdom-global/register';
5
5
  import {assert} from '@webex/test-helper-chai';
6
6
  import sinon from 'sinon';
7
7
  import MockWebex from '@webex/test-helper-mock-webex';
@@ -23,7 +23,6 @@ import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
23
23
  import Metrics from '@webex/plugin-meetings/src/metrics';
24
24
  import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
25
25
  import {forEach} from 'lodash';
26
- import { request } from 'express';
27
26
 
28
27
  describe('plugin-meetings', () => {
29
28
  const conversation = {
@@ -433,7 +432,7 @@ describe('plugin-meetings', () => {
433
432
  assert.deepEqual(submitInternalEventCalls[1].args[0], {
434
433
  name: 'internal.client.meetinginfo.response',
435
434
  });
436
-
435
+
437
436
  assert.deepEqual(submitClientEventCalls[1].args[0], {
438
437
  name: 'client.meetinginfo.response',
439
438
  payload: {
@@ -484,9 +483,9 @@ describe('plugin-meetings', () => {
484
483
  requestResponse.body.confIdStr = confIdStr;
485
484
  }
486
485
  const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'}
487
-
486
+
488
487
  webex.request.resolves(requestResponse);
489
-
488
+
490
489
  const result = await meetingInfo.fetchMeetingInfo(
491
490
  '1234323',
492
491
  DESTINATION_TYPE.MEETING_ID,
@@ -497,7 +496,7 @@ describe('plugin-meetings', () => {
497
496
  extraParams,
498
497
  {meetingId, sendCAevents}
499
498
  );
500
-
499
+
501
500
  assert.calledWith(webex.request, {
502
501
  method: 'POST',
503
502
  service: WBXAPPAPI_SERVICE,
@@ -515,7 +514,7 @@ describe('plugin-meetings', () => {
515
514
  Metrics.sendBehavioralMetric,
516
515
  BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_SUCCESS
517
516
  );
518
-
517
+
519
518
  const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
520
519
  const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
521
520
 
@@ -529,7 +528,7 @@ describe('plugin-meetings', () => {
529
528
  meetingId,
530
529
  }
531
530
  });
532
-
531
+
533
532
  assert.deepEqual(submitInternalEventCalls[1].args[0], {
534
533
  name: 'internal.client.meetinginfo.response',
535
534
  });
@@ -591,7 +590,7 @@ describe('plugin-meetings', () => {
591
590
 
592
591
  const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
593
592
  const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
594
-
593
+
595
594
  assert.deepEqual(submitInternalEventCalls[0].args[0], {
596
595
  name: 'internal.client.meetinginfo.request',
597
596
  });
@@ -601,7 +600,7 @@ describe('plugin-meetings', () => {
601
600
  meetingId: 'meetingId',
602
601
  }
603
602
  });
604
-
603
+
605
604
  assert.deepEqual(submitInternalEventCalls[1].args[0], {
606
605
  name: 'internal.client.meetinginfo.response',
607
606
  });
@@ -629,7 +628,7 @@ describe('plugin-meetings', () => {
629
628
  it(`should not send CA metric if meetingId is not provided disregarding if sendCAevents is ${sendCAevents}`, async () => {
630
629
  const message = 'a message';
631
630
  const meetingInfoData = 'meeting info';
632
-
631
+
633
632
  webex.request = sinon.stub().rejects({
634
633
  statusCode: 403,
635
634
  body: {message, code: 403102, data: {meetingInfo: meetingInfoData}},
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
-
4
+ import 'jsdom-global/register';
5
5
  import {assert} from '@webex/test-helper-chai';
6
6
  import sinon from 'sinon';
7
7
  import MockWebex from '@webex/test-helper-mock-webex';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import sinon from 'sinon';
2
3
  import chai from 'chai';
3
4
  import uuid from 'uuid';
@@ -131,7 +132,7 @@ describe('plugin-meetings', () => {
131
132
  locusUrl: url1,
132
133
  memberIds: ['1', '2'],
133
134
  };
134
-
135
+
135
136
  await membersRequest.admitMember(options)
136
137
 
137
138
  checkRequest({
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import {MediaRequestManager} from '@webex/plugin-meetings/src/multistream/mediaRequestManager';
2
3
  import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
3
4
  import sinon from 'sinon';
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable require-jsdoc */
2
+ import 'jsdom-global/register';
2
3
  import EventEmitter from 'events';
3
4
 
4
5
  import {MediaType, ReceiveSlotEvents as WcmeReceiveSlotEvents} from '@webex/internal-media-core';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import sinon from 'sinon';
2
3
  import {assert} from '@webex/test-helper-chai';
3
4
  import {MediaType} from '@webex/internal-media-core';
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable require-jsdoc */
2
+ import 'jsdom-global/register';
2
3
  import EventEmitter from 'events';
3
4
 
4
5
  import {MediaType} from '@webex/internal-media-core';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import EventEmitter from 'events';
2
3
 
3
4
  import {MediaType} from '@webex/internal-media-core';
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable require-jsdoc */
2
+ import 'jsdom-global/register';
2
3
  import EventEmitter from 'events';
3
4
 
4
5
  import {MediaType} from '@webex/internal-media-core';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import SendSlotManager from '@webex/plugin-meetings/src/multistream/sendSlotManager';
2
3
  import { LocalStream, MediaType, MultistreamRoapMediaConnection } from "@webex/internal-media-core";
3
4
  import {expect} from '@webex/test-helper-chai';
@@ -1,7 +1,6 @@
1
1
  /*!
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
-
5
4
  import 'jsdom-global/register';
6
5
  import {assert} from '@webex/test-helper-chai';
7
6
  import sinon from 'sinon';
@@ -1,3 +1,4 @@
1
+ import 'jsdom-global/register';
1
2
  import sinon from 'sinon';
2
3
  import {assert} from '@webex/test-helper-chai';
3
4
  import MockWebex from '@webex/test-helper-mock-webex';