@webex/plugin-meetings 3.0.0-beta.32 → 3.0.0-beta.321
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 +94 -15
- 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 +709 -35
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +45 -1
- package/dist/breakouts/utils.js.map +1 -1
- 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/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -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/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -11
- package/dist/config.js.map +1 -1
- package/dist/constants.js +233 -29
- 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 +61 -116
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +84 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +3810 -2939
- 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 +260 -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 +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +415 -115
- 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 +72 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +58 -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 +132 -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 +102 -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 +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +13 -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 +228 -58
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +29 -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 +201 -156
- 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 +62 -32
- 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 +95 -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 +142 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +107 -79
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +27 -26
- 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/utils.d.ts +14 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +1 -7
- package/dist/types/constants.d.ts +194 -24
- 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 +84 -2
- package/dist/types/meeting/index.d.ts +464 -510
- 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 +17 -0
- package/dist/types/meetings/index.d.ts +98 -20
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -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 +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +12 -4
- package/dist/types/metrics/index.d.ts +4 -119
- package/dist/types/multistream/mediaRequestManager.d.ts +72 -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/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +15 -11
- package/dist/types/roap/turnDiscovery.d.ts +21 -3
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +54 -0
- package/dist/types/statsAnalyzer/index.d.ts +7 -1
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +24 -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 +42 -12
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +592 -20
- package/src/breakouts/utils.ts +42 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -10
- package/src/constants.ts +221 -19
- 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 +102 -122
- package/src/media/properties.ts +87 -110
- package/src/meeting/in-meeting-actions.ts +167 -3
- package/src/meeting/index.ts +3162 -2553
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +229 -131
- package/src/meeting/request.ts +177 -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 +33 -0
- package/src/meetings/index.ts +445 -123
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +80 -11
- package/src/member/index.ts +58 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +134 -8
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +12 -4
- package/src/metrics/index.ts +1 -490
- package/src/multistream/mediaRequestManager.ts +277 -82
- package/src/multistream/receiveSlot.ts +31 -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 +83 -56
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +63 -32
- package/src/roap/request.ts +100 -104
- package/src/roap/turnDiscovery.ts +48 -26
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +124 -0
- package/src/statsAnalyzer/index.ts +135 -92
- package/src/statsAnalyzer/mqaUtil.ts +30 -28
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- 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 +118 -28
- 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 +1395 -69
- package/test/unit/spec/breakouts/utils.js +52 -1
- 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/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +83 -3
- package/test/unit/spec/meeting/index.js +5428 -1930
- 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 +483 -49
- package/test/unit/spec/meeting/utils.js +679 -64
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1148 -205
- package/test/unit/spec/meetings/utils.js +202 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +776 -162
- package/test/unit/spec/multistream/receiveSlot.ts +28 -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 +85 -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 +178 -64
- package/test/unit/spec/roap/request.ts +203 -85
- package/test/unit/spec/roap/turnDiscovery.ts +82 -36
- package/test/unit/spec/rtcMetrics/index.ts +93 -0
- package/test/unit/spec/stats-analyzer/index.js +147 -3
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- 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
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import 'jsdom-global/register';
|
|
5
5
|
|
|
6
|
+
// Polyfill for crypto: https://github.com/jsdom/jsdom/issues/1612#issuecomment-663210638
|
|
7
|
+
import {Crypto} from '@peculiar/webcrypto';
|
|
8
|
+
global.crypto = new Crypto();
|
|
9
|
+
|
|
6
10
|
import Device from '@webex/internal-plugin-device';
|
|
7
11
|
import Mercury from '@webex/internal-plugin-mercury';
|
|
8
12
|
import {assert} from '@webex/test-helper-chai';
|
|
@@ -11,6 +15,7 @@ import sinon from 'sinon';
|
|
|
11
15
|
import uuid from 'uuid';
|
|
12
16
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
13
17
|
import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
18
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
14
19
|
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
15
20
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
16
21
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
@@ -19,6 +24,7 @@ import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
|
19
24
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
20
25
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
21
26
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
27
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
22
28
|
|
|
23
29
|
import testUtils from '../../../utils/testUtils';
|
|
24
30
|
import {
|
|
@@ -29,6 +35,12 @@ import {
|
|
|
29
35
|
LOCUSINFO,
|
|
30
36
|
EVENT_TRIGGERS,
|
|
31
37
|
} from '../../../../src/constants';
|
|
38
|
+
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
|
|
39
|
+
import {forEach} from 'lodash';
|
|
40
|
+
import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
|
|
41
|
+
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
42
|
+
import {NoiseReductionEffect, VirtualBackgroundEffect} from '@webex/media-helpers';
|
|
43
|
+
import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
|
|
32
44
|
|
|
33
45
|
describe('plugin-meetings', () => {
|
|
34
46
|
const logger = {
|
|
@@ -40,6 +52,8 @@ describe('plugin-meetings', () => {
|
|
|
40
52
|
debug: () => {},
|
|
41
53
|
};
|
|
42
54
|
|
|
55
|
+
let triggerProxyStub;
|
|
56
|
+
|
|
43
57
|
beforeEach(() => {
|
|
44
58
|
StaticConfig.set({
|
|
45
59
|
bandwidth: {
|
|
@@ -51,7 +65,7 @@ describe('plugin-meetings', () => {
|
|
|
51
65
|
verboseEvents: true,
|
|
52
66
|
enable: false,
|
|
53
67
|
});
|
|
54
|
-
|
|
68
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
55
69
|
});
|
|
56
70
|
|
|
57
71
|
let webex;
|
|
@@ -60,6 +74,7 @@ describe('plugin-meetings', () => {
|
|
|
60
74
|
let url1;
|
|
61
75
|
let test1;
|
|
62
76
|
let test2;
|
|
77
|
+
let locusInfo;
|
|
63
78
|
|
|
64
79
|
describe('meetings index', () => {
|
|
65
80
|
beforeEach(() => {
|
|
@@ -69,6 +84,10 @@ describe('plugin-meetings', () => {
|
|
|
69
84
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
70
85
|
test1 = `test-${uuid.v4()}`;
|
|
71
86
|
test2 = `test2-${uuid.v4()}`;
|
|
87
|
+
locusInfo = {
|
|
88
|
+
parse: sinon.stub().returns(true),
|
|
89
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
90
|
+
};
|
|
72
91
|
webex = new MockWebex({
|
|
73
92
|
children: {
|
|
74
93
|
device: Device,
|
|
@@ -151,6 +170,10 @@ describe('plugin-meetings', () => {
|
|
|
151
170
|
webex.emit('ready');
|
|
152
171
|
});
|
|
153
172
|
|
|
173
|
+
afterEach(() => {
|
|
174
|
+
sinon.restore();
|
|
175
|
+
});
|
|
176
|
+
|
|
154
177
|
it('has a webex instance with a meetings property', () => {
|
|
155
178
|
assert.exists(webex, 'webex was initialized with children');
|
|
156
179
|
assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
|
|
@@ -217,34 +240,6 @@ describe('plugin-meetings', () => {
|
|
|
217
240
|
});
|
|
218
241
|
});
|
|
219
242
|
|
|
220
|
-
describe('#_toggleTurnDiscovery', () => {
|
|
221
|
-
it('should have toggleAdhocMeetings', () => {
|
|
222
|
-
assert.equal(typeof webex.meetings._toggleTurnDiscovery, 'function');
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
describe('success', () => {
|
|
226
|
-
it('should update meetings to do TURN discovery', () => {
|
|
227
|
-
webex.meetings._toggleTurnDiscovery(true);
|
|
228
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, true);
|
|
229
|
-
|
|
230
|
-
webex.meetings._toggleTurnDiscovery(false);
|
|
231
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, false);
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
describe('failure', () => {
|
|
236
|
-
it('should not accept non boolean input', () => {
|
|
237
|
-
const currentEnableTurnDiscovery = webex.meetings.config.experimental.enableTurnDiscovery;
|
|
238
|
-
|
|
239
|
-
webex.meetings._toggleTurnDiscovery('test');
|
|
240
|
-
assert.equal(
|
|
241
|
-
webex.meetings.config.experimental.enableAdhocMeetings,
|
|
242
|
-
currentEnableTurnDiscovery
|
|
243
|
-
);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
243
|
describe('Public API Contracts', () => {
|
|
249
244
|
describe('#register', () => {
|
|
250
245
|
it('emits an event and resolves when register succeeds', async () => {
|
|
@@ -338,37 +333,110 @@ describe('plugin-meetings', () => {
|
|
|
338
333
|
});
|
|
339
334
|
});
|
|
340
335
|
|
|
336
|
+
describe('virtual background effect', () => {
|
|
337
|
+
beforeEach(() => {
|
|
338
|
+
webex.credentials = {
|
|
339
|
+
supertoken: {
|
|
340
|
+
access_token: 'fake_token',
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('creates background effect', async () => {
|
|
346
|
+
const result = await webex.meetings.createVirtualBackgroundEffect();
|
|
347
|
+
|
|
348
|
+
assert.exists(result);
|
|
349
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
350
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
351
|
+
assert.deepEqual(result.options, {
|
|
352
|
+
mode: 'BLUR',
|
|
353
|
+
blurStrength: 'STRONG',
|
|
354
|
+
generator: 'worker',
|
|
355
|
+
quality: 'LOW',
|
|
356
|
+
authToken: 'fake_token',
|
|
357
|
+
mirror: false,
|
|
358
|
+
});
|
|
359
|
+
assert.exists(result.enable);
|
|
360
|
+
assert.exists(result.disable);
|
|
361
|
+
assert.exists(result.dispose);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('creates background effect with custom options passed', async () => {
|
|
365
|
+
const effectOptions = {
|
|
366
|
+
generator: 'local',
|
|
367
|
+
frameRate: 45,
|
|
368
|
+
mode: 'IMAGE',
|
|
369
|
+
mirror: false,
|
|
370
|
+
quality: 'HIGH',
|
|
371
|
+
blurStrength: 'STRONG',
|
|
372
|
+
bgImageUrl: 'https://test.webex.com/landscape.5a535788.jpg',
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const result = await webex.meetings.createVirtualBackgroundEffect(effectOptions);
|
|
376
|
+
|
|
377
|
+
assert.exists(result);
|
|
378
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
379
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
380
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
381
|
+
assert.exists(result.enable);
|
|
382
|
+
assert.exists(result.disable);
|
|
383
|
+
assert.exists(result.dispose);
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
describe('noise reduction effect', () => {
|
|
388
|
+
beforeEach(() => {
|
|
389
|
+
webex.credentials = {
|
|
390
|
+
supertoken: {
|
|
391
|
+
access_token: 'fake_token',
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('creates noise reduction effect', async () => {
|
|
397
|
+
const result = await webex.meetings.createNoiseReductionEffect({audioContext: {}});
|
|
398
|
+
|
|
399
|
+
assert.exists(result);
|
|
400
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
401
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
402
|
+
assert.deepEqual(result.options, {
|
|
403
|
+
authToken: 'fake_token',
|
|
404
|
+
audioContext: {},
|
|
405
|
+
});
|
|
406
|
+
assert.exists(result.enable);
|
|
407
|
+
assert.exists(result.disable);
|
|
408
|
+
assert.exists(result.dispose);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('creates noise reduction effect with custom options passed', async () => {
|
|
412
|
+
const effectOptions = {
|
|
413
|
+
audioContext: {},
|
|
414
|
+
mode: 'WORKLET',
|
|
415
|
+
env: 'prod',
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const result = await webex.meetings.createNoiseReductionEffect(effectOptions);
|
|
419
|
+
|
|
420
|
+
assert.exists(result);
|
|
421
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
422
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
423
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
424
|
+
assert.exists(result.enable);
|
|
425
|
+
assert.exists(result.disable);
|
|
426
|
+
assert.exists(result.dispose);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
341
430
|
describe('gets', () => {
|
|
342
431
|
describe('#getReachability', () => {
|
|
343
432
|
it('should have #getReachability', () => {
|
|
344
433
|
assert.exists(webex.meetings.getReachability);
|
|
345
434
|
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const reachability = webex.meetings.getReachability();
|
|
435
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
436
|
+
const reachability = webex.meetings.getReachability();
|
|
349
437
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
'reachability is undefined because #setReachability has not been called'
|
|
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
|
-
});
|
|
438
|
+
assert.exists(reachability, 'reachability is defined');
|
|
439
|
+
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
372
440
|
});
|
|
373
441
|
});
|
|
374
442
|
describe('#getPersonalMeetingRoom', () => {
|
|
@@ -443,21 +511,16 @@ describe('plugin-meetings', () => {
|
|
|
443
511
|
);
|
|
444
512
|
});
|
|
445
513
|
describe('when meeting is returned', () => {
|
|
446
|
-
let parse;
|
|
447
|
-
|
|
448
514
|
beforeEach(() => {
|
|
449
|
-
parse = sinon.stub().returns(true);
|
|
450
515
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
451
|
-
locusInfo
|
|
452
|
-
parse,
|
|
453
|
-
},
|
|
516
|
+
locusInfo,
|
|
454
517
|
});
|
|
455
518
|
});
|
|
456
519
|
it('tests the sync meeting calls for existing meeting', async () => {
|
|
457
520
|
await webex.meetings.syncMeetings();
|
|
458
521
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
459
522
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
460
|
-
assert.calledOnce(parse);
|
|
523
|
+
assert.calledOnce(locusInfo.parse);
|
|
461
524
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
462
525
|
});
|
|
463
526
|
});
|
|
@@ -470,6 +533,7 @@ describe('plugin-meetings', () => {
|
|
|
470
533
|
webex.meetings.create = sinon.stub().returns(
|
|
471
534
|
Promise.resolve({
|
|
472
535
|
locusInfo: {
|
|
536
|
+
...locusInfo,
|
|
473
537
|
initialSetup,
|
|
474
538
|
},
|
|
475
539
|
})
|
|
@@ -478,7 +542,7 @@ describe('plugin-meetings', () => {
|
|
|
478
542
|
it('tests the sync meeting calls for not existing meeting', async () => {
|
|
479
543
|
await webex.meetings.syncMeetings();
|
|
480
544
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
481
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
545
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
482
546
|
assert.calledOnce(initialSetup);
|
|
483
547
|
assert.calledOnce(webex.meetings.create);
|
|
484
548
|
assert.calledWith(webex.meetings.request.getActiveMeetings);
|
|
@@ -502,12 +566,9 @@ describe('plugin-meetings', () => {
|
|
|
502
566
|
|
|
503
567
|
beforeEach(() => {
|
|
504
568
|
destroySpy = sinon.spy(webex.meetings, 'destroy');
|
|
505
|
-
parse = sinon.stub().returns(true);
|
|
506
569
|
initialSetup = sinon.stub().returns(true);
|
|
507
570
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
508
|
-
locusInfo
|
|
509
|
-
parse,
|
|
510
|
-
},
|
|
571
|
+
locusInfo,
|
|
511
572
|
sendCallAnalyzerMetrics: sinon.stub(),
|
|
512
573
|
});
|
|
513
574
|
webex.meetings.meetingCollection.getAll = sinon.stub().returns({
|
|
@@ -574,14 +635,66 @@ describe('plugin-meetings', () => {
|
|
|
574
635
|
});
|
|
575
636
|
});
|
|
576
637
|
|
|
638
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
639
|
+
const correlationId = 'my-correlationId';
|
|
640
|
+
|
|
641
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
642
|
+
const create = webex.meetings.create(...createParameters);
|
|
643
|
+
|
|
644
|
+
assert.exists(create.then);
|
|
645
|
+
await create;
|
|
646
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
647
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
648
|
+
};
|
|
649
|
+
|
|
577
650
|
it('calls createMeeting and returns its promise', async () => {
|
|
578
|
-
|
|
579
|
-
|
|
651
|
+
checkCallCreateMeeting(
|
|
652
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true],
|
|
653
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true]
|
|
654
|
+
);
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
658
|
+
checkCallCreateMeeting(
|
|
659
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
|
|
660
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]
|
|
661
|
+
);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
665
|
+
checkCallCreateMeeting(
|
|
666
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false],
|
|
667
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]
|
|
668
|
+
);
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
672
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
673
|
+
const correlationId = 'my-correlationId';
|
|
674
|
+
|
|
675
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
676
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
677
|
+
joinTXId: 'TSmrX61wNF',
|
|
678
|
+
};
|
|
679
|
+
const create = webex.meetings.create(
|
|
680
|
+
test1,
|
|
681
|
+
test2,
|
|
682
|
+
FAKE_USE_RANDOM_DELAY,
|
|
683
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
684
|
+
correlationId
|
|
685
|
+
);
|
|
580
686
|
|
|
581
687
|
assert.exists(create.then);
|
|
582
688
|
await create;
|
|
583
689
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
584
|
-
assert.calledWith(
|
|
690
|
+
assert.calledWith(
|
|
691
|
+
webex.meetings.createMeeting,
|
|
692
|
+
test1,
|
|
693
|
+
test2,
|
|
694
|
+
FAKE_USE_RANDOM_DELAY,
|
|
695
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
696
|
+
correlationId
|
|
697
|
+
);
|
|
585
698
|
});
|
|
586
699
|
|
|
587
700
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -677,45 +790,51 @@ describe('plugin-meetings', () => {
|
|
|
677
790
|
});
|
|
678
791
|
describe('#handleLocusEvent', () => {
|
|
679
792
|
describe('there was a meeting', () => {
|
|
680
|
-
let parse;
|
|
681
|
-
|
|
682
793
|
beforeEach(() => {
|
|
683
|
-
parse = sinon.stub().returns(true);
|
|
684
794
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
685
|
-
locusInfo
|
|
686
|
-
parse,
|
|
687
|
-
},
|
|
795
|
+
locusInfo,
|
|
688
796
|
});
|
|
689
797
|
});
|
|
690
|
-
it('should parse the meeting info', () => {
|
|
798
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
799
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
691
800
|
webex.meetings.handleLocusEvent({
|
|
692
801
|
locusUrl: url1,
|
|
693
802
|
});
|
|
694
803
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
695
804
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
696
|
-
assert.calledOnce(parse);
|
|
805
|
+
assert.calledOnce(locusInfo.parse);
|
|
806
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
697
807
|
assert.calledWith(
|
|
698
|
-
parse,
|
|
808
|
+
locusInfo.parse,
|
|
699
809
|
{
|
|
700
|
-
locusInfo
|
|
701
|
-
parse,
|
|
702
|
-
},
|
|
810
|
+
locusInfo,
|
|
703
811
|
},
|
|
704
812
|
{
|
|
705
813
|
locusUrl: url1,
|
|
706
814
|
}
|
|
707
815
|
);
|
|
708
816
|
});
|
|
817
|
+
|
|
818
|
+
it('should not update main session locus cache', () => {
|
|
819
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
820
|
+
webex.meetings.handleLocusEvent({
|
|
821
|
+
locusUrl: url1,
|
|
822
|
+
});
|
|
823
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
824
|
+
});
|
|
709
825
|
});
|
|
710
826
|
describe('there was not a meeting', () => {
|
|
711
827
|
let initialSetup;
|
|
828
|
+
const webExMeetingId = '123456';
|
|
712
829
|
|
|
713
830
|
beforeEach(() => {
|
|
714
831
|
initialSetup = sinon.stub().returns(true);
|
|
715
832
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
716
833
|
webex.meetings.create = sinon.stub().returns(
|
|
717
834
|
Promise.resolve({
|
|
835
|
+
id: 'meeting-id',
|
|
718
836
|
locusInfo: {
|
|
837
|
+
...locusInfo,
|
|
719
838
|
initialSetup,
|
|
720
839
|
},
|
|
721
840
|
})
|
|
@@ -735,12 +854,20 @@ describe('plugin-meetings', () => {
|
|
|
735
854
|
callbackAddress: uri1,
|
|
736
855
|
},
|
|
737
856
|
},
|
|
857
|
+
info: {
|
|
858
|
+
webExMeetingId,
|
|
859
|
+
},
|
|
738
860
|
},
|
|
739
861
|
eventType: 'locus.difference',
|
|
740
862
|
locusUrl: url1,
|
|
741
863
|
});
|
|
742
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
864
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
743
865
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
866
|
+
assert.calledWith(
|
|
867
|
+
webex.meetings.meetingCollection.getByKey,
|
|
868
|
+
'meetingNumber',
|
|
869
|
+
webExMeetingId
|
|
870
|
+
);
|
|
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,20 @@ 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(
|
|
908
|
+
webex.meetings.meetingCollection.getByKey,
|
|
909
|
+
'meetingNumber',
|
|
910
|
+
webExMeetingId
|
|
911
|
+
);
|
|
774
912
|
assert.calledOnce(initialSetup);
|
|
775
913
|
assert.calledWith(initialSetup, {
|
|
776
914
|
id: uuid1,
|
|
@@ -779,8 +917,44 @@ describe('plugin-meetings', () => {
|
|
|
779
917
|
callbackAddress: uri1,
|
|
780
918
|
},
|
|
781
919
|
},
|
|
920
|
+
info: {
|
|
921
|
+
webExMeetingId,
|
|
922
|
+
},
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
|
|
926
|
+
it('sends client event correctly on finally', async () => {
|
|
927
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
928
|
+
|
|
929
|
+
await webex.meetings.handleLocusEvent({
|
|
930
|
+
locus: {
|
|
931
|
+
id: uuid1,
|
|
932
|
+
self: {
|
|
933
|
+
callBackInfo: {
|
|
934
|
+
callbackAddress: uri1,
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
info: {
|
|
938
|
+
webExMeetingId,
|
|
939
|
+
},
|
|
940
|
+
},
|
|
941
|
+
eventType: 'locus.difference',
|
|
942
|
+
locusUrl: url1,
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
await testUtils.flushPromises();
|
|
946
|
+
|
|
947
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
948
|
+
name: 'client.call.remote-started',
|
|
949
|
+
payload: {
|
|
950
|
+
trigger: 'mercury-event',
|
|
951
|
+
},
|
|
952
|
+
options: {
|
|
953
|
+
meetingId: 'meeting-id',
|
|
954
|
+
},
|
|
782
955
|
});
|
|
783
956
|
});
|
|
957
|
+
|
|
784
958
|
it('should setup the meeting by a not difference event', async () => {
|
|
785
959
|
await webex.meetings.handleLocusEvent({
|
|
786
960
|
locus: {
|
|
@@ -790,12 +964,20 @@ describe('plugin-meetings', () => {
|
|
|
790
964
|
callbackAddress: uri1,
|
|
791
965
|
},
|
|
792
966
|
},
|
|
967
|
+
info: {
|
|
968
|
+
webExMeetingId,
|
|
969
|
+
},
|
|
793
970
|
},
|
|
794
971
|
eventType: test1,
|
|
795
972
|
locusUrl: url1,
|
|
796
973
|
});
|
|
797
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
974
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
798
975
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
976
|
+
assert.calledWith(
|
|
977
|
+
webex.meetings.meetingCollection.getByKey,
|
|
978
|
+
'meetingNumber',
|
|
979
|
+
webExMeetingId
|
|
980
|
+
);
|
|
799
981
|
assert.calledOnce(initialSetup);
|
|
800
982
|
assert.calledWith(initialSetup, {
|
|
801
983
|
id: uuid1,
|
|
@@ -804,6 +986,9 @@ describe('plugin-meetings', () => {
|
|
|
804
986
|
callbackAddress: uri1,
|
|
805
987
|
},
|
|
806
988
|
},
|
|
989
|
+
info: {
|
|
990
|
+
webExMeetingId,
|
|
991
|
+
},
|
|
807
992
|
});
|
|
808
993
|
});
|
|
809
994
|
|
|
@@ -826,7 +1011,7 @@ describe('plugin-meetings', () => {
|
|
|
826
1011
|
|
|
827
1012
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
828
1013
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
|
|
829
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1014
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
830
1015
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
831
1016
|
'locusUrl',
|
|
832
1017
|
url1,
|
|
@@ -843,7 +1028,7 @@ describe('plugin-meetings', () => {
|
|
|
843
1028
|
});
|
|
844
1029
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
845
1030
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
|
|
846
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1031
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
847
1032
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
848
1033
|
'locusUrl',
|
|
849
1034
|
url1,
|
|
@@ -874,6 +1059,10 @@ describe('plugin-meetings', () => {
|
|
|
874
1059
|
});
|
|
875
1060
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
876
1061
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1062
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
1063
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
1064
|
+
joinTXId: 'TSmrX61wNF',
|
|
1065
|
+
};
|
|
877
1066
|
|
|
878
1067
|
beforeEach(() => {
|
|
879
1068
|
clock = sinon.useFakeTimers();
|
|
@@ -903,13 +1092,25 @@ describe('plugin-meetings', () => {
|
|
|
903
1092
|
meeting,
|
|
904
1093
|
destination,
|
|
905
1094
|
type,
|
|
906
|
-
|
|
1095
|
+
extraParams = {},
|
|
1096
|
+
expectedMeetingData = {},
|
|
1097
|
+
sendCAevents = false
|
|
907
1098
|
) => {
|
|
908
1099
|
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
909
1100
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
910
1101
|
assert.notCalled(setTimeoutSpy);
|
|
911
|
-
assert.
|
|
912
|
-
assert.calledWith(
|
|
1102
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1103
|
+
assert.calledWith(
|
|
1104
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1105
|
+
destination,
|
|
1106
|
+
type,
|
|
1107
|
+
null,
|
|
1108
|
+
null,
|
|
1109
|
+
undefined,
|
|
1110
|
+
undefined,
|
|
1111
|
+
extraParams,
|
|
1112
|
+
{meetingId: meeting.id, sendCAevents}
|
|
1113
|
+
);
|
|
913
1114
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
914
1115
|
|
|
915
1116
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -918,6 +1119,9 @@ describe('plugin-meetings', () => {
|
|
|
918
1119
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
919
1120
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
920
1121
|
}
|
|
1122
|
+
if (expectedMeetingData.correlationId) {
|
|
1123
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1124
|
+
}
|
|
921
1125
|
assert.equal(meeting.destination, destination);
|
|
922
1126
|
assert.equal(meeting.destinationType, type);
|
|
923
1127
|
assert.calledWith(
|
|
@@ -947,107 +1151,139 @@ describe('plugin-meetings', () => {
|
|
|
947
1151
|
const expectedMeetingData = {
|
|
948
1152
|
permissionToken: 'PT',
|
|
949
1153
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
1154
|
+
correlationId: meeting.id,
|
|
950
1155
|
};
|
|
951
1156
|
|
|
952
|
-
checkCreateWithoutDelay(
|
|
953
|
-
});
|
|
954
|
-
|
|
955
|
-
it('creates the meeting from a successful meeting info fetch meeting resolve testing', async () => {
|
|
956
|
-
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
957
|
-
const expectedMeetingData = {
|
|
958
|
-
permissionToken: 'PT',
|
|
959
|
-
meetingJoinUrl: 'meetingJoinUrl',
|
|
960
|
-
};
|
|
961
|
-
|
|
962
|
-
assert.instanceOf(
|
|
1157
|
+
checkCreateWithoutDelay(
|
|
963
1158
|
meeting,
|
|
964
|
-
|
|
965
|
-
'
|
|
1159
|
+
'test destination',
|
|
1160
|
+
'test type',
|
|
1161
|
+
{},
|
|
1162
|
+
expectedMeetingData
|
|
966
1163
|
);
|
|
967
|
-
checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
|
|
968
1164
|
});
|
|
969
1165
|
|
|
970
|
-
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1166
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1167
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
1168
|
+
|
|
1169
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${
|
|
1170
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1171
|
+
}`, async () => {
|
|
1172
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1173
|
+
'test destination',
|
|
1174
|
+
'test type',
|
|
1175
|
+
false,
|
|
1176
|
+
infoExtraParams
|
|
1177
|
+
);
|
|
1178
|
+
const expectedMeetingData = {
|
|
1179
|
+
permissionToken: 'PT',
|
|
1180
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1183
|
+
assert.instanceOf(
|
|
1184
|
+
meeting,
|
|
1185
|
+
Meeting,
|
|
1186
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1187
|
+
);
|
|
1188
|
+
checkCreateWithoutDelay(
|
|
1189
|
+
meeting,
|
|
1190
|
+
'test destination',
|
|
1191
|
+
'test type',
|
|
1192
|
+
infoExtraParamsProvided ? infoExtraParams : {},
|
|
1193
|
+
expectedMeetingData
|
|
1194
|
+
);
|
|
1195
|
+
});
|
|
986
1196
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1197
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${
|
|
1198
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1199
|
+
}`, async () => {
|
|
1200
|
+
const FAKE_LOCUS_MEETING = {
|
|
1201
|
+
conversationUrl: 'locusConvURL',
|
|
1202
|
+
url: 'locusUrl',
|
|
1203
|
+
info: {
|
|
1204
|
+
webExMeetingId: 'locusMeetingId',
|
|
1205
|
+
sipUri: 'locusSipUri',
|
|
1206
|
+
owner: 'locusOwner',
|
|
1207
|
+
},
|
|
1208
|
+
meeting: {
|
|
1209
|
+
startTime: fakeMeetingStartTimeString,
|
|
1210
|
+
},
|
|
1211
|
+
fullState: {
|
|
1212
|
+
active: false,
|
|
1213
|
+
},
|
|
1214
|
+
};
|
|
992
1215
|
|
|
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
|
-
);
|
|
1216
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1217
|
+
FAKE_LOCUS_MEETING,
|
|
1218
|
+
'test type',
|
|
1219
|
+
true,
|
|
1220
|
+
infoExtraParams
|
|
1221
|
+
);
|
|
1026
1222
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1223
|
+
assert.instanceOf(
|
|
1224
|
+
meeting,
|
|
1225
|
+
Meeting,
|
|
1226
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1227
|
+
);
|
|
1228
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1229
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1230
|
+
|
|
1231
|
+
// Parse meeting info with locus object
|
|
1232
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1233
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1234
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1235
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1236
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1237
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1238
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1239
|
+
|
|
1240
|
+
// Add meeting and send trigger
|
|
1241
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1242
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1243
|
+
assert.calledWith(
|
|
1244
|
+
TriggerProxy.trigger,
|
|
1245
|
+
sinon.match.instanceOf(Meetings),
|
|
1246
|
+
{
|
|
1247
|
+
file: 'meetings',
|
|
1248
|
+
function: 'createMeeting',
|
|
1249
|
+
},
|
|
1250
|
+
'meeting:added',
|
|
1251
|
+
{
|
|
1252
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1253
|
+
type: 'test meeting added type',
|
|
1254
|
+
}
|
|
1255
|
+
);
|
|
1034
1256
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1257
|
+
// When timer expires
|
|
1258
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1259
|
+
assert.calledWith(
|
|
1260
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1261
|
+
FAKE_LOCUS_MEETING,
|
|
1262
|
+
'test type',
|
|
1263
|
+
null,
|
|
1264
|
+
null,
|
|
1265
|
+
undefined,
|
|
1266
|
+
undefined,
|
|
1267
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1268
|
+
);
|
|
1044
1269
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
meeting,
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1270
|
+
// Parse meeting info is called again with new meeting info
|
|
1271
|
+
await testUtils.flushPromises();
|
|
1272
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1273
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1274
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1275
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1276
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1277
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1278
|
+
assert.equal(meeting.permissionToken, 'PT');
|
|
1279
|
+
|
|
1280
|
+
assert.calledWith(
|
|
1281
|
+
TriggerProxy.trigger,
|
|
1282
|
+
meeting,
|
|
1283
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1284
|
+
'meeting:meetingInfoAvailable'
|
|
1285
|
+
);
|
|
1286
|
+
});
|
|
1051
1287
|
});
|
|
1052
1288
|
|
|
1053
1289
|
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
@@ -1147,6 +1383,29 @@ describe('plugin-meetings', () => {
|
|
|
1147
1383
|
);
|
|
1148
1384
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1149
1385
|
});
|
|
1386
|
+
|
|
1387
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1388
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1389
|
+
'test destination',
|
|
1390
|
+
'test type',
|
|
1391
|
+
false,
|
|
1392
|
+
{},
|
|
1393
|
+
'my-correlationId'
|
|
1394
|
+
);
|
|
1395
|
+
|
|
1396
|
+
const expectedMeetingData = {
|
|
1397
|
+
correlationId: 'my-correlationId',
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1400
|
+
checkCreateWithoutDelay(
|
|
1401
|
+
meeting,
|
|
1402
|
+
'test destination',
|
|
1403
|
+
'test type',
|
|
1404
|
+
{},
|
|
1405
|
+
expectedMeetingData,
|
|
1406
|
+
true
|
|
1407
|
+
);
|
|
1408
|
+
});
|
|
1150
1409
|
});
|
|
1151
1410
|
|
|
1152
1411
|
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
@@ -1156,38 +1415,130 @@ describe('plugin-meetings', () => {
|
|
|
1156
1415
|
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1157
1416
|
.stub()
|
|
1158
1417
|
.returns(Promise.reject(new Error('test')));
|
|
1418
|
+
webex.meetings.destroy = sinon.stub().returns(Promise.resolve());
|
|
1419
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1159
1420
|
});
|
|
1421
|
+
|
|
1422
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1423
|
+
try {
|
|
1424
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1425
|
+
'test destination',
|
|
1426
|
+
'test type',
|
|
1427
|
+
undefined,
|
|
1428
|
+
undefined,
|
|
1429
|
+
undefined,
|
|
1430
|
+
failOnMissingMeetingInfo
|
|
1431
|
+
);
|
|
1432
|
+
|
|
1433
|
+
assert.instanceOf(
|
|
1434
|
+
meeting,
|
|
1435
|
+
Meeting,
|
|
1436
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1437
|
+
);
|
|
1438
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1439
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1440
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1441
|
+
assert.calledWith(
|
|
1442
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1443
|
+
'test destination',
|
|
1444
|
+
'test type'
|
|
1445
|
+
);
|
|
1446
|
+
|
|
1447
|
+
if (destroy) {
|
|
1448
|
+
assert.calledWith(
|
|
1449
|
+
webex.meetings.destroy,
|
|
1450
|
+
sinon.match.instanceOf(Meeting),
|
|
1451
|
+
'MISSING_MEETING_INFO'
|
|
1452
|
+
);
|
|
1453
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1454
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1455
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1456
|
+
} else {
|
|
1457
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1458
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1459
|
+
assert.calledWith(
|
|
1460
|
+
TriggerProxy.trigger,
|
|
1461
|
+
sinon.match.instanceOf(Meetings),
|
|
1462
|
+
{
|
|
1463
|
+
file: 'meetings',
|
|
1464
|
+
function: 'createMeeting',
|
|
1465
|
+
},
|
|
1466
|
+
'meeting:added',
|
|
1467
|
+
{
|
|
1468
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1469
|
+
type: 'test meeting added type',
|
|
1470
|
+
}
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
} catch (err) {
|
|
1474
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1475
|
+
}
|
|
1476
|
+
};
|
|
1477
|
+
|
|
1160
1478
|
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1161
|
-
|
|
1479
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1480
|
+
});
|
|
1162
1481
|
|
|
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),
|
|
1482
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1483
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1484
|
+
});
|
|
1485
|
+
});
|
|
1486
|
+
|
|
1487
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1488
|
+
forEach(
|
|
1489
|
+
[
|
|
1180
1490
|
{
|
|
1181
|
-
|
|
1182
|
-
|
|
1491
|
+
error: new CaptchaError(),
|
|
1492
|
+
debugLogMessage:
|
|
1493
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1183
1494
|
},
|
|
1184
|
-
'meeting:added',
|
|
1185
1495
|
{
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1496
|
+
error: new PasswordError(),
|
|
1497
|
+
debugLogMessage:
|
|
1498
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
error: new PermissionError(),
|
|
1502
|
+
debugLogMessage:
|
|
1503
|
+
'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.',
|
|
1504
|
+
},
|
|
1505
|
+
{
|
|
1506
|
+
error: new Error(),
|
|
1507
|
+
infoLogMessage: true,
|
|
1508
|
+
debugLogMessage:
|
|
1509
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1510
|
+
},
|
|
1511
|
+
],
|
|
1512
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1513
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1514
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1515
|
+
.stub()
|
|
1516
|
+
.returns(Promise.reject(error));
|
|
1517
|
+
|
|
1518
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1519
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1520
|
+
|
|
1521
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1522
|
+
|
|
1523
|
+
assert.instanceOf(
|
|
1524
|
+
meeting,
|
|
1525
|
+
Meeting,
|
|
1526
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1527
|
+
);
|
|
1528
|
+
|
|
1529
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1530
|
+
|
|
1531
|
+
if (infoLogMessage) {
|
|
1532
|
+
assert.calledWith(
|
|
1533
|
+
LoggerProxy.logger.info,
|
|
1534
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1535
|
+
);
|
|
1536
|
+
} else {
|
|
1537
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
}
|
|
1541
|
+
);
|
|
1191
1542
|
});
|
|
1192
1543
|
});
|
|
1193
1544
|
});
|
|
@@ -1267,6 +1618,8 @@ describe('plugin-meetings', () => {
|
|
|
1267
1618
|
});
|
|
1268
1619
|
|
|
1269
1620
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1621
|
+
let loggerProxySpy;
|
|
1622
|
+
|
|
1270
1623
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1271
1624
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1272
1625
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1274,7 +1627,22 @@ describe('plugin-meetings', () => {
|
|
|
1274
1627
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1275
1628
|
});
|
|
1276
1629
|
|
|
1630
|
+
const setup = ({user} = {}) => {
|
|
1631
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1632
|
+
|
|
1633
|
+
Object.assign(webex.internal, {
|
|
1634
|
+
services: {
|
|
1635
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1636
|
+
},
|
|
1637
|
+
user: {
|
|
1638
|
+
get: sinon.stub().returns(Promise.resolve(user)),
|
|
1639
|
+
},
|
|
1640
|
+
});
|
|
1641
|
+
};
|
|
1642
|
+
|
|
1277
1643
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1644
|
+
setup();
|
|
1645
|
+
|
|
1278
1646
|
Object.assign(webex.internal, {
|
|
1279
1647
|
services: {
|
|
1280
1648
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
@@ -1284,6 +1652,63 @@ describe('plugin-meetings', () => {
|
|
|
1284
1652
|
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1285
1653
|
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1286
1654
|
});
|
|
1655
|
+
assert.calledOnceWithExactly(
|
|
1656
|
+
loggerProxySpy,
|
|
1657
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1658
|
+
);
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1662
|
+
setup({
|
|
1663
|
+
user: {
|
|
1664
|
+
userPreferences: {
|
|
1665
|
+
userPreferencesItems: {
|
|
1666
|
+
preferredWebExSite: 'site.webex.com',
|
|
1667
|
+
},
|
|
1668
|
+
},
|
|
1669
|
+
},
|
|
1670
|
+
});
|
|
1671
|
+
|
|
1672
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1673
|
+
|
|
1674
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1675
|
+
assert.notCalled(loggerProxySpy);
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
forEach(
|
|
1679
|
+
[
|
|
1680
|
+
{user: undefined},
|
|
1681
|
+
{user: {userPreferences: {}}},
|
|
1682
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1683
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1684
|
+
],
|
|
1685
|
+
({user}) => {
|
|
1686
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1687
|
+
setup({user});
|
|
1688
|
+
|
|
1689
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1690
|
+
|
|
1691
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1692
|
+
assert.calledOnceWithExactly(
|
|
1693
|
+
loggerProxySpy,
|
|
1694
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1695
|
+
);
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
);
|
|
1699
|
+
|
|
1700
|
+
it('should handle a get user failure', async () => {
|
|
1701
|
+
setup();
|
|
1702
|
+
|
|
1703
|
+
webex.internal.user.get.rejects(new Error());
|
|
1704
|
+
|
|
1705
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1706
|
+
|
|
1707
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1708
|
+
assert.calledOnceWithExactly(
|
|
1709
|
+
loggerProxySpy,
|
|
1710
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1711
|
+
);
|
|
1287
1712
|
});
|
|
1288
1713
|
});
|
|
1289
1714
|
});
|
|
@@ -1368,5 +1793,523 @@ describe('plugin-meetings', () => {
|
|
|
1368
1793
|
);
|
|
1369
1794
|
});
|
|
1370
1795
|
});
|
|
1796
|
+
|
|
1797
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
1798
|
+
let meeting;
|
|
1799
|
+
let newLocus;
|
|
1800
|
+
beforeEach(() => {
|
|
1801
|
+
meeting = {
|
|
1802
|
+
controls: {},
|
|
1803
|
+
self: {},
|
|
1804
|
+
};
|
|
1805
|
+
newLocus = {
|
|
1806
|
+
controls: {},
|
|
1807
|
+
self: {},
|
|
1808
|
+
};
|
|
1809
|
+
});
|
|
1810
|
+
afterEach(() => {
|
|
1811
|
+
sinon.restore();
|
|
1812
|
+
});
|
|
1813
|
+
it('check normal case will return true', () => {
|
|
1814
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1815
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1816
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1817
|
+
assert.equal(result, true);
|
|
1818
|
+
assert.calledWith(
|
|
1819
|
+
LoggerProxy.logger.log,
|
|
1820
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1821
|
+
);
|
|
1822
|
+
});
|
|
1823
|
+
|
|
1824
|
+
it('check self joined and joined on this device, return true', () => {
|
|
1825
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1826
|
+
newLocus.self.state = 'JOINED';
|
|
1827
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1828
|
+
|
|
1829
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1830
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1831
|
+
assert.equal(result, true);
|
|
1832
|
+
assert.calledWith(
|
|
1833
|
+
LoggerProxy.logger.log,
|
|
1834
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
1835
|
+
);
|
|
1836
|
+
});
|
|
1837
|
+
|
|
1838
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
1839
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1840
|
+
joinedWith: {
|
|
1841
|
+
replaces: [
|
|
1842
|
+
{
|
|
1843
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
1844
|
+
},
|
|
1845
|
+
],
|
|
1846
|
+
},
|
|
1847
|
+
});
|
|
1848
|
+
newLocus.self.state = 'JOINED';
|
|
1849
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1850
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1851
|
+
replaces: [
|
|
1852
|
+
{
|
|
1853
|
+
replaceAt: '2023-03-27T02:17:01.506Z',
|
|
1854
|
+
},
|
|
1855
|
+
],
|
|
1856
|
+
});
|
|
1857
|
+
|
|
1858
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1859
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1860
|
+
assert.equal(result, false);
|
|
1861
|
+
assert.calledWith(
|
|
1862
|
+
LoggerProxy.logger.log,
|
|
1863
|
+
`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`
|
|
1864
|
+
);
|
|
1865
|
+
});
|
|
1866
|
+
|
|
1867
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
1868
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1869
|
+
joinedWith: {
|
|
1870
|
+
correlationId: '111',
|
|
1871
|
+
},
|
|
1872
|
+
});
|
|
1873
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
1874
|
+
meeting.correlationId = '111';
|
|
1875
|
+
|
|
1876
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1877
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1878
|
+
assert.equal(result, false);
|
|
1879
|
+
assert.calledWith(
|
|
1880
|
+
LoggerProxy.logger.log,
|
|
1881
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
1882
|
+
);
|
|
1883
|
+
});
|
|
1884
|
+
|
|
1885
|
+
it('check self is moved and removed, return false', () => {
|
|
1886
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1887
|
+
newLocus.self.state = 'LEFT';
|
|
1888
|
+
newLocus.self.reason = 'MOVED';
|
|
1889
|
+
newLocus.self.removed = true;
|
|
1890
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1891
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1892
|
+
assert.equal(result, false);
|
|
1893
|
+
assert.calledWith(
|
|
1894
|
+
LoggerProxy.logger.log,
|
|
1895
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1896
|
+
);
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1899
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
1900
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1901
|
+
newLocus.self.state = 'LEFT';
|
|
1902
|
+
newLocus.self.reason = 'MOVED';
|
|
1903
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1904
|
+
state: 'LEFT',
|
|
1905
|
+
reason: 'MOVED',
|
|
1906
|
+
});
|
|
1907
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1908
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1909
|
+
assert.equal(result, false);
|
|
1910
|
+
assert.calledWith(
|
|
1911
|
+
LoggerProxy.logger.log,
|
|
1912
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1913
|
+
);
|
|
1914
|
+
});
|
|
1915
|
+
|
|
1916
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
1917
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1918
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
1919
|
+
newLocus.self.state = 'JOINED';
|
|
1920
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1921
|
+
state: 'LEFT',
|
|
1922
|
+
reason: 'MOVED',
|
|
1923
|
+
});
|
|
1924
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1925
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1926
|
+
assert.equal(result, false);
|
|
1927
|
+
assert.calledWith(
|
|
1928
|
+
LoggerProxy.logger.log,
|
|
1929
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
1930
|
+
);
|
|
1931
|
+
});
|
|
1932
|
+
});
|
|
1933
|
+
|
|
1934
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
1935
|
+
let meeting;
|
|
1936
|
+
let newLocus;
|
|
1937
|
+
beforeEach(() => {
|
|
1938
|
+
meeting = {
|
|
1939
|
+
controls: {},
|
|
1940
|
+
self: {},
|
|
1941
|
+
};
|
|
1942
|
+
newLocus = {
|
|
1943
|
+
controls: {},
|
|
1944
|
+
self: {},
|
|
1945
|
+
};
|
|
1946
|
+
});
|
|
1947
|
+
afterEach(() => {
|
|
1948
|
+
sinon.restore();
|
|
1949
|
+
});
|
|
1950
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
1951
|
+
newLocus.controls.breakout = {
|
|
1952
|
+
sessionType: 'BREAKOUT',
|
|
1953
|
+
};
|
|
1954
|
+
newLocus.self.state = 'JOINED';
|
|
1955
|
+
newLocus.fullState = {
|
|
1956
|
+
active: true,
|
|
1957
|
+
};
|
|
1958
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1959
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
1960
|
+
assert.equal(result, true);
|
|
1961
|
+
assert.calledWith(
|
|
1962
|
+
LoggerProxy.logger.log,
|
|
1963
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
1964
|
+
);
|
|
1965
|
+
});
|
|
1966
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
1967
|
+
newLocus.controls.breakout = {
|
|
1968
|
+
sessionType: 'MAIN',
|
|
1969
|
+
};
|
|
1970
|
+
newLocus.self.state = 'JOINED';
|
|
1971
|
+
|
|
1972
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1973
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
1974
|
+
assert.equal(result, true);
|
|
1975
|
+
assert.calledWith(
|
|
1976
|
+
LoggerProxy.logger.log,
|
|
1977
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1978
|
+
);
|
|
1979
|
+
});
|
|
1980
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
1981
|
+
newLocus.controls.breakout = {
|
|
1982
|
+
sessionType: 'BREAKOUT',
|
|
1983
|
+
};
|
|
1984
|
+
newLocus.self.state = 'LEFT';
|
|
1985
|
+
newLocus.self.reason = 'MOVED';
|
|
1986
|
+
|
|
1987
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1988
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
1989
|
+
assert.equal(result, false);
|
|
1990
|
+
});
|
|
1991
|
+
});
|
|
1992
|
+
|
|
1993
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
1994
|
+
let locus;
|
|
1995
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
1996
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
1997
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
1998
|
+
if (key === keyWillReturnMeeting) {
|
|
1999
|
+
return mockReturnMeeting;
|
|
2000
|
+
}
|
|
2001
|
+
return null;
|
|
2002
|
+
});
|
|
2003
|
+
};
|
|
2004
|
+
|
|
2005
|
+
beforeEach(() => {
|
|
2006
|
+
locus = {
|
|
2007
|
+
controls: {},
|
|
2008
|
+
self: {
|
|
2009
|
+
callbackInfo: {
|
|
2010
|
+
callbackAddress: 'address1',
|
|
2011
|
+
},
|
|
2012
|
+
},
|
|
2013
|
+
info: {
|
|
2014
|
+
webExMeetingId: '123456',
|
|
2015
|
+
isUnifiedSpaceMeeting: false,
|
|
2016
|
+
},
|
|
2017
|
+
conversationUrl: 'conversationUrl1',
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
2021
|
+
});
|
|
2022
|
+
afterEach(() => {
|
|
2023
|
+
sinon.restore();
|
|
2024
|
+
});
|
|
2025
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
2026
|
+
mockGetByKey();
|
|
2027
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2028
|
+
assert.isNull(result);
|
|
2029
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2030
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2031
|
+
assert.calledWith(
|
|
2032
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2033
|
+
'correlationId',
|
|
2034
|
+
'correlationId1'
|
|
2035
|
+
);
|
|
2036
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2037
|
+
assert.calledWith(
|
|
2038
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2039
|
+
'conversationUrl',
|
|
2040
|
+
'conversationUrl1'
|
|
2041
|
+
);
|
|
2042
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2043
|
+
});
|
|
2044
|
+
|
|
2045
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
2046
|
+
mockGetByKey();
|
|
2047
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
2048
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2049
|
+
assert.isNull(result);
|
|
2050
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2051
|
+
});
|
|
2052
|
+
|
|
2053
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
2054
|
+
mockGetByKey('locusUrl');
|
|
2055
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2056
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2057
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
2058
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2059
|
+
});
|
|
2060
|
+
|
|
2061
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
2062
|
+
mockGetByKey('correlationId');
|
|
2063
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2064
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2065
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
2066
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2067
|
+
assert.calledWith(
|
|
2068
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2069
|
+
'correlationId',
|
|
2070
|
+
'correlationId1'
|
|
2071
|
+
);
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
2075
|
+
mockGetByKey('sipUri');
|
|
2076
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2077
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2078
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
2079
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2080
|
+
assert.calledWith(
|
|
2081
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2082
|
+
'correlationId',
|
|
2083
|
+
'correlationId1'
|
|
2084
|
+
);
|
|
2085
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2086
|
+
});
|
|
2087
|
+
|
|
2088
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
2089
|
+
mockGetByKey('conversationUrl');
|
|
2090
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2091
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2092
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2093
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2094
|
+
assert.calledWith(
|
|
2095
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2096
|
+
'correlationId',
|
|
2097
|
+
'correlationId1'
|
|
2098
|
+
);
|
|
2099
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2100
|
+
assert.calledWith(
|
|
2101
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2102
|
+
'conversationUrl',
|
|
2103
|
+
'conversationUrl1'
|
|
2104
|
+
);
|
|
2105
|
+
});
|
|
2106
|
+
|
|
2107
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
2108
|
+
mockGetByKey('meetingNumber');
|
|
2109
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2110
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2111
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2112
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2113
|
+
assert.calledWith(
|
|
2114
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2115
|
+
'correlationId',
|
|
2116
|
+
'correlationId1'
|
|
2117
|
+
);
|
|
2118
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2119
|
+
assert.calledWith(
|
|
2120
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2121
|
+
'conversationUrl',
|
|
2122
|
+
'conversationUrl1'
|
|
2123
|
+
);
|
|
2124
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2125
|
+
});
|
|
2126
|
+
});
|
|
2127
|
+
|
|
2128
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
2129
|
+
let lociArray;
|
|
2130
|
+
let mainLocus;
|
|
2131
|
+
let breakoutLocus;
|
|
2132
|
+
beforeEach(() => {
|
|
2133
|
+
mainLocus = {
|
|
2134
|
+
url: 'mainUrl1',
|
|
2135
|
+
controls: {
|
|
2136
|
+
breakout: {
|
|
2137
|
+
sessionType: 'MAIN',
|
|
2138
|
+
url: 'breakoutUnifiedUrl1',
|
|
2139
|
+
},
|
|
2140
|
+
},
|
|
2141
|
+
};
|
|
2142
|
+
breakoutLocus = {
|
|
2143
|
+
url: 'breakoutUrl1',
|
|
2144
|
+
controls: {
|
|
2145
|
+
breakout: {
|
|
2146
|
+
sessionType: 'BREAKOUT',
|
|
2147
|
+
url: 'breakoutUnifiedUrl1',
|
|
2148
|
+
},
|
|
2149
|
+
},
|
|
2150
|
+
};
|
|
2151
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2152
|
+
|
|
2153
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2154
|
+
return locus.url === 'breakoutUrl1';
|
|
2155
|
+
});
|
|
2156
|
+
});
|
|
2157
|
+
afterEach(() => {
|
|
2158
|
+
sinon.restore();
|
|
2159
|
+
});
|
|
2160
|
+
|
|
2161
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2162
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2163
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2164
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2165
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2166
|
+
});
|
|
2167
|
+
|
|
2168
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2169
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2170
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2171
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2172
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2173
|
+
});
|
|
2174
|
+
|
|
2175
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2176
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2177
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2178
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2179
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2180
|
+
});
|
|
2181
|
+
});
|
|
2182
|
+
|
|
2183
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2184
|
+
let breakoutLocus;
|
|
2185
|
+
beforeEach(() => {
|
|
2186
|
+
breakoutLocus = {
|
|
2187
|
+
url: 'breakoutUrl1',
|
|
2188
|
+
controls: {
|
|
2189
|
+
breakout: {
|
|
2190
|
+
sessionType: 'BREAKOUT',
|
|
2191
|
+
url: 'breakoutUnifiedUrl1',
|
|
2192
|
+
},
|
|
2193
|
+
},
|
|
2194
|
+
};
|
|
2195
|
+
|
|
2196
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2197
|
+
});
|
|
2198
|
+
afterEach(() => {
|
|
2199
|
+
sinon.restore();
|
|
2200
|
+
});
|
|
2201
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2202
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2203
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2204
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2205
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2206
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2207
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2208
|
+
});
|
|
2209
|
+
|
|
2210
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2211
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2212
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2213
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2214
|
+
});
|
|
2215
|
+
|
|
2216
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2217
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2218
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2219
|
+
controls: {
|
|
2220
|
+
breakout: {
|
|
2221
|
+
sessionType: 'MAIN',
|
|
2222
|
+
url: 'breakoutUnifiedUrl2',
|
|
2223
|
+
},
|
|
2224
|
+
},
|
|
2225
|
+
});
|
|
2226
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2227
|
+
});
|
|
2228
|
+
|
|
2229
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2230
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2231
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2232
|
+
controls: {
|
|
2233
|
+
breakout: {
|
|
2234
|
+
sessionType: 'MAIN',
|
|
2235
|
+
url: 'breakoutUnifiedUrl1',
|
|
2236
|
+
},
|
|
2237
|
+
},
|
|
2238
|
+
});
|
|
2239
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {
|
|
2240
|
+
locus: breakoutLocus,
|
|
2241
|
+
locusUrl: breakoutLocus.url,
|
|
2242
|
+
});
|
|
2243
|
+
});
|
|
2244
|
+
});
|
|
2245
|
+
|
|
2246
|
+
describe('uploading of logs', () => {
|
|
2247
|
+
let metricsSpy;
|
|
2248
|
+
let meeting;
|
|
2249
|
+
|
|
2250
|
+
beforeEach(async () => {
|
|
2251
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2252
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2253
|
+
|
|
2254
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2255
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2256
|
+
|
|
2257
|
+
triggerProxyStub.restore();
|
|
2258
|
+
|
|
2259
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2260
|
+
|
|
2261
|
+
meeting = await webex.meetings.create('test');
|
|
2262
|
+
|
|
2263
|
+
meeting.locusId = 'locus id';
|
|
2264
|
+
meeting.correlationId = 'correlation id';
|
|
2265
|
+
meeting.locusInfo = {
|
|
2266
|
+
fullState: {lastActive: 'last active', sessionId: 'locus session id'},
|
|
2267
|
+
info: {webExMeetingId: 'meeting id'},
|
|
2268
|
+
};
|
|
2269
|
+
});
|
|
2270
|
+
|
|
2271
|
+
afterEach(() => {
|
|
2272
|
+
sinon.restore();
|
|
2273
|
+
});
|
|
2274
|
+
|
|
2275
|
+
it('sends metrics on success', async () => {
|
|
2276
|
+
await meeting.uploadLogs();
|
|
2277
|
+
|
|
2278
|
+
await testUtils.flushPromises();
|
|
2279
|
+
|
|
2280
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2281
|
+
callStart: 'last active',
|
|
2282
|
+
correlationId: 'correlation id',
|
|
2283
|
+
feedbackId: 'correlation id',
|
|
2284
|
+
locusId: 'locus id',
|
|
2285
|
+
meetingId: 'meeting id',
|
|
2286
|
+
autoupload: true,
|
|
2287
|
+
locussessionid: 'locus session id',
|
|
2288
|
+
});
|
|
2289
|
+
});
|
|
2290
|
+
|
|
2291
|
+
it('sends metrics on failure', async () => {
|
|
2292
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2293
|
+
|
|
2294
|
+
await meeting.uploadLogs();
|
|
2295
|
+
|
|
2296
|
+
await testUtils.flushPromises();
|
|
2297
|
+
|
|
2298
|
+
assert.calledOnceWithExactly(
|
|
2299
|
+
metricsSpy,
|
|
2300
|
+
'js_sdk_upload_logs_failure',
|
|
2301
|
+
sinon.match({
|
|
2302
|
+
callStart: 'last active',
|
|
2303
|
+
correlationId: 'correlation id',
|
|
2304
|
+
feedbackId: 'correlation id',
|
|
2305
|
+
locusId: 'locus id',
|
|
2306
|
+
meetingId: 'meeting id',
|
|
2307
|
+
reason: 'fake error',
|
|
2308
|
+
autoupload: true,
|
|
2309
|
+
locussessionid: 'locus session id',
|
|
2310
|
+
})
|
|
2311
|
+
);
|
|
2312
|
+
});
|
|
2313
|
+
});
|
|
1371
2314
|
});
|
|
1372
2315
|
});
|