@webex/plugin-meetings 3.0.0-beta.28 → 3.0.0-beta.280
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.
- package/README.md +46 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +114 -14
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +52 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +763 -31
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +78 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.js +67 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/webex-errors.js +28 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.js +203 -28
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +112 -1
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +383 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +57 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +58 -116
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +72 -123
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +82 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +3123 -2814
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +230 -124
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +256 -196
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +601 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +192 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +22 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +394 -94
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +71 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +49 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +121 -25
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +86 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +316 -233
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +12 -5
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -468
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +238 -49
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +40 -16
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +39 -36
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +44 -18
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +60 -3
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +209 -59
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/index.js +225 -59
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +17 -8
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +199 -154
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +23 -29
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +112 -97
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +96 -36
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +67 -73
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +11 -10
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/request.d.ts +22 -0
- package/dist/types/breakouts/utils.d.ts +15 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/webex-errors.d.ts +13 -1
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +1 -6
- package/dist/types/constants.d.ts +161 -21
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -4
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +67 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -48
- package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
- package/dist/types/meeting/index.d.ts +345 -507
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +99 -23
- package/dist/types/meeting/request.d.ts +72 -43
- package/dist/types/meeting/util.d.ts +101 -1
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +8 -0
- package/dist/types/meetings/index.d.ts +88 -12
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +13 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +24 -0
- package/dist/types/members/util.d.ts +209 -1
- package/dist/types/metrics/constants.d.ts +11 -4
- package/dist/types/metrics/index.d.ts +4 -119
- package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
- package/dist/types/multistream/receiveSlot.d.ts +13 -11
- package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
- package/dist/types/multistream/remoteMedia.d.ts +8 -29
- package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
- package/dist/types/multistream/sendSlotManager.d.ts +61 -0
- package/dist/types/reachability/index.d.ts +61 -7
- package/dist/types/reachability/request.d.ts +7 -3
- package/dist/types/reconnection-manager/index.d.ts +9 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/request.d.ts +15 -11
- package/dist/types/roap/turnDiscovery.d.ts +18 -1
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +47 -0
- package/dist/types/statsAnalyzer/index.d.ts +6 -1
- package/package.json +23 -20
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +44 -14
- package/src/breakouts/breakout.ts +87 -9
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +646 -18
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/webex-errors.ts +27 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -9
- package/src/constants.ts +184 -18
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +413 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +100 -122
- package/src/media/properties.ts +85 -108
- package/src/meeting/in-meeting-actions.ts +163 -3
- package/src/meeting/index.ts +2541 -2309
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +229 -131
- package/src/meeting/request.ts +172 -121
- package/src/meeting/util.ts +588 -394
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +170 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +20 -0
- package/src/meetings/index.ts +428 -108
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +79 -4
- package/src/member/index.ts +49 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +127 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +106 -7
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +28 -0
- package/src/members/util.ts +319 -240
- package/src/metrics/constants.ts +11 -4
- package/src/metrics/index.ts +1 -490
- package/src/multistream/mediaRequestManager.ts +289 -79
- package/src/multistream/receiveSlot.ts +47 -17
- package/src/multistream/receiveSlotManager.ts +34 -24
- package/src/multistream/remoteMedia.ts +27 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +148 -30
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/reachability/index.ts +228 -37
- package/src/reachability/request.ts +17 -8
- package/src/reconnection-manager/index.ts +81 -54
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +23 -30
- package/src/roap/request.ts +100 -104
- package/src/roap/turnDiscovery.ts +51 -25
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/index.ts +88 -88
- package/src/statsAnalyzer/mqaUtil.ts +13 -14
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +142 -24
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1488 -67
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1304 -33
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +104 -37
- package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
- package/test/unit/spec/meeting/index.js +4515 -1932
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +408 -208
- package/test/unit/spec/meeting/request.js +440 -45
- package/test/unit/spec/meeting/utils.js +679 -64
- package/test/unit/spec/meeting-info/index.js +295 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +521 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +14 -0
- package/test/unit/spec/meetings/index.js +1007 -177
- package/test/unit/spec/meetings/utils.js +206 -2
- package/test/unit/spec/member/index.js +58 -4
- package/test/unit/spec/member/util.js +479 -35
- package/test/unit/spec/members/index.js +319 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +184 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
- package/test/unit/spec/multistream/receiveSlot.ts +43 -20
- package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
- package/test/unit/spec/multistream/remoteMedia.ts +30 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/reachability/index.ts +549 -9
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +84 -9
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +31 -51
- package/test/unit/spec/roap/request.ts +203 -85
- package/test/unit/spec/roap/turnDiscovery.ts +48 -13
- package/test/unit/spec/rtcMetrics/index.ts +68 -0
- package/test/unit/spec/stats-analyzer/index.js +64 -2
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -52
- package/dist/meeting/effectsState.js +0 -262
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.js +0 -299
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/meeting/effectsState.d.ts +0 -42
- package/dist/types/metrics/config.d.ts +0 -178
- package/src/index.js +0 -16
- package/src/meeting/effectsState.ts +0 -211
- package/src/metrics/config.ts +0 -495
- package/test/unit/spec/meeting/effectsState.js +0 -285
|
@@ -11,6 +11,7 @@ import sinon from 'sinon';
|
|
|
11
11
|
import uuid from 'uuid';
|
|
12
12
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
13
13
|
import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
14
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
14
15
|
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
15
16
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
16
17
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
@@ -19,6 +20,7 @@ import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
|
19
20
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
20
21
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
21
22
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
23
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
22
24
|
|
|
23
25
|
import testUtils from '../../../utils/testUtils';
|
|
24
26
|
import {
|
|
@@ -29,6 +31,12 @@ import {
|
|
|
29
31
|
LOCUSINFO,
|
|
30
32
|
EVENT_TRIGGERS,
|
|
31
33
|
} from '../../../../src/constants';
|
|
34
|
+
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
|
|
35
|
+
import { forEach } from 'lodash';
|
|
36
|
+
import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
|
|
37
|
+
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
38
|
+
import {NoiseReductionEffect,VirtualBackgroundEffect} from '@webex/media-helpers';
|
|
39
|
+
import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
|
|
32
40
|
|
|
33
41
|
describe('plugin-meetings', () => {
|
|
34
42
|
const logger = {
|
|
@@ -40,6 +48,8 @@ describe('plugin-meetings', () => {
|
|
|
40
48
|
debug: () => {},
|
|
41
49
|
};
|
|
42
50
|
|
|
51
|
+
let triggerProxyStub;
|
|
52
|
+
|
|
43
53
|
beforeEach(() => {
|
|
44
54
|
StaticConfig.set({
|
|
45
55
|
bandwidth: {
|
|
@@ -51,7 +61,7 @@ describe('plugin-meetings', () => {
|
|
|
51
61
|
verboseEvents: true,
|
|
52
62
|
enable: false,
|
|
53
63
|
});
|
|
54
|
-
|
|
64
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
55
65
|
});
|
|
56
66
|
|
|
57
67
|
let webex;
|
|
@@ -60,15 +70,20 @@ describe('plugin-meetings', () => {
|
|
|
60
70
|
let url1;
|
|
61
71
|
let test1;
|
|
62
72
|
let test2;
|
|
73
|
+
let locusInfo;
|
|
63
74
|
|
|
64
75
|
describe('meetings index', () => {
|
|
65
76
|
beforeEach(() => {
|
|
66
77
|
MeetingsUtil.checkH264Support = sinon.stub();
|
|
67
|
-
|
|
78
|
+
uuid1 = uuid.v4();
|
|
68
79
|
url1 = `https://example.com/${uuid.v4()}`;
|
|
69
80
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
70
81
|
test1 = `test-${uuid.v4()}`;
|
|
71
82
|
test2 = `test2-${uuid.v4()}`;
|
|
83
|
+
locusInfo = {
|
|
84
|
+
parse: sinon.stub().returns(true),
|
|
85
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
86
|
+
};
|
|
72
87
|
webex = new MockWebex({
|
|
73
88
|
children: {
|
|
74
89
|
device: Device,
|
|
@@ -151,6 +166,10 @@ describe('plugin-meetings', () => {
|
|
|
151
166
|
webex.emit('ready');
|
|
152
167
|
});
|
|
153
168
|
|
|
169
|
+
afterEach(() => {
|
|
170
|
+
sinon.restore();
|
|
171
|
+
});
|
|
172
|
+
|
|
154
173
|
it('has a webex instance with a meetings property', () => {
|
|
155
174
|
assert.exists(webex, 'webex was initialized with children');
|
|
156
175
|
assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
|
|
@@ -338,37 +357,113 @@ describe('plugin-meetings', () => {
|
|
|
338
357
|
});
|
|
339
358
|
});
|
|
340
359
|
|
|
360
|
+
describe('virtual background effect', () => {
|
|
361
|
+
beforeEach(() => {
|
|
362
|
+
webex.credentials = {
|
|
363
|
+
supertoken: {
|
|
364
|
+
access_token: "fake_token"
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
it('creates background effect', async () => {
|
|
370
|
+
const result = await webex.meetings.createVirtualBackgroundEffect();
|
|
371
|
+
|
|
372
|
+
assert.exists(result);
|
|
373
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
374
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
375
|
+
assert.deepEqual(result.options, {
|
|
376
|
+
mode: 'BLUR',
|
|
377
|
+
blurStrength: 'STRONG',
|
|
378
|
+
generator: 'worker',
|
|
379
|
+
quality: 'LOW',
|
|
380
|
+
authToken: 'fake_token',
|
|
381
|
+
mirror: false
|
|
382
|
+
});
|
|
383
|
+
assert.exists(result.enable);
|
|
384
|
+
assert.exists(result.disable);
|
|
385
|
+
assert.exists(result.dispose);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('creates background effect with custom options passed', async () => {
|
|
389
|
+
const effectOptions = {
|
|
390
|
+
generator: "local",
|
|
391
|
+
frameRate: 45,
|
|
392
|
+
mode: "IMAGE",
|
|
393
|
+
mirror: false,
|
|
394
|
+
quality: "HIGH",
|
|
395
|
+
blurStrength: "STRONG",
|
|
396
|
+
bgImageUrl: "https://test.webex.com/landscape.5a535788.jpg",
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const result = await webex.meetings.createVirtualBackgroundEffect(effectOptions);
|
|
400
|
+
|
|
401
|
+
assert.exists(result);
|
|
402
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
403
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
404
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: "fake_token"});
|
|
405
|
+
assert.exists(result.enable);
|
|
406
|
+
assert.exists(result.disable);
|
|
407
|
+
assert.exists(result.dispose);
|
|
408
|
+
});
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
describe('noise reduction effect', () => {
|
|
412
|
+
beforeEach(() => {
|
|
413
|
+
webex.credentials = {
|
|
414
|
+
supertoken: {
|
|
415
|
+
access_token: "fake_token"
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
})
|
|
419
|
+
|
|
420
|
+
it('creates noise reduction effect', async () => {
|
|
421
|
+
const result = await webex.meetings.createNoiseReductionEffect({audioContext: {}});
|
|
422
|
+
|
|
423
|
+
assert.exists(result);
|
|
424
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
425
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
426
|
+
assert.deepEqual(result.options, {
|
|
427
|
+
authToken: 'fake_token',
|
|
428
|
+
audioContext: {}
|
|
429
|
+
});
|
|
430
|
+
assert.exists(result.enable);
|
|
431
|
+
assert.exists(result.disable);
|
|
432
|
+
assert.exists(result.dispose);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('creates noise reduction effect with custom options passed', async () => {
|
|
436
|
+
const effectOptions = {
|
|
437
|
+
audioContext: {},
|
|
438
|
+
mode: "WORKLET",
|
|
439
|
+
env: "prod"
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const result = await webex.meetings.createNoiseReductionEffect(effectOptions);
|
|
443
|
+
|
|
444
|
+
assert.exists(result);
|
|
445
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
446
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
447
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: "fake_token"});
|
|
448
|
+
assert.exists(result.enable);
|
|
449
|
+
assert.exists(result.disable);
|
|
450
|
+
assert.exists(result.dispose);
|
|
451
|
+
});
|
|
452
|
+
})
|
|
453
|
+
|
|
341
454
|
describe('gets', () => {
|
|
342
455
|
describe('#getReachability', () => {
|
|
343
456
|
it('should have #getReachability', () => {
|
|
344
457
|
assert.exists(webex.meetings.getReachability);
|
|
345
458
|
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const reachability = webex.meetings.getReachability();
|
|
459
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
460
|
+
const reachability = webex.meetings.getReachability();
|
|
349
461
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
});
|
|
356
|
-
describe('after #setReachability', () => {
|
|
357
|
-
beforeEach(() => {
|
|
358
|
-
webex.meetings.setReachability();
|
|
359
|
-
const reachabilityMocker = webex.meetings.getReachability();
|
|
360
|
-
|
|
361
|
-
sinon.stub(reachabilityMocker, 'gatherReachability').returns(true);
|
|
362
|
-
});
|
|
363
|
-
it('gets the reachability data instance from webex.meetings', () => {
|
|
364
|
-
const reachability = webex.meetings.getReachability();
|
|
365
|
-
|
|
366
|
-
assert.exists(
|
|
367
|
-
reachability,
|
|
368
|
-
'reachability is defined because #setReachability has been called'
|
|
369
|
-
);
|
|
370
|
-
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
371
|
-
});
|
|
462
|
+
assert.exists(
|
|
463
|
+
reachability,
|
|
464
|
+
'reachability is defined'
|
|
465
|
+
);
|
|
466
|
+
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
372
467
|
});
|
|
373
468
|
});
|
|
374
469
|
describe('#getPersonalMeetingRoom', () => {
|
|
@@ -443,21 +538,17 @@ describe('plugin-meetings', () => {
|
|
|
443
538
|
);
|
|
444
539
|
});
|
|
445
540
|
describe('when meeting is returned', () => {
|
|
446
|
-
let parse;
|
|
447
541
|
|
|
448
542
|
beforeEach(() => {
|
|
449
|
-
parse = sinon.stub().returns(true);
|
|
450
543
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
451
|
-
locusInfo
|
|
452
|
-
parse,
|
|
453
|
-
},
|
|
544
|
+
locusInfo,
|
|
454
545
|
});
|
|
455
546
|
});
|
|
456
547
|
it('tests the sync meeting calls for existing meeting', async () => {
|
|
457
548
|
await webex.meetings.syncMeetings();
|
|
458
549
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
459
550
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
460
|
-
assert.calledOnce(parse);
|
|
551
|
+
assert.calledOnce(locusInfo.parse);
|
|
461
552
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
462
553
|
});
|
|
463
554
|
});
|
|
@@ -470,6 +561,7 @@ describe('plugin-meetings', () => {
|
|
|
470
561
|
webex.meetings.create = sinon.stub().returns(
|
|
471
562
|
Promise.resolve({
|
|
472
563
|
locusInfo: {
|
|
564
|
+
...locusInfo,
|
|
473
565
|
initialSetup,
|
|
474
566
|
},
|
|
475
567
|
})
|
|
@@ -478,7 +570,7 @@ describe('plugin-meetings', () => {
|
|
|
478
570
|
it('tests the sync meeting calls for not existing meeting', async () => {
|
|
479
571
|
await webex.meetings.syncMeetings();
|
|
480
572
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
481
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
573
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
482
574
|
assert.calledOnce(initialSetup);
|
|
483
575
|
assert.calledOnce(webex.meetings.create);
|
|
484
576
|
assert.calledWith(webex.meetings.request.getActiveMeetings);
|
|
@@ -502,12 +594,9 @@ describe('plugin-meetings', () => {
|
|
|
502
594
|
|
|
503
595
|
beforeEach(() => {
|
|
504
596
|
destroySpy = sinon.spy(webex.meetings, 'destroy');
|
|
505
|
-
parse = sinon.stub().returns(true);
|
|
506
597
|
initialSetup = sinon.stub().returns(true);
|
|
507
598
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
508
|
-
locusInfo
|
|
509
|
-
parse,
|
|
510
|
-
},
|
|
599
|
+
locusInfo,
|
|
511
600
|
sendCallAnalyzerMetrics: sinon.stub(),
|
|
512
601
|
});
|
|
513
602
|
webex.meetings.meetingCollection.getAll = sinon.stub().returns({
|
|
@@ -574,14 +663,41 @@ describe('plugin-meetings', () => {
|
|
|
574
663
|
});
|
|
575
664
|
});
|
|
576
665
|
|
|
666
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
667
|
+
const correlationId = 'my-correlationId';
|
|
668
|
+
|
|
669
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
670
|
+
const create = webex.meetings.create(...createParameters);
|
|
671
|
+
|
|
672
|
+
assert.exists(create.then);
|
|
673
|
+
await create;
|
|
674
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
675
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
676
|
+
}
|
|
677
|
+
|
|
577
678
|
it('calls createMeeting and returns its promise', async () => {
|
|
578
|
-
|
|
579
|
-
|
|
679
|
+
checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true]);
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
683
|
+
checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]);
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
687
|
+
checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
691
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
692
|
+
const correlationId = 'my-correlationId';
|
|
693
|
+
|
|
694
|
+
const FAKE_INFO_EXTRA_PARAMS = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
|
|
695
|
+
const create = webex.meetings.create(test1, test2, FAKE_USE_RANDOM_DELAY, FAKE_INFO_EXTRA_PARAMS, correlationId);
|
|
580
696
|
|
|
581
697
|
assert.exists(create.then);
|
|
582
698
|
await create;
|
|
583
699
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
584
|
-
assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY);
|
|
700
|
+
assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY, FAKE_INFO_EXTRA_PARAMS, correlationId);
|
|
585
701
|
});
|
|
586
702
|
|
|
587
703
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -677,45 +793,52 @@ describe('plugin-meetings', () => {
|
|
|
677
793
|
});
|
|
678
794
|
describe('#handleLocusEvent', () => {
|
|
679
795
|
describe('there was a meeting', () => {
|
|
680
|
-
let parse;
|
|
681
796
|
|
|
682
797
|
beforeEach(() => {
|
|
683
|
-
parse = sinon.stub().returns(true);
|
|
684
798
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
685
|
-
locusInfo
|
|
686
|
-
parse,
|
|
687
|
-
},
|
|
799
|
+
locusInfo,
|
|
688
800
|
});
|
|
689
801
|
});
|
|
690
|
-
it('should parse the meeting info', () => {
|
|
802
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
803
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
691
804
|
webex.meetings.handleLocusEvent({
|
|
692
805
|
locusUrl: url1,
|
|
693
806
|
});
|
|
694
807
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
695
808
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
696
|
-
assert.calledOnce(parse);
|
|
809
|
+
assert.calledOnce(locusInfo.parse);
|
|
810
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
697
811
|
assert.calledWith(
|
|
698
|
-
parse,
|
|
812
|
+
locusInfo.parse,
|
|
699
813
|
{
|
|
700
|
-
locusInfo
|
|
701
|
-
parse,
|
|
702
|
-
},
|
|
814
|
+
locusInfo,
|
|
703
815
|
},
|
|
704
816
|
{
|
|
705
817
|
locusUrl: url1,
|
|
706
818
|
}
|
|
707
819
|
);
|
|
708
820
|
});
|
|
821
|
+
|
|
822
|
+
it('should not update main session locus cache', () => {
|
|
823
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
824
|
+
webex.meetings.handleLocusEvent({
|
|
825
|
+
locusUrl: url1,
|
|
826
|
+
});
|
|
827
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
828
|
+
});
|
|
709
829
|
});
|
|
710
830
|
describe('there was not a meeting', () => {
|
|
711
831
|
let initialSetup;
|
|
832
|
+
const webExMeetingId = '123456';
|
|
712
833
|
|
|
713
834
|
beforeEach(() => {
|
|
714
835
|
initialSetup = sinon.stub().returns(true);
|
|
715
836
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
716
837
|
webex.meetings.create = sinon.stub().returns(
|
|
717
838
|
Promise.resolve({
|
|
839
|
+
id: 'meeting-id',
|
|
718
840
|
locusInfo: {
|
|
841
|
+
...locusInfo,
|
|
719
842
|
initialSetup,
|
|
720
843
|
},
|
|
721
844
|
})
|
|
@@ -735,12 +858,16 @@ describe('plugin-meetings', () => {
|
|
|
735
858
|
callbackAddress: uri1,
|
|
736
859
|
},
|
|
737
860
|
},
|
|
861
|
+
info: {
|
|
862
|
+
webExMeetingId
|
|
863
|
+
},
|
|
738
864
|
},
|
|
739
865
|
eventType: 'locus.difference',
|
|
740
866
|
locusUrl: url1,
|
|
741
867
|
});
|
|
742
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
868
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
743
869
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
870
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
|
|
744
871
|
assert.calledOnce(initialSetup);
|
|
745
872
|
assert.calledWith(initialSetup, {
|
|
746
873
|
id: uuid1,
|
|
@@ -754,6 +881,9 @@ describe('plugin-meetings', () => {
|
|
|
754
881
|
callbackAddress: uri1,
|
|
755
882
|
},
|
|
756
883
|
},
|
|
884
|
+
info: {
|
|
885
|
+
webExMeetingId
|
|
886
|
+
},
|
|
757
887
|
});
|
|
758
888
|
});
|
|
759
889
|
it('should setup the meeting by difference event without replaces', async () => {
|
|
@@ -765,12 +895,16 @@ describe('plugin-meetings', () => {
|
|
|
765
895
|
callbackAddress: uri1,
|
|
766
896
|
},
|
|
767
897
|
},
|
|
898
|
+
info: {
|
|
899
|
+
webExMeetingId
|
|
900
|
+
},
|
|
768
901
|
},
|
|
769
902
|
eventType: 'locus.difference',
|
|
770
903
|
locusUrl: url1,
|
|
771
904
|
});
|
|
772
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
905
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
773
906
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
907
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
|
|
774
908
|
assert.calledOnce(initialSetup);
|
|
775
909
|
assert.calledWith(initialSetup, {
|
|
776
910
|
id: uuid1,
|
|
@@ -779,8 +913,44 @@ describe('plugin-meetings', () => {
|
|
|
779
913
|
callbackAddress: uri1,
|
|
780
914
|
},
|
|
781
915
|
},
|
|
916
|
+
info: {
|
|
917
|
+
webExMeetingId
|
|
918
|
+
},
|
|
919
|
+
});
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
it('sends client event correctly on finally', async () => {
|
|
923
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
924
|
+
|
|
925
|
+
await webex.meetings.handleLocusEvent({
|
|
926
|
+
locus: {
|
|
927
|
+
id: uuid1,
|
|
928
|
+
self: {
|
|
929
|
+
callBackInfo: {
|
|
930
|
+
callbackAddress: uri1,
|
|
931
|
+
},
|
|
932
|
+
},
|
|
933
|
+
info: {
|
|
934
|
+
webExMeetingId,
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
eventType: 'locus.difference',
|
|
938
|
+
locusUrl: url1,
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
await testUtils.flushPromises();
|
|
942
|
+
|
|
943
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
944
|
+
name: 'client.call.remote-started',
|
|
945
|
+
payload: {
|
|
946
|
+
trigger: 'mercury-event',
|
|
947
|
+
},
|
|
948
|
+
options: {
|
|
949
|
+
meetingId: 'meeting-id',
|
|
950
|
+
},
|
|
782
951
|
});
|
|
783
952
|
});
|
|
953
|
+
|
|
784
954
|
it('should setup the meeting by a not difference event', async () => {
|
|
785
955
|
await webex.meetings.handleLocusEvent({
|
|
786
956
|
locus: {
|
|
@@ -790,12 +960,16 @@ describe('plugin-meetings', () => {
|
|
|
790
960
|
callbackAddress: uri1,
|
|
791
961
|
},
|
|
792
962
|
},
|
|
963
|
+
info: {
|
|
964
|
+
webExMeetingId
|
|
965
|
+
},
|
|
793
966
|
},
|
|
794
967
|
eventType: test1,
|
|
795
968
|
locusUrl: url1,
|
|
796
969
|
});
|
|
797
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
970
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
798
971
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
972
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
|
|
799
973
|
assert.calledOnce(initialSetup);
|
|
800
974
|
assert.calledWith(initialSetup, {
|
|
801
975
|
id: uuid1,
|
|
@@ -804,6 +978,9 @@ describe('plugin-meetings', () => {
|
|
|
804
978
|
callbackAddress: uri1,
|
|
805
979
|
},
|
|
806
980
|
},
|
|
981
|
+
info: {
|
|
982
|
+
webExMeetingId
|
|
983
|
+
},
|
|
807
984
|
});
|
|
808
985
|
});
|
|
809
986
|
|
|
@@ -826,7 +1003,7 @@ describe('plugin-meetings', () => {
|
|
|
826
1003
|
|
|
827
1004
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
828
1005
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
|
|
829
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1006
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
830
1007
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
831
1008
|
'locusUrl',
|
|
832
1009
|
url1,
|
|
@@ -843,7 +1020,7 @@ describe('plugin-meetings', () => {
|
|
|
843
1020
|
});
|
|
844
1021
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
845
1022
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
|
|
846
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1023
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
847
1024
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
848
1025
|
'locusUrl',
|
|
849
1026
|
url1,
|
|
@@ -874,6 +1051,7 @@ describe('plugin-meetings', () => {
|
|
|
874
1051
|
});
|
|
875
1052
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
876
1053
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1054
|
+
const FAKE_INFO_EXTRA_PARAMS = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
|
|
877
1055
|
|
|
878
1056
|
beforeEach(() => {
|
|
879
1057
|
clock = sinon.useFakeTimers();
|
|
@@ -903,13 +1081,15 @@ describe('plugin-meetings', () => {
|
|
|
903
1081
|
meeting,
|
|
904
1082
|
destination,
|
|
905
1083
|
type,
|
|
906
|
-
|
|
1084
|
+
extraParams = {},
|
|
1085
|
+
expectedMeetingData = {},
|
|
1086
|
+
sendCAevents = false,
|
|
907
1087
|
) => {
|
|
908
1088
|
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
909
1089
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
910
1090
|
assert.notCalled(setTimeoutSpy);
|
|
911
|
-
assert.
|
|
912
|
-
assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, destination, type);
|
|
1091
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1092
|
+
assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, destination, type, null, null, undefined, undefined, extraParams, {meetingId: meeting.id, sendCAevents});
|
|
913
1093
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
914
1094
|
|
|
915
1095
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -918,6 +1098,9 @@ describe('plugin-meetings', () => {
|
|
|
918
1098
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
919
1099
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
920
1100
|
}
|
|
1101
|
+
if(expectedMeetingData.correlationId) {
|
|
1102
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1103
|
+
}
|
|
921
1104
|
assert.equal(meeting.destination, destination);
|
|
922
1105
|
assert.equal(meeting.destinationType, type);
|
|
923
1106
|
assert.calledWith(
|
|
@@ -947,108 +1130,119 @@ describe('plugin-meetings', () => {
|
|
|
947
1130
|
const expectedMeetingData = {
|
|
948
1131
|
permissionToken: 'PT',
|
|
949
1132
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
1133
|
+
correlationId: meeting.id,
|
|
950
1134
|
};
|
|
951
1135
|
|
|
952
|
-
checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
|
|
1136
|
+
checkCreateWithoutDelay(meeting, 'test destination', 'test type', {}, expectedMeetingData);
|
|
953
1137
|
});
|
|
954
1138
|
|
|
955
|
-
|
|
956
|
-
const
|
|
957
|
-
const expectedMeetingData = {
|
|
958
|
-
permissionToken: 'PT',
|
|
959
|
-
meetingJoinUrl: 'meetingJoinUrl',
|
|
960
|
-
};
|
|
1139
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1140
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
961
1141
|
|
|
962
|
-
|
|
963
|
-
meeting,
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
});
|
|
1142
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
|
|
1143
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type', false, infoExtraParams);
|
|
1144
|
+
const expectedMeetingData = {
|
|
1145
|
+
permissionToken: 'PT',
|
|
1146
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1147
|
+
};
|
|
969
1148
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
owner: 'locusOwner',
|
|
978
|
-
},
|
|
979
|
-
meeting: {
|
|
980
|
-
startTime: fakeMeetingStartTimeString,
|
|
981
|
-
},
|
|
982
|
-
fullState: {
|
|
983
|
-
active: false,
|
|
984
|
-
},
|
|
985
|
-
};
|
|
1149
|
+
assert.instanceOf(
|
|
1150
|
+
meeting,
|
|
1151
|
+
Meeting,
|
|
1152
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1153
|
+
);
|
|
1154
|
+
checkCreateWithoutDelay(meeting, 'test destination', 'test type', infoExtraParamsProvided ? infoExtraParams : {}, expectedMeetingData);
|
|
1155
|
+
});
|
|
986
1156
|
|
|
987
|
-
|
|
988
|
-
FAKE_LOCUS_MEETING
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1157
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
|
|
1158
|
+
const FAKE_LOCUS_MEETING = {
|
|
1159
|
+
conversationUrl: 'locusConvURL',
|
|
1160
|
+
url: 'locusUrl',
|
|
1161
|
+
info: {
|
|
1162
|
+
webExMeetingId: 'locusMeetingId',
|
|
1163
|
+
sipUri: 'locusSipUri',
|
|
1164
|
+
owner: 'locusOwner',
|
|
1165
|
+
},
|
|
1166
|
+
meeting: {
|
|
1167
|
+
startTime: fakeMeetingStartTimeString,
|
|
1168
|
+
},
|
|
1169
|
+
fullState: {
|
|
1170
|
+
active: false,
|
|
1171
|
+
},
|
|
1172
|
+
};
|
|
992
1173
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
assert.calledOnce(setTimeoutSpy);
|
|
1000
|
-
|
|
1001
|
-
// Parse meeting info with locus object
|
|
1002
|
-
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1003
|
-
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1004
|
-
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1005
|
-
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1006
|
-
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1007
|
-
assert.equal(meeting.owner, 'locusOwner');
|
|
1008
|
-
assert.isUndefined(meeting.permissionToken);
|
|
1009
|
-
|
|
1010
|
-
// Add meeting and send trigger
|
|
1011
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1012
|
-
assert.calledTwice(TriggerProxy.trigger);
|
|
1013
|
-
assert.calledWith(
|
|
1014
|
-
TriggerProxy.trigger,
|
|
1015
|
-
sinon.match.instanceOf(Meetings),
|
|
1016
|
-
{
|
|
1017
|
-
file: 'meetings',
|
|
1018
|
-
function: 'createMeeting',
|
|
1019
|
-
},
|
|
1020
|
-
'meeting:added',
|
|
1021
|
-
{
|
|
1022
|
-
meeting: sinon.match.instanceOf(Meeting),
|
|
1023
|
-
type: 'test meeting added type',
|
|
1024
|
-
}
|
|
1025
|
-
);
|
|
1174
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1175
|
+
FAKE_LOCUS_MEETING,
|
|
1176
|
+
'test type',
|
|
1177
|
+
true,
|
|
1178
|
+
infoExtraParams
|
|
1179
|
+
);
|
|
1026
1180
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1181
|
+
assert.instanceOf(
|
|
1182
|
+
meeting,
|
|
1183
|
+
Meeting,
|
|
1184
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1185
|
+
);
|
|
1186
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1187
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1188
|
+
|
|
1189
|
+
// Parse meeting info with locus object
|
|
1190
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1191
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1192
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1193
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1194
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1195
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1196
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1197
|
+
|
|
1198
|
+
// Add meeting and send trigger
|
|
1199
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1200
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1201
|
+
assert.calledWith(
|
|
1202
|
+
TriggerProxy.trigger,
|
|
1203
|
+
sinon.match.instanceOf(Meetings),
|
|
1204
|
+
{
|
|
1205
|
+
file: 'meetings',
|
|
1206
|
+
function: 'createMeeting',
|
|
1207
|
+
},
|
|
1208
|
+
'meeting:added',
|
|
1209
|
+
{
|
|
1210
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1211
|
+
type: 'test meeting added type',
|
|
1212
|
+
}
|
|
1213
|
+
);
|
|
1034
1214
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1215
|
+
// When timer expires
|
|
1216
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1217
|
+
assert.calledWith(
|
|
1218
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1219
|
+
FAKE_LOCUS_MEETING,
|
|
1220
|
+
'test type',
|
|
1221
|
+
null,
|
|
1222
|
+
null,
|
|
1223
|
+
undefined,
|
|
1224
|
+
undefined,
|
|
1225
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1226
|
+
);
|
|
1044
1227
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
meeting,
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1228
|
+
// Parse meeting info is called again with new meeting info
|
|
1229
|
+
await testUtils.flushPromises();
|
|
1230
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1231
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1232
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1233
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1234
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1235
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1236
|
+
assert.equal(meeting.permissionToken, 'PT');
|
|
1237
|
+
|
|
1238
|
+
assert.calledWith(
|
|
1239
|
+
TriggerProxy.trigger,
|
|
1240
|
+
meeting,
|
|
1241
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1242
|
+
'meeting:meetingInfoAvailable'
|
|
1243
|
+
);
|
|
1244
|
+
});
|
|
1245
|
+
})
|
|
1052
1246
|
|
|
1053
1247
|
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
1054
1248
|
const FAKE_LOCUS_MEETING = {
|
|
@@ -1147,6 +1341,16 @@ describe('plugin-meetings', () => {
|
|
|
1147
1341
|
);
|
|
1148
1342
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1149
1343
|
});
|
|
1344
|
+
|
|
1345
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1346
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type', false, {}, 'my-correlationId');
|
|
1347
|
+
|
|
1348
|
+
const expectedMeetingData = {
|
|
1349
|
+
correlationId: 'my-correlationId',
|
|
1350
|
+
};
|
|
1351
|
+
|
|
1352
|
+
checkCreateWithoutDelay(meeting, 'test destination', 'test type', {}, expectedMeetingData, true);
|
|
1353
|
+
})
|
|
1150
1354
|
});
|
|
1151
1355
|
|
|
1152
1356
|
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
@@ -1156,38 +1360,121 @@ describe('plugin-meetings', () => {
|
|
|
1156
1360
|
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1157
1361
|
.stub()
|
|
1158
1362
|
.returns(Promise.reject(new Error('test')));
|
|
1363
|
+
webex.meetings.destroy = sinon
|
|
1364
|
+
.stub()
|
|
1365
|
+
.returns(Promise.resolve());
|
|
1366
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1159
1367
|
});
|
|
1368
|
+
|
|
1369
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1370
|
+
try {
|
|
1371
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type', undefined, undefined, undefined, failOnMissingMeetingInfo);
|
|
1372
|
+
|
|
1373
|
+
assert.instanceOf(
|
|
1374
|
+
meeting,
|
|
1375
|
+
Meeting,
|
|
1376
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1377
|
+
);
|
|
1378
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1379
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1380
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1381
|
+
assert.calledWith(
|
|
1382
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1383
|
+
'test destination',
|
|
1384
|
+
'test type'
|
|
1385
|
+
);
|
|
1386
|
+
|
|
1387
|
+
if (destroy) {
|
|
1388
|
+
assert.calledWith(webex.meetings.destroy, sinon.match.instanceOf(Meeting), 'MISSING_MEETING_INFO')
|
|
1389
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1390
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1391
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1392
|
+
} else {
|
|
1393
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1394
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1395
|
+
assert.calledWith(
|
|
1396
|
+
TriggerProxy.trigger,
|
|
1397
|
+
sinon.match.instanceOf(Meetings),
|
|
1398
|
+
{
|
|
1399
|
+
file: 'meetings',
|
|
1400
|
+
function: 'createMeeting',
|
|
1401
|
+
},
|
|
1402
|
+
'meeting:added',
|
|
1403
|
+
{
|
|
1404
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1405
|
+
type: 'test meeting added type',
|
|
1406
|
+
}
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
} catch (err) {
|
|
1410
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1160
1414
|
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1161
|
-
|
|
1415
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1416
|
+
});
|
|
1162
1417
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
assert.calledWith(
|
|
1172
|
-
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1173
|
-
'test destination',
|
|
1174
|
-
'test type'
|
|
1175
|
-
);
|
|
1176
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1177
|
-
assert.calledWith(
|
|
1178
|
-
TriggerProxy.trigger,
|
|
1179
|
-
sinon.match.instanceOf(Meetings),
|
|
1418
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1419
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1420
|
+
});
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1423
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1424
|
+
forEach(
|
|
1425
|
+
[
|
|
1180
1426
|
{
|
|
1181
|
-
|
|
1182
|
-
|
|
1427
|
+
error: new CaptchaError(),
|
|
1428
|
+
debugLogMessage:
|
|
1429
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1183
1430
|
},
|
|
1184
|
-
'meeting:added',
|
|
1185
1431
|
{
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1432
|
+
error: new PasswordError(),
|
|
1433
|
+
debugLogMessage:
|
|
1434
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
error: new PermissionError(),
|
|
1438
|
+
debugLogMessage:
|
|
1439
|
+
'Meetings:index#createMeeting --> Debug PermissionError: Not allowed to execute the function, some properties on server, or local client state do not allow you to complete this action. fetching /meetingInfo for creation.',
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
error: new Error(),
|
|
1443
|
+
infoLogMessage: true,
|
|
1444
|
+
debugLogMessage:
|
|
1445
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1446
|
+
},
|
|
1447
|
+
],
|
|
1448
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1449
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1450
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1451
|
+
.stub()
|
|
1452
|
+
.returns(Promise.reject(error));
|
|
1453
|
+
|
|
1454
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1455
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1456
|
+
|
|
1457
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1458
|
+
|
|
1459
|
+
assert.instanceOf(
|
|
1460
|
+
meeting,
|
|
1461
|
+
Meeting,
|
|
1462
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1463
|
+
);
|
|
1464
|
+
|
|
1465
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1466
|
+
|
|
1467
|
+
if (infoLogMessage) {
|
|
1468
|
+
assert.calledWith(
|
|
1469
|
+
LoggerProxy.logger.info,
|
|
1470
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1471
|
+
);
|
|
1472
|
+
} else {
|
|
1473
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1474
|
+
}
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
);
|
|
1191
1478
|
});
|
|
1192
1479
|
});
|
|
1193
1480
|
});
|
|
@@ -1267,6 +1554,9 @@ describe('plugin-meetings', () => {
|
|
|
1267
1554
|
});
|
|
1268
1555
|
|
|
1269
1556
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1557
|
+
|
|
1558
|
+
let loggerProxySpy;
|
|
1559
|
+
|
|
1270
1560
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1271
1561
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1272
1562
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1274,7 +1564,24 @@ describe('plugin-meetings', () => {
|
|
|
1274
1564
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1275
1565
|
});
|
|
1276
1566
|
|
|
1567
|
+
const setup = ({user} = {}) => {
|
|
1568
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1569
|
+
|
|
1570
|
+
Object.assign(webex.internal, {
|
|
1571
|
+
services: {
|
|
1572
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1573
|
+
},
|
|
1574
|
+
user: {
|
|
1575
|
+
get: sinon.stub().returns(
|
|
1576
|
+
Promise.resolve(user)
|
|
1577
|
+
),
|
|
1578
|
+
},
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1277
1582
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1583
|
+
setup();
|
|
1584
|
+
|
|
1278
1585
|
Object.assign(webex.internal, {
|
|
1279
1586
|
services: {
|
|
1280
1587
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
@@ -1284,7 +1591,62 @@ describe('plugin-meetings', () => {
|
|
|
1284
1591
|
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1285
1592
|
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1286
1593
|
});
|
|
1594
|
+
assert.calledOnceWithExactly(
|
|
1595
|
+
loggerProxySpy,
|
|
1596
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1597
|
+
);
|
|
1598
|
+
});
|
|
1599
|
+
|
|
1600
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1601
|
+
setup({
|
|
1602
|
+
user: {
|
|
1603
|
+
userPreferences: {
|
|
1604
|
+
userPreferencesItems: {
|
|
1605
|
+
preferredWebExSite: 'site.webex.com',
|
|
1606
|
+
},
|
|
1607
|
+
},
|
|
1608
|
+
},
|
|
1609
|
+
});
|
|
1610
|
+
|
|
1611
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1612
|
+
|
|
1613
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1614
|
+
assert.notCalled(loggerProxySpy);
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1617
|
+
forEach([
|
|
1618
|
+
{user: undefined},
|
|
1619
|
+
{user: {userPreferences: {}}},
|
|
1620
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1621
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1622
|
+
], ({user}) => {
|
|
1623
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1624
|
+
setup({user});
|
|
1625
|
+
|
|
1626
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1627
|
+
|
|
1628
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1629
|
+
assert.calledOnceWithExactly(
|
|
1630
|
+
loggerProxySpy,
|
|
1631
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1632
|
+
);
|
|
1633
|
+
});
|
|
1634
|
+
});
|
|
1635
|
+
|
|
1636
|
+
it('should handle a get user failure', async () => {
|
|
1637
|
+
setup();
|
|
1638
|
+
|
|
1639
|
+
webex.internal.user.get.rejects(new Error());
|
|
1640
|
+
|
|
1641
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1642
|
+
|
|
1643
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1644
|
+
assert.calledOnceWithExactly(
|
|
1645
|
+
loggerProxySpy,
|
|
1646
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1647
|
+
);
|
|
1287
1648
|
});
|
|
1649
|
+
|
|
1288
1650
|
});
|
|
1289
1651
|
});
|
|
1290
1652
|
|
|
@@ -1368,5 +1730,473 @@ describe('plugin-meetings', () => {
|
|
|
1368
1730
|
);
|
|
1369
1731
|
});
|
|
1370
1732
|
});
|
|
1733
|
+
|
|
1734
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
1735
|
+
let meeting;
|
|
1736
|
+
let newLocus;
|
|
1737
|
+
beforeEach(() => {
|
|
1738
|
+
meeting = {
|
|
1739
|
+
controls: {},
|
|
1740
|
+
self: {},
|
|
1741
|
+
};
|
|
1742
|
+
newLocus = {
|
|
1743
|
+
controls: {},
|
|
1744
|
+
self: {},
|
|
1745
|
+
}
|
|
1746
|
+
});
|
|
1747
|
+
afterEach(() => {
|
|
1748
|
+
sinon.restore();
|
|
1749
|
+
});
|
|
1750
|
+
it('check normal case will return true', () => {
|
|
1751
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1752
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1753
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1754
|
+
assert.equal(result, true);
|
|
1755
|
+
assert.calledWith(
|
|
1756
|
+
LoggerProxy.logger.log,
|
|
1757
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1758
|
+
);
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
it('check self joined and joined on this device, return true', () => {
|
|
1762
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1763
|
+
newLocus.self.state = 'JOINED';
|
|
1764
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1765
|
+
|
|
1766
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1767
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1768
|
+
assert.equal(result, true);
|
|
1769
|
+
assert.calledWith(
|
|
1770
|
+
LoggerProxy.logger.log,
|
|
1771
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
1772
|
+
);
|
|
1773
|
+
});
|
|
1774
|
+
|
|
1775
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
1776
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({joinedWith: {replaces: [{
|
|
1777
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
1778
|
+
}]}});
|
|
1779
|
+
newLocus.self.state = 'JOINED';
|
|
1780
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1781
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1782
|
+
replaces: [{
|
|
1783
|
+
replaceAt: '2023-03-27T02:17:01.506Z'
|
|
1784
|
+
}]
|
|
1785
|
+
})
|
|
1786
|
+
|
|
1787
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1788
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1789
|
+
assert.equal(result, false);
|
|
1790
|
+
assert.calledWith(
|
|
1791
|
+
LoggerProxy.logger.log,
|
|
1792
|
+
`Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt 2023-03-27T02:17:01.506Z bo replacedAt 2023-03-27T02:17:02.506Z`
|
|
1793
|
+
);
|
|
1794
|
+
});
|
|
1795
|
+
|
|
1796
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
1797
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1798
|
+
joinedWith: {
|
|
1799
|
+
correlationId: '111',
|
|
1800
|
+
},
|
|
1801
|
+
});
|
|
1802
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
1803
|
+
meeting.correlationId = '111';
|
|
1804
|
+
|
|
1805
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1806
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1807
|
+
assert.equal(result, false);
|
|
1808
|
+
assert.calledWith(
|
|
1809
|
+
LoggerProxy.logger.log,
|
|
1810
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
1811
|
+
);
|
|
1812
|
+
});
|
|
1813
|
+
|
|
1814
|
+
it('check self is moved and removed, return false', () => {
|
|
1815
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1816
|
+
newLocus.self.state = 'LEFT';
|
|
1817
|
+
newLocus.self.reason = 'MOVED';
|
|
1818
|
+
newLocus.self.removed = true;
|
|
1819
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1820
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1821
|
+
assert.equal(result, false);
|
|
1822
|
+
assert.calledWith(
|
|
1823
|
+
LoggerProxy.logger.log,
|
|
1824
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1825
|
+
);
|
|
1826
|
+
});
|
|
1827
|
+
|
|
1828
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
1829
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1830
|
+
newLocus.self.state = 'LEFT';
|
|
1831
|
+
newLocus.self.reason = 'MOVED';
|
|
1832
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1833
|
+
state: 'LEFT',
|
|
1834
|
+
reason: 'MOVED',
|
|
1835
|
+
});
|
|
1836
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1837
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1838
|
+
assert.equal(result, false);
|
|
1839
|
+
assert.calledWith(
|
|
1840
|
+
LoggerProxy.logger.log,
|
|
1841
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1842
|
+
);
|
|
1843
|
+
});
|
|
1844
|
+
|
|
1845
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
1846
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1847
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
1848
|
+
newLocus.self.state = 'JOINED';
|
|
1849
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1850
|
+
state: 'LEFT',
|
|
1851
|
+
reason: 'MOVED',
|
|
1852
|
+
});
|
|
1853
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1854
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1855
|
+
assert.equal(result, false);
|
|
1856
|
+
assert.calledWith(
|
|
1857
|
+
LoggerProxy.logger.log,
|
|
1858
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
1859
|
+
);
|
|
1860
|
+
});
|
|
1861
|
+
});
|
|
1862
|
+
|
|
1863
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
1864
|
+
let meeting;
|
|
1865
|
+
let newLocus;
|
|
1866
|
+
beforeEach(() => {
|
|
1867
|
+
meeting = {
|
|
1868
|
+
controls: {},
|
|
1869
|
+
self: {},
|
|
1870
|
+
};
|
|
1871
|
+
newLocus = {
|
|
1872
|
+
controls: {},
|
|
1873
|
+
self: {},
|
|
1874
|
+
}
|
|
1875
|
+
});
|
|
1876
|
+
afterEach(() => {
|
|
1877
|
+
sinon.restore();
|
|
1878
|
+
});
|
|
1879
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
1880
|
+
newLocus.controls.breakout = {
|
|
1881
|
+
sessionType: 'BREAKOUT',
|
|
1882
|
+
};
|
|
1883
|
+
newLocus.self.state = 'JOINED';
|
|
1884
|
+
newLocus.fullState = {
|
|
1885
|
+
active: true,
|
|
1886
|
+
};
|
|
1887
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1888
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
1889
|
+
assert.equal(result, true);
|
|
1890
|
+
assert.calledWith(
|
|
1891
|
+
LoggerProxy.logger.log,
|
|
1892
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
1893
|
+
);
|
|
1894
|
+
});
|
|
1895
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
1896
|
+
newLocus.controls.breakout = {
|
|
1897
|
+
sessionType: 'MAIN',
|
|
1898
|
+
};
|
|
1899
|
+
newLocus.self.state = 'JOINED';
|
|
1900
|
+
|
|
1901
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1902
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
1903
|
+
assert.equal(result, true);
|
|
1904
|
+
assert.calledWith(
|
|
1905
|
+
LoggerProxy.logger.log,
|
|
1906
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1907
|
+
);
|
|
1908
|
+
});
|
|
1909
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
1910
|
+
newLocus.controls.breakout = {
|
|
1911
|
+
sessionType: 'BREAKOUT',
|
|
1912
|
+
};
|
|
1913
|
+
newLocus.self.state = 'LEFT';
|
|
1914
|
+
newLocus.self.reason = 'MOVED';
|
|
1915
|
+
|
|
1916
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1917
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
1918
|
+
assert.equal(result, false);
|
|
1919
|
+
});
|
|
1920
|
+
});
|
|
1921
|
+
|
|
1922
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
1923
|
+
let locus;
|
|
1924
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
1925
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
1926
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
1927
|
+
if (key === keyWillReturnMeeting) {
|
|
1928
|
+
return mockReturnMeeting;
|
|
1929
|
+
}
|
|
1930
|
+
return null;
|
|
1931
|
+
});
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1934
|
+
beforeEach(() => {
|
|
1935
|
+
locus = {
|
|
1936
|
+
controls: {},
|
|
1937
|
+
self: {
|
|
1938
|
+
callbackInfo: {
|
|
1939
|
+
callbackAddress: 'address1',
|
|
1940
|
+
}
|
|
1941
|
+
},
|
|
1942
|
+
info: {
|
|
1943
|
+
webExMeetingId: '123456',
|
|
1944
|
+
isUnifiedSpaceMeeting: false,
|
|
1945
|
+
},
|
|
1946
|
+
conversationUrl: 'conversationUrl1'
|
|
1947
|
+
};
|
|
1948
|
+
|
|
1949
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
1950
|
+
});
|
|
1951
|
+
afterEach(() => {
|
|
1952
|
+
sinon.restore();
|
|
1953
|
+
});
|
|
1954
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
1955
|
+
mockGetByKey();
|
|
1956
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1957
|
+
assert.isNull(result);
|
|
1958
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
1959
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1960
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1961
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
1962
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
|
|
1963
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
1964
|
+
});
|
|
1965
|
+
|
|
1966
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
1967
|
+
mockGetByKey();
|
|
1968
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
1969
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1970
|
+
assert.isNull(result);
|
|
1971
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
1972
|
+
})
|
|
1973
|
+
|
|
1974
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
1975
|
+
mockGetByKey('locusUrl');
|
|
1976
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1977
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1978
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
1979
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1980
|
+
});
|
|
1981
|
+
|
|
1982
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
1983
|
+
mockGetByKey('correlationId');
|
|
1984
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1985
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1986
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
1987
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1988
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1989
|
+
});
|
|
1990
|
+
|
|
1991
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
1992
|
+
mockGetByKey('sipUri');
|
|
1993
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1994
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1995
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
1996
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1997
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1998
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
1999
|
+
});
|
|
2000
|
+
|
|
2001
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
2002
|
+
mockGetByKey('conversationUrl');
|
|
2003
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2004
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2005
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2006
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2007
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
2008
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2009
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
|
|
2010
|
+
});
|
|
2011
|
+
|
|
2012
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
2013
|
+
mockGetByKey('meetingNumber');
|
|
2014
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2015
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2016
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2017
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2018
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
2019
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2020
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
|
|
2021
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2022
|
+
});
|
|
2023
|
+
});
|
|
2024
|
+
|
|
2025
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
2026
|
+
let lociArray;
|
|
2027
|
+
let mainLocus;
|
|
2028
|
+
let breakoutLocus;
|
|
2029
|
+
beforeEach(() => {
|
|
2030
|
+
mainLocus = {
|
|
2031
|
+
url: 'mainUrl1',
|
|
2032
|
+
controls: {
|
|
2033
|
+
breakout: {
|
|
2034
|
+
sessionType: 'MAIN',
|
|
2035
|
+
url: 'breakoutUnifiedUrl1'
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
breakoutLocus = {
|
|
2040
|
+
url: 'breakoutUrl1',
|
|
2041
|
+
controls: {
|
|
2042
|
+
breakout: {
|
|
2043
|
+
sessionType: 'BREAKOUT',
|
|
2044
|
+
url: 'breakoutUnifiedUrl1'
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
};
|
|
2048
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2049
|
+
|
|
2050
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2051
|
+
return locus.url === 'breakoutUrl1';
|
|
2052
|
+
});
|
|
2053
|
+
});
|
|
2054
|
+
afterEach(() => {
|
|
2055
|
+
sinon.restore();
|
|
2056
|
+
});
|
|
2057
|
+
|
|
2058
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2059
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2060
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2061
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2062
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2063
|
+
});
|
|
2064
|
+
|
|
2065
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2066
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2067
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2068
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2069
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2070
|
+
});
|
|
2071
|
+
|
|
2072
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2073
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2074
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2075
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2076
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2077
|
+
});
|
|
2078
|
+
});
|
|
2079
|
+
|
|
2080
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2081
|
+
let breakoutLocus;
|
|
2082
|
+
beforeEach(() => {
|
|
2083
|
+
breakoutLocus = {
|
|
2084
|
+
url: 'breakoutUrl1',
|
|
2085
|
+
controls: {
|
|
2086
|
+
breakout: {
|
|
2087
|
+
sessionType: 'BREAKOUT',
|
|
2088
|
+
url: 'breakoutUnifiedUrl1',
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2094
|
+
});
|
|
2095
|
+
afterEach(() => {
|
|
2096
|
+
sinon.restore();
|
|
2097
|
+
});
|
|
2098
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2099
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2100
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2101
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2102
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2103
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2104
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2105
|
+
});
|
|
2106
|
+
|
|
2107
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2108
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2109
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2110
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2111
|
+
});
|
|
2112
|
+
|
|
2113
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2114
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2115
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2116
|
+
controls: {
|
|
2117
|
+
breakout: {
|
|
2118
|
+
sessionType: 'MAIN',
|
|
2119
|
+
url: 'breakoutUnifiedUrl2',
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
});
|
|
2123
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2124
|
+
});
|
|
2125
|
+
|
|
2126
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2127
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2128
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2129
|
+
controls: {
|
|
2130
|
+
breakout: {
|
|
2131
|
+
sessionType: 'MAIN',
|
|
2132
|
+
url: 'breakoutUnifiedUrl1',
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
});
|
|
2136
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {locus: breakoutLocus, locusUrl: breakoutLocus.url});
|
|
2137
|
+
});
|
|
2138
|
+
});
|
|
2139
|
+
|
|
2140
|
+
describe('uploading of logs', () => {
|
|
2141
|
+
let metricsSpy;
|
|
2142
|
+
let meeting;
|
|
2143
|
+
|
|
2144
|
+
beforeEach(async () => {
|
|
2145
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2146
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2147
|
+
|
|
2148
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2149
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2150
|
+
|
|
2151
|
+
triggerProxyStub.restore();
|
|
2152
|
+
|
|
2153
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2154
|
+
|
|
2155
|
+
meeting = await webex.meetings.create('test');
|
|
2156
|
+
|
|
2157
|
+
meeting.locusId = 'locus id';
|
|
2158
|
+
meeting.correlationId = 'correlation id';
|
|
2159
|
+
meeting.locusInfo = {
|
|
2160
|
+
fullState: { lastActive: 'last active'},
|
|
2161
|
+
info: { webExMeetingId: 'meeting id'}
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
2164
|
+
|
|
2165
|
+
afterEach(() => {
|
|
2166
|
+
sinon.restore();
|
|
2167
|
+
})
|
|
2168
|
+
|
|
2169
|
+
it('sends metrics on success', async () => {
|
|
2170
|
+
|
|
2171
|
+
await meeting.uploadLogs();
|
|
2172
|
+
|
|
2173
|
+
await testUtils.flushPromises();
|
|
2174
|
+
|
|
2175
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2176
|
+
callStart: 'last active',
|
|
2177
|
+
correlationId: 'correlation id',
|
|
2178
|
+
feedbackId: 'correlation id',
|
|
2179
|
+
locusId: 'locus id',
|
|
2180
|
+
meetingId: 'meeting id',
|
|
2181
|
+
});
|
|
2182
|
+
});
|
|
2183
|
+
|
|
2184
|
+
it('sends metrics on failure', async () => {
|
|
2185
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2186
|
+
|
|
2187
|
+
await meeting.uploadLogs();
|
|
2188
|
+
|
|
2189
|
+
await testUtils.flushPromises();
|
|
2190
|
+
|
|
2191
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_failure', sinon.match({
|
|
2192
|
+
callStart: 'last active',
|
|
2193
|
+
correlationId: 'correlation id',
|
|
2194
|
+
feedbackId: 'correlation id',
|
|
2195
|
+
locusId: 'locus id',
|
|
2196
|
+
meetingId: 'meeting id',
|
|
2197
|
+
reason: 'fake error',
|
|
2198
|
+
}));
|
|
2199
|
+
});
|
|
2200
|
+
});
|
|
1371
2201
|
});
|
|
1372
2202
|
});
|