@webex/plugin-meetings 2.59.8 → 2.60.0-next.10
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.d.ts +42 -0
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.d.ts +31 -0
- package/dist/annotation/constants.js +41 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.d.ts +117 -0
- package/dist/annotation/index.js +357 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.d.ts +8 -0
- package/dist/breakouts/breakout.js +215 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.d.ts +5 -0
- package/dist/breakouts/collection.js +22 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/breakouts/edit-lock-error.js +51 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.d.ts +8 -0
- package/dist/breakouts/events.js +44 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.d.ts +5 -0
- package/dist/breakouts/index.js +1047 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/breakouts/request.d.ts +22 -0
- package/dist/breakouts/request.js +77 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.d.ts +15 -0
- package/dist/breakouts/utils.js +64 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/browser-detection.js +2 -3
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +3 -4
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +1 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +1 -2
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +1 -2
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +1 -2
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +1 -2
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/common/errors/no-meeting-info.js +50 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/common/errors/reclaim-host-role-errors.js +154 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/reconnection-in-progress.js +1 -2
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +1 -2
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +1 -2
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.d.ts +20 -8
- package/dist/common/errors/webex-errors.js +48 -28
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +1 -2
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +1 -2
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +1 -2
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +1 -2
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +1 -2
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +1 -2
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +2 -3
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.d.ts +3 -1
- package/dist/common/logs/request.js +8 -5
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.d.ts +9 -7
- package/dist/common/queue.js +22 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.d.ts +5 -7
- package/dist/config.js +8 -11
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +243 -97
- package/dist/constants.js +437 -435
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +3 -6
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.d.ts +11 -1
- package/dist/controls-options-manager/enums.js +15 -6
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.d.ts +17 -1
- package/dist/controls-options-manager/index.js +127 -38
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.d.ts +43 -0
- 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.d.ts +1 -7
- package/dist/controls-options-manager/util.js +309 -19
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +116 -4
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.d.ts +5 -0
- package/dist/interpretation/collection.js +22 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.d.ts +5 -0
- package/dist/interpretation/index.js +365 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.d.ts +5 -0
- package/dist/interpretation/siLanguage.js +24 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +100 -11
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -4
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +1 -2
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +1 -2
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.d.ts +57 -4
- package/dist/locus-info/index.js +425 -84
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +13 -5
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +58 -3
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.d.ts +66 -6
- package/dist/locus-info/parser.js +253 -80
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +97 -13
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.d.ts +2 -0
- package/dist/media/index.js +107 -319
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.d.ts +38 -53
- package/dist/media/properties.js +96 -153
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -22
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.d.ts +234 -230
- package/dist/mediaQualityMetrics/config.js +302 -498
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.d.ts +88 -0
- package/dist/meeting/in-meeting-actions.js +94 -3
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.d.ts +591 -494
- package/dist/meeting/index.js +4728 -2990
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/meeting/locusMediaRequest.js +291 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.d.ts +93 -25
- package/dist/meeting/muteState.js +224 -133
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.d.ts +82 -47
- package/dist/meeting/request.js +297 -199
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.d.ts +11 -0
- package/dist/meeting/request.type.js +7 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.d.ts +102 -1
- package/dist/meeting/util.js +605 -435
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.d.ts +13 -1
- package/dist/meeting-info/index.js +74 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/meeting-info/meeting-info-v2.js +200 -63
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +2 -3
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +39 -41
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.d.ts +17 -0
- package/dist/meetings/collection.js +42 -4
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.d.ts +103 -21
- package/dist/meetings/index.js +486 -124
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.d.ts +4 -0
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +4 -3
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +107 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.d.ts +14 -1
- package/dist/member/index.js +54 -2
- package/dist/member/index.js.map +1 -1
- package/dist/member/member.types.js +3 -4
- package/dist/member/member.types.js.map +1 -1
- package/dist/member/types.d.ts +32 -0
- package/dist/member/types.js +23 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +131 -29
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.d.ts +5 -0
- package/dist/members/collection.js +11 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.d.ts +57 -2
- package/dist/members/index.js +174 -10
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.d.ts +73 -9
- package/dist/members/request.js +108 -41
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.d.ts +25 -0
- package/dist/members/types.js +14 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.d.ts +214 -1
- package/dist/members/util.js +327 -234
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.d.ts +15 -6
- package/dist/metrics/constants.js +17 -9
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.d.ts +4 -111
- package/dist/metrics/index.js +4 -452
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.d.ts +118 -0
- package/dist/multistream/mediaRequestManager.js +344 -0
- package/dist/multistream/mediaRequestManager.js.map +1 -0
- package/dist/multistream/receiveSlot.d.ts +68 -0
- package/dist/multistream/receiveSlot.js +200 -0
- package/dist/multistream/receiveSlot.js.map +1 -0
- package/dist/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/multistream/receiveSlotManager.js +174 -0
- package/dist/multistream/receiveSlotManager.js.map +1 -0
- package/dist/multistream/remoteMedia.d.ts +72 -0
- package/dist/multistream/remoteMedia.js +268 -0
- package/dist/multistream/remoteMedia.js.map +1 -0
- package/dist/multistream/remoteMediaGroup.d.ts +47 -0
- package/dist/multistream/remoteMediaGroup.js +267 -0
- package/dist/multistream/remoteMediaGroup.js.map +1 -0
- package/dist/multistream/remoteMediaManager.d.ts +285 -0
- package/dist/multistream/remoteMediaManager.js +1211 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -0
- package/dist/multistream/sendSlotManager.d.ts +61 -0
- package/dist/multistream/sendSlotManager.js +236 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/networkQualityMonitor/index.js +5 -4
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +2 -3
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -3
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +1 -2
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/index.d.ts +62 -7
- package/dist/reachability/index.js +265 -72
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.d.ts +7 -3
- package/dist/reachability/request.js +18 -10
- package/dist/reachability/request.js.map +1 -1
- package/dist/reactions/constants.d.ts +3 -0
- package/dist/reactions/constants.js +12 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.d.ts +2 -2
- package/dist/reactions/reactions.js +4 -6
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.d.ts +23 -3
- package/dist/reactions/reactions.type.js +21 -23
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.d.ts +32 -8
- package/dist/reconnection-manager/index.js +282 -231
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +4 -5
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.d.ts +15 -1
- package/dist/recording-controller/index.js +57 -46
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.d.ts +5 -4
- package/dist/recording-controller/util.js +10 -10
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.d.ts +9 -47
- package/dist/roap/index.js +101 -235
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.d.ts +18 -12
- package/dist/roap/request.js +126 -180
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +27 -16
- package/dist/roap/turnDiscovery.js +115 -105
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.d.ts +4 -0
- package/dist/rtcMetrics/constants.js +11 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.d.ts +54 -0
- package/dist/rtcMetrics/index.js +140 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.d.ts +1 -83
- package/dist/statsAnalyzer/global.js +2 -85
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.d.ts +28 -30
- package/dist/statsAnalyzer/index.js +374 -509
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +8 -6
- package/dist/statsAnalyzer/mqaUtil.js +116 -83
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +1 -2
- package/dist/transcription/index.js.map +1 -1
- package/dist/webinar/collection.d.ts +16 -0
- package/dist/webinar/collection.js +43 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +68 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +35 -26
- 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 +220 -0
- package/src/breakouts/breakout.ts +188 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +925 -0
- 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/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +36 -12
- 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 +5 -7
- package/src/constants.ts +271 -93
- 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 +110 -0
- package/src/locus-info/index.ts +449 -61
- package/src/locus-info/infoUtils.ts +14 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +85 -2
- package/src/media/index.ts +153 -370
- package/src/media/properties.ts +106 -136
- package/src/media/util.ts +0 -21
- package/src/mediaQualityMetrics/config.ts +244 -377
- package/src/meeting/in-meeting-actions.ts +176 -0
- package/src/meeting/index.ts +3895 -2448
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +224 -138
- package/src/meeting/request.ts +207 -127
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/util.ts +590 -423
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +163 -13
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +28 -28
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +486 -126
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +116 -5
- package/src/member/index.ts +52 -1
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +139 -28
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +196 -7
- 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 +15 -6
- package/src/metrics/index.ts +1 -471
- package/src/multistream/mediaRequestManager.ts +440 -0
- package/src/multistream/receiveSlot.ts +184 -0
- package/src/multistream/receiveSlotManager.ts +166 -0
- package/src/multistream/remoteMedia.ts +254 -0
- package/src/multistream/remoteMediaGroup.ts +284 -0
- package/src/multistream/remoteMediaManager.ts +1145 -0
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/networkQualityMonitor/index.ts +6 -6
- package/src/reachability/index.ts +238 -45
- package/src/reachability/request.ts +17 -8
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.ts +4 -4
- package/src/reactions/reactions.type.ts +30 -4
- package/src/reconnection-manager/index.ts +168 -156
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +98 -241
- package/src/roap/request.ts +74 -148
- package/src/roap/turnDiscovery.ts +62 -56
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +124 -0
- package/src/statsAnalyzer/global.ts +1 -84
- package/src/statsAnalyzer/index.ts +413 -642
- package/src/statsAnalyzer/mqaUtil.ts +111 -114
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +320 -264
- package/test/integration/spec/space-meeting.js +77 -4
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +237 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- 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 +1790 -0
- 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 +323 -30
- package/test/unit/spec/locus-info/index.js +1390 -16
- package/test/unit/spec/locus-info/infoUtils.js +54 -16
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/lib/selfConstant.js +48 -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/selfUtils.js +275 -0
- package/test/unit/spec/media/index.ts +290 -0
- package/test/unit/spec/media/properties.ts +75 -84
- package/test/unit/spec/meeting/in-meeting-actions.ts +86 -0
- package/test/unit/spec/meeting/index.js +8181 -2770
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +409 -213
- package/test/unit/spec/meeting/request.js +512 -42
- package/test/unit/spec/meeting/utils.js +741 -24
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +527 -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 +1284 -217
- package/test/unit/spec/meetings/utils.js +202 -2
- package/test/unit/spec/member/index.js +38 -8
- package/test/unit/spec/member/util.js +499 -29
- package/test/unit/spec/members/index.js +597 -3
- 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 +1418 -0
- package/test/unit/spec/multistream/receiveSlot.ts +163 -0
- package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
- package/test/unit/spec/multistream/remoteMedia.ts +255 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +662 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +1924 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/networkQualityMonitor/index.js +4 -4
- package/test/unit/spec/reachability/index.ts +598 -24
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +162 -24
- package/test/unit/spec/recording-controller/index.js +293 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +200 -76
- package/test/unit/spec/roap/request.ts +232 -0
- package/test/unit/spec/roap/turnDiscovery.ts +86 -48
- package/test/unit/spec/rtcMetrics/index.ts +93 -0
- package/test/unit/spec/stats-analyzer/index.js +188 -174
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/constants.js +9 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -45
- package/test/utils/webex-config.js +4 -0
- package/test/utils/webex-test-users.js +7 -3
- package/dist/meeting/effectsState.d.ts +0 -42
- package/dist/meeting/effectsState.js +0 -260
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.d.ts +0 -169
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/peer-connection-manager/index.d.ts +0 -6
- package/dist/peer-connection-manager/index.js +0 -671
- package/dist/peer-connection-manager/index.js.map +0 -1
- package/dist/peer-connection-manager/util.d.ts +0 -6
- package/dist/peer-connection-manager/util.js +0 -110
- package/dist/peer-connection-manager/util.js.map +0 -1
- package/dist/roap/collection.d.ts +0 -10
- package/dist/roap/collection.js +0 -63
- package/dist/roap/collection.js.map +0 -1
- package/dist/roap/handler.d.ts +0 -47
- package/dist/roap/handler.js +0 -279
- package/dist/roap/handler.js.map +0 -1
- package/dist/roap/state.d.ts +0 -9
- package/dist/roap/state.js +0 -127
- package/dist/roap/state.js.map +0 -1
- package/dist/roap/util.d.ts +0 -2
- package/dist/roap/util.js +0 -76
- package/dist/roap/util.js.map +0 -1
- package/src/index.js +0 -15
- package/src/meeting/effectsState.ts +0 -209
- package/src/metrics/config.ts +0 -485
- package/src/peer-connection-manager/index.ts +0 -847
- package/src/peer-connection-manager/util.ts +0 -119
- package/src/roap/collection.ts +0 -62
- package/src/roap/handler.ts +0 -294
- package/src/roap/state.ts +0 -156
- package/src/roap/util.ts +0 -100
- package/test/unit/spec/meeting/effectsState.js +0 -281
- package/test/unit/spec/peerconnection-manager/index.js +0 -218
- package/test/unit/spec/peerconnection-manager/utils.js +0 -49
- package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -388
- package/test/unit/spec/roap/util.js +0 -30
|
@@ -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,8 +15,8 @@ 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
|
-
import MediaUtil from '@webex/plugin-meetings/src/media/util';
|
|
16
20
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
17
21
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
18
22
|
import Meetings from '@webex/plugin-meetings/src/meetings';
|
|
@@ -20,6 +24,7 @@ import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
|
20
24
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
21
25
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
22
26
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
27
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
23
28
|
|
|
24
29
|
import testUtils from '../../../utils/testUtils';
|
|
25
30
|
import {
|
|
@@ -30,6 +35,12 @@ import {
|
|
|
30
35
|
LOCUSINFO,
|
|
31
36
|
EVENT_TRIGGERS,
|
|
32
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';
|
|
33
44
|
|
|
34
45
|
describe('plugin-meetings', () => {
|
|
35
46
|
const logger = {
|
|
@@ -41,6 +52,8 @@ describe('plugin-meetings', () => {
|
|
|
41
52
|
debug: () => {},
|
|
42
53
|
};
|
|
43
54
|
|
|
55
|
+
let triggerProxyStub;
|
|
56
|
+
|
|
44
57
|
beforeEach(() => {
|
|
45
58
|
StaticConfig.set({
|
|
46
59
|
bandwidth: {
|
|
@@ -52,7 +65,7 @@ describe('plugin-meetings', () => {
|
|
|
52
65
|
verboseEvents: true,
|
|
53
66
|
enable: false,
|
|
54
67
|
});
|
|
55
|
-
|
|
68
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
56
69
|
});
|
|
57
70
|
|
|
58
71
|
let webex;
|
|
@@ -61,15 +74,20 @@ describe('plugin-meetings', () => {
|
|
|
61
74
|
let url1;
|
|
62
75
|
let test1;
|
|
63
76
|
let test2;
|
|
77
|
+
let locusInfo;
|
|
64
78
|
|
|
65
79
|
describe('meetings index', () => {
|
|
66
80
|
beforeEach(() => {
|
|
67
81
|
MeetingsUtil.checkH264Support = sinon.stub();
|
|
68
|
-
|
|
82
|
+
uuid1 = uuid.v4();
|
|
69
83
|
url1 = `https://example.com/${uuid.v4()}`;
|
|
70
84
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
71
85
|
test1 = `test-${uuid.v4()}`;
|
|
72
86
|
test2 = `test2-${uuid.v4()}`;
|
|
87
|
+
locusInfo = {
|
|
88
|
+
parse: sinon.stub().returns(true),
|
|
89
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
90
|
+
};
|
|
73
91
|
webex = new MockWebex({
|
|
74
92
|
children: {
|
|
75
93
|
device: Device,
|
|
@@ -108,6 +126,7 @@ describe('plugin-meetings', () => {
|
|
|
108
126
|
});
|
|
109
127
|
|
|
110
128
|
Object.assign(webex.internal, {
|
|
129
|
+
llm: {on: sinon.stub()},
|
|
111
130
|
device: {
|
|
112
131
|
deviceType: 'FAKE_DEVICE',
|
|
113
132
|
register: sinon.stub().returns(Promise.resolve()),
|
|
@@ -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();
|
|
349
|
-
|
|
350
|
-
assert.notExists(
|
|
351
|
-
reachability,
|
|
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();
|
|
435
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
436
|
+
const reachability = webex.meetings.getReachability();
|
|
365
437
|
|
|
366
|
-
|
|
367
|
-
|
|
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,104 @@ describe('plugin-meetings', () => {
|
|
|
574
635
|
});
|
|
575
636
|
});
|
|
576
637
|
|
|
638
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
639
|
+
const correlationId = 'my-correlationId';
|
|
640
|
+
const callStateForMetrics = {
|
|
641
|
+
correlationId: 'my-correlationId2',
|
|
642
|
+
joinTrigger: 'my-join-trigger',
|
|
643
|
+
loginType: 'my-login-type',
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
it('should call setCallStateForMetrics on any pre-existing meeting', async () => {
|
|
647
|
+
const fakeMeeting = {setCallStateForMetrics: sinon.mock()};
|
|
648
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(fakeMeeting);
|
|
649
|
+
await webex.meetings.create(
|
|
650
|
+
test1,
|
|
651
|
+
test2,
|
|
652
|
+
FAKE_USE_RANDOM_DELAY,
|
|
653
|
+
{},
|
|
654
|
+
correlationId,
|
|
655
|
+
true,
|
|
656
|
+
callStateForMetrics
|
|
657
|
+
);
|
|
658
|
+
assert.calledOnceWithExactly(fakeMeeting.setCallStateForMetrics, {
|
|
659
|
+
...callStateForMetrics,
|
|
660
|
+
correlationId,
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
665
|
+
const create = webex.meetings.create(...createParameters);
|
|
666
|
+
|
|
667
|
+
assert.exists(create.then);
|
|
668
|
+
await create;
|
|
669
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
670
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
671
|
+
};
|
|
672
|
+
|
|
577
673
|
it('calls createMeeting and returns its promise', async () => {
|
|
578
|
-
|
|
579
|
-
|
|
674
|
+
await checkCallCreateMeeting(
|
|
675
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true],
|
|
676
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true]
|
|
677
|
+
);
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
681
|
+
await checkCallCreateMeeting(
|
|
682
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
|
|
683
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
684
|
+
);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
688
|
+
await checkCallCreateMeeting(
|
|
689
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false],
|
|
690
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
691
|
+
);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it('calls createMeeting with callStateForMetrics and returns its promise', async () => {
|
|
695
|
+
await checkCallCreateMeeting(
|
|
696
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, undefined, true, callStateForMetrics],
|
|
697
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, callStateForMetrics, true]
|
|
698
|
+
);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
it('calls createMeeting with callStateForMetrics overwritten with correlationId and returns its promise', async () => {
|
|
702
|
+
await checkCallCreateMeeting(
|
|
703
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, callStateForMetrics],
|
|
704
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {...callStateForMetrics, correlationId}, true]
|
|
705
|
+
);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
709
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
710
|
+
const correlationId = 'my-correlationId';
|
|
711
|
+
|
|
712
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
713
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
714
|
+
joinTXId: 'TSmrX61wNF',
|
|
715
|
+
};
|
|
716
|
+
const create = webex.meetings.create(
|
|
717
|
+
test1,
|
|
718
|
+
test2,
|
|
719
|
+
FAKE_USE_RANDOM_DELAY,
|
|
720
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
721
|
+
correlationId
|
|
722
|
+
);
|
|
580
723
|
|
|
581
724
|
assert.exists(create.then);
|
|
582
725
|
await create;
|
|
583
726
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
584
|
-
assert.calledWith(
|
|
727
|
+
assert.calledWith(
|
|
728
|
+
webex.meetings.createMeeting,
|
|
729
|
+
test1,
|
|
730
|
+
test2,
|
|
731
|
+
FAKE_USE_RANDOM_DELAY,
|
|
732
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
733
|
+
{correlationId},
|
|
734
|
+
false
|
|
735
|
+
);
|
|
585
736
|
});
|
|
586
737
|
|
|
587
738
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -677,45 +828,51 @@ describe('plugin-meetings', () => {
|
|
|
677
828
|
});
|
|
678
829
|
describe('#handleLocusEvent', () => {
|
|
679
830
|
describe('there was a meeting', () => {
|
|
680
|
-
let parse;
|
|
681
|
-
|
|
682
831
|
beforeEach(() => {
|
|
683
|
-
parse = sinon.stub().returns(true);
|
|
684
832
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
685
|
-
locusInfo
|
|
686
|
-
parse,
|
|
687
|
-
},
|
|
833
|
+
locusInfo,
|
|
688
834
|
});
|
|
689
835
|
});
|
|
690
|
-
it('should parse the meeting info', () => {
|
|
836
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
837
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
691
838
|
webex.meetings.handleLocusEvent({
|
|
692
839
|
locusUrl: url1,
|
|
693
840
|
});
|
|
694
841
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
695
842
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
696
|
-
assert.calledOnce(parse);
|
|
843
|
+
assert.calledOnce(locusInfo.parse);
|
|
844
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
697
845
|
assert.calledWith(
|
|
698
|
-
parse,
|
|
846
|
+
locusInfo.parse,
|
|
699
847
|
{
|
|
700
|
-
locusInfo
|
|
701
|
-
parse,
|
|
702
|
-
},
|
|
848
|
+
locusInfo,
|
|
703
849
|
},
|
|
704
850
|
{
|
|
705
851
|
locusUrl: url1,
|
|
706
852
|
}
|
|
707
853
|
);
|
|
708
854
|
});
|
|
855
|
+
|
|
856
|
+
it('should not update main session locus cache', () => {
|
|
857
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
858
|
+
webex.meetings.handleLocusEvent({
|
|
859
|
+
locusUrl: url1,
|
|
860
|
+
});
|
|
861
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
862
|
+
});
|
|
709
863
|
});
|
|
710
864
|
describe('there was not a meeting', () => {
|
|
711
865
|
let initialSetup;
|
|
866
|
+
const webExMeetingId = '123456';
|
|
712
867
|
|
|
713
868
|
beforeEach(() => {
|
|
714
869
|
initialSetup = sinon.stub().returns(true);
|
|
715
870
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
716
871
|
webex.meetings.create = sinon.stub().returns(
|
|
717
872
|
Promise.resolve({
|
|
873
|
+
id: 'meeting-id',
|
|
718
874
|
locusInfo: {
|
|
875
|
+
...locusInfo,
|
|
719
876
|
initialSetup,
|
|
720
877
|
},
|
|
721
878
|
})
|
|
@@ -735,12 +892,20 @@ describe('plugin-meetings', () => {
|
|
|
735
892
|
callbackAddress: uri1,
|
|
736
893
|
},
|
|
737
894
|
},
|
|
895
|
+
info: {
|
|
896
|
+
webExMeetingId,
|
|
897
|
+
},
|
|
738
898
|
},
|
|
739
899
|
eventType: 'locus.difference',
|
|
740
900
|
locusUrl: url1,
|
|
741
901
|
});
|
|
742
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
902
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
743
903
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
904
|
+
assert.calledWith(
|
|
905
|
+
webex.meetings.meetingCollection.getByKey,
|
|
906
|
+
'meetingNumber',
|
|
907
|
+
webExMeetingId
|
|
908
|
+
);
|
|
744
909
|
assert.calledOnce(initialSetup);
|
|
745
910
|
assert.calledWith(initialSetup, {
|
|
746
911
|
id: uuid1,
|
|
@@ -754,6 +919,9 @@ describe('plugin-meetings', () => {
|
|
|
754
919
|
callbackAddress: uri1,
|
|
755
920
|
},
|
|
756
921
|
},
|
|
922
|
+
info: {
|
|
923
|
+
webExMeetingId,
|
|
924
|
+
},
|
|
757
925
|
});
|
|
758
926
|
});
|
|
759
927
|
it('should setup the meeting by difference event without replaces', async () => {
|
|
@@ -765,12 +933,20 @@ describe('plugin-meetings', () => {
|
|
|
765
933
|
callbackAddress: uri1,
|
|
766
934
|
},
|
|
767
935
|
},
|
|
936
|
+
info: {
|
|
937
|
+
webExMeetingId,
|
|
938
|
+
},
|
|
768
939
|
},
|
|
769
940
|
eventType: 'locus.difference',
|
|
770
941
|
locusUrl: url1,
|
|
771
942
|
});
|
|
772
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
943
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
773
944
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
945
|
+
assert.calledWith(
|
|
946
|
+
webex.meetings.meetingCollection.getByKey,
|
|
947
|
+
'meetingNumber',
|
|
948
|
+
webExMeetingId
|
|
949
|
+
);
|
|
774
950
|
assert.calledOnce(initialSetup);
|
|
775
951
|
assert.calledWith(initialSetup, {
|
|
776
952
|
id: uuid1,
|
|
@@ -779,8 +955,44 @@ describe('plugin-meetings', () => {
|
|
|
779
955
|
callbackAddress: uri1,
|
|
780
956
|
},
|
|
781
957
|
},
|
|
958
|
+
info: {
|
|
959
|
+
webExMeetingId,
|
|
960
|
+
},
|
|
961
|
+
});
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
it('sends client event correctly on finally', async () => {
|
|
965
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
966
|
+
|
|
967
|
+
await webex.meetings.handleLocusEvent({
|
|
968
|
+
locus: {
|
|
969
|
+
id: uuid1,
|
|
970
|
+
self: {
|
|
971
|
+
callBackInfo: {
|
|
972
|
+
callbackAddress: uri1,
|
|
973
|
+
},
|
|
974
|
+
},
|
|
975
|
+
info: {
|
|
976
|
+
webExMeetingId,
|
|
977
|
+
},
|
|
978
|
+
},
|
|
979
|
+
eventType: 'locus.difference',
|
|
980
|
+
locusUrl: url1,
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
await testUtils.flushPromises();
|
|
984
|
+
|
|
985
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
986
|
+
name: 'client.call.remote-started',
|
|
987
|
+
payload: {
|
|
988
|
+
trigger: 'mercury-event',
|
|
989
|
+
},
|
|
990
|
+
options: {
|
|
991
|
+
meetingId: 'meeting-id',
|
|
992
|
+
},
|
|
782
993
|
});
|
|
783
994
|
});
|
|
995
|
+
|
|
784
996
|
it('should setup the meeting by a not difference event', async () => {
|
|
785
997
|
await webex.meetings.handleLocusEvent({
|
|
786
998
|
locus: {
|
|
@@ -790,12 +1002,20 @@ describe('plugin-meetings', () => {
|
|
|
790
1002
|
callbackAddress: uri1,
|
|
791
1003
|
},
|
|
792
1004
|
},
|
|
1005
|
+
info: {
|
|
1006
|
+
webExMeetingId,
|
|
1007
|
+
},
|
|
793
1008
|
},
|
|
794
1009
|
eventType: test1,
|
|
795
1010
|
locusUrl: url1,
|
|
796
1011
|
});
|
|
797
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1012
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
798
1013
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1014
|
+
assert.calledWith(
|
|
1015
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1016
|
+
'meetingNumber',
|
|
1017
|
+
webExMeetingId
|
|
1018
|
+
);
|
|
799
1019
|
assert.calledOnce(initialSetup);
|
|
800
1020
|
assert.calledWith(initialSetup, {
|
|
801
1021
|
id: uuid1,
|
|
@@ -804,6 +1024,9 @@ describe('plugin-meetings', () => {
|
|
|
804
1024
|
callbackAddress: uri1,
|
|
805
1025
|
},
|
|
806
1026
|
},
|
|
1027
|
+
info: {
|
|
1028
|
+
webExMeetingId,
|
|
1029
|
+
},
|
|
807
1030
|
});
|
|
808
1031
|
});
|
|
809
1032
|
|
|
@@ -826,7 +1049,7 @@ describe('plugin-meetings', () => {
|
|
|
826
1049
|
|
|
827
1050
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
828
1051
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
|
|
829
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1052
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
830
1053
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
831
1054
|
'locusUrl',
|
|
832
1055
|
url1,
|
|
@@ -843,7 +1066,7 @@ describe('plugin-meetings', () => {
|
|
|
843
1066
|
});
|
|
844
1067
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
845
1068
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
|
|
846
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1069
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
847
1070
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
848
1071
|
'locusUrl',
|
|
849
1072
|
url1,
|
|
@@ -866,7 +1089,6 @@ describe('plugin-meetings', () => {
|
|
|
866
1089
|
});
|
|
867
1090
|
describe('#createMeeting', () => {
|
|
868
1091
|
beforeEach(() => {
|
|
869
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
870
1092
|
webex.internal.device.userId = uuid1;
|
|
871
1093
|
webex.internal.device.url = url1;
|
|
872
1094
|
MeetingCollection.set = sinon.stub().returns(true);
|
|
@@ -875,6 +1097,10 @@ describe('plugin-meetings', () => {
|
|
|
875
1097
|
});
|
|
876
1098
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
877
1099
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1100
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
1101
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
1102
|
+
joinTXId: 'TSmrX61wNF',
|
|
1103
|
+
};
|
|
878
1104
|
|
|
879
1105
|
beforeEach(() => {
|
|
880
1106
|
clock = sinon.useFakeTimers();
|
|
@@ -904,13 +1130,25 @@ describe('plugin-meetings', () => {
|
|
|
904
1130
|
meeting,
|
|
905
1131
|
destination,
|
|
906
1132
|
type,
|
|
907
|
-
|
|
1133
|
+
extraParams = {},
|
|
1134
|
+
expectedMeetingData = {},
|
|
1135
|
+
sendCAevents = false
|
|
908
1136
|
) => {
|
|
909
1137
|
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
910
1138
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
911
1139
|
assert.notCalled(setTimeoutSpy);
|
|
912
|
-
assert.
|
|
913
|
-
assert.calledWith(
|
|
1140
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1141
|
+
assert.calledWith(
|
|
1142
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1143
|
+
destination,
|
|
1144
|
+
type,
|
|
1145
|
+
null,
|
|
1146
|
+
null,
|
|
1147
|
+
undefined,
|
|
1148
|
+
undefined,
|
|
1149
|
+
extraParams,
|
|
1150
|
+
{meetingId: meeting.id, sendCAevents}
|
|
1151
|
+
);
|
|
914
1152
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
915
1153
|
|
|
916
1154
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -919,6 +1157,15 @@ describe('plugin-meetings', () => {
|
|
|
919
1157
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
920
1158
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
921
1159
|
}
|
|
1160
|
+
if (expectedMeetingData.correlationId) {
|
|
1161
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1162
|
+
}
|
|
1163
|
+
if (expectedMeetingData.callStateForMetrics) {
|
|
1164
|
+
assert.deepEqual(
|
|
1165
|
+
meeting.callStateForMetrics,
|
|
1166
|
+
expectedMeetingData.callStateForMetrics
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
922
1169
|
assert.equal(meeting.destination, destination);
|
|
923
1170
|
assert.equal(meeting.destinationType, type);
|
|
924
1171
|
assert.calledWith(
|
|
@@ -948,107 +1195,139 @@ describe('plugin-meetings', () => {
|
|
|
948
1195
|
const expectedMeetingData = {
|
|
949
1196
|
permissionToken: 'PT',
|
|
950
1197
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
1198
|
+
correlationId: meeting.id,
|
|
951
1199
|
};
|
|
952
1200
|
|
|
953
|
-
checkCreateWithoutDelay(
|
|
954
|
-
});
|
|
955
|
-
|
|
956
|
-
it('creates the meeting from a successful meeting info fetch meeting resolve testing', async () => {
|
|
957
|
-
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
958
|
-
const expectedMeetingData = {
|
|
959
|
-
permissionToken: 'PT',
|
|
960
|
-
meetingJoinUrl: 'meetingJoinUrl',
|
|
961
|
-
};
|
|
962
|
-
|
|
963
|
-
assert.instanceOf(
|
|
1201
|
+
checkCreateWithoutDelay(
|
|
964
1202
|
meeting,
|
|
965
|
-
|
|
966
|
-
'
|
|
1203
|
+
'test destination',
|
|
1204
|
+
'test type',
|
|
1205
|
+
{},
|
|
1206
|
+
expectedMeetingData
|
|
967
1207
|
);
|
|
968
|
-
checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
|
|
969
1208
|
});
|
|
970
1209
|
|
|
971
|
-
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1210
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1211
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
1212
|
+
|
|
1213
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${
|
|
1214
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1215
|
+
}`, async () => {
|
|
1216
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1217
|
+
'test destination',
|
|
1218
|
+
'test type',
|
|
1219
|
+
false,
|
|
1220
|
+
infoExtraParams
|
|
1221
|
+
);
|
|
1222
|
+
const expectedMeetingData = {
|
|
1223
|
+
permissionToken: 'PT',
|
|
1224
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
assert.instanceOf(
|
|
1228
|
+
meeting,
|
|
1229
|
+
Meeting,
|
|
1230
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1231
|
+
);
|
|
1232
|
+
checkCreateWithoutDelay(
|
|
1233
|
+
meeting,
|
|
1234
|
+
'test destination',
|
|
1235
|
+
'test type',
|
|
1236
|
+
infoExtraParamsProvided ? infoExtraParams : {},
|
|
1237
|
+
expectedMeetingData
|
|
1238
|
+
);
|
|
1239
|
+
});
|
|
987
1240
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1241
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${
|
|
1242
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1243
|
+
}`, async () => {
|
|
1244
|
+
const FAKE_LOCUS_MEETING = {
|
|
1245
|
+
conversationUrl: 'locusConvURL',
|
|
1246
|
+
url: 'locusUrl',
|
|
1247
|
+
info: {
|
|
1248
|
+
webExMeetingId: 'locusMeetingId',
|
|
1249
|
+
sipUri: 'locusSipUri',
|
|
1250
|
+
owner: 'locusOwner',
|
|
1251
|
+
},
|
|
1252
|
+
meeting: {
|
|
1253
|
+
startTime: fakeMeetingStartTimeString,
|
|
1254
|
+
},
|
|
1255
|
+
fullState: {
|
|
1256
|
+
active: false,
|
|
1257
|
+
},
|
|
1258
|
+
};
|
|
993
1259
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
assert.calledOnce(setTimeoutSpy);
|
|
1001
|
-
|
|
1002
|
-
// Parse meeting info with locus object
|
|
1003
|
-
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1004
|
-
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1005
|
-
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1006
|
-
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1007
|
-
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1008
|
-
assert.equal(meeting.owner, 'locusOwner');
|
|
1009
|
-
assert.isUndefined(meeting.permissionToken);
|
|
1010
|
-
|
|
1011
|
-
// Add meeting and send trigger
|
|
1012
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1013
|
-
assert.calledTwice(TriggerProxy.trigger);
|
|
1014
|
-
assert.calledWith(
|
|
1015
|
-
TriggerProxy.trigger,
|
|
1016
|
-
sinon.match.instanceOf(Meetings),
|
|
1017
|
-
{
|
|
1018
|
-
file: 'meetings',
|
|
1019
|
-
function: 'createMeeting',
|
|
1020
|
-
},
|
|
1021
|
-
'meeting:added',
|
|
1022
|
-
{
|
|
1023
|
-
meeting: sinon.match.instanceOf(Meeting),
|
|
1024
|
-
type: 'test meeting added type',
|
|
1025
|
-
}
|
|
1026
|
-
);
|
|
1260
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1261
|
+
FAKE_LOCUS_MEETING,
|
|
1262
|
+
'test type',
|
|
1263
|
+
true,
|
|
1264
|
+
infoExtraParams
|
|
1265
|
+
);
|
|
1027
1266
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1267
|
+
assert.instanceOf(
|
|
1268
|
+
meeting,
|
|
1269
|
+
Meeting,
|
|
1270
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1271
|
+
);
|
|
1272
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1273
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1274
|
+
|
|
1275
|
+
// Parse meeting info with locus object
|
|
1276
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1277
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1278
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1279
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1280
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1281
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1282
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1283
|
+
|
|
1284
|
+
// Add meeting and send trigger
|
|
1285
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1286
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1287
|
+
assert.calledWith(
|
|
1288
|
+
TriggerProxy.trigger,
|
|
1289
|
+
sinon.match.instanceOf(Meetings),
|
|
1290
|
+
{
|
|
1291
|
+
file: 'meetings',
|
|
1292
|
+
function: 'createMeeting',
|
|
1293
|
+
},
|
|
1294
|
+
'meeting:added',
|
|
1295
|
+
{
|
|
1296
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1297
|
+
type: 'test meeting added type',
|
|
1298
|
+
}
|
|
1299
|
+
);
|
|
1035
1300
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1301
|
+
// When timer expires
|
|
1302
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1303
|
+
assert.calledWith(
|
|
1304
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1305
|
+
FAKE_LOCUS_MEETING,
|
|
1306
|
+
'test type',
|
|
1307
|
+
null,
|
|
1308
|
+
null,
|
|
1309
|
+
undefined,
|
|
1310
|
+
undefined,
|
|
1311
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1312
|
+
);
|
|
1045
1313
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
meeting,
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1314
|
+
// Parse meeting info is called again with new meeting info
|
|
1315
|
+
await testUtils.flushPromises();
|
|
1316
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1317
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1318
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1319
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1320
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1321
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1322
|
+
assert.equal(meeting.permissionToken, 'PT');
|
|
1323
|
+
|
|
1324
|
+
assert.calledWith(
|
|
1325
|
+
TriggerProxy.trigger,
|
|
1326
|
+
meeting,
|
|
1327
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1328
|
+
'meeting:meetingInfoAvailable'
|
|
1329
|
+
);
|
|
1330
|
+
});
|
|
1052
1331
|
});
|
|
1053
1332
|
|
|
1054
1333
|
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
@@ -1148,54 +1427,200 @@ describe('plugin-meetings', () => {
|
|
|
1148
1427
|
);
|
|
1149
1428
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1150
1429
|
});
|
|
1151
|
-
});
|
|
1152
|
-
|
|
1153
|
-
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
1154
|
-
beforeEach(() => {
|
|
1155
|
-
console.error = sinon.stub().returns(false);
|
|
1156
|
-
TriggerProxy.trigger.reset();
|
|
1157
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1158
|
-
.stub()
|
|
1159
|
-
.returns(Promise.reject(new Error('test')));
|
|
1160
|
-
});
|
|
1161
|
-
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1162
|
-
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1163
1430
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
'
|
|
1431
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1432
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1433
|
+
'test destination',
|
|
1434
|
+
'test type',
|
|
1435
|
+
false,
|
|
1436
|
+
{},
|
|
1437
|
+
{correlationId: 'my-correlationId'}
|
|
1168
1438
|
);
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1439
|
+
|
|
1440
|
+
const expectedMeetingData = {
|
|
1441
|
+
correlationId: 'my-correlationId',
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
checkCreateWithoutDelay(
|
|
1445
|
+
meeting,
|
|
1174
1446
|
'test destination',
|
|
1175
|
-
'test type'
|
|
1447
|
+
'test type',
|
|
1448
|
+
{},
|
|
1449
|
+
expectedMeetingData,
|
|
1450
|
+
true
|
|
1176
1451
|
);
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
},
|
|
1185
|
-
'meeting:added',
|
|
1452
|
+
});
|
|
1453
|
+
|
|
1454
|
+
it('creates meeting with the callStateForMetrics provided', async () => {
|
|
1455
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1456
|
+
'test destination',
|
|
1457
|
+
'test type',
|
|
1458
|
+
false,
|
|
1459
|
+
{},
|
|
1186
1460
|
{
|
|
1187
|
-
|
|
1188
|
-
|
|
1461
|
+
correlationId: 'my-correlationId',
|
|
1462
|
+
joinTrigger: 'my-join-trigger',
|
|
1463
|
+
loginType: 'my-login-type',
|
|
1189
1464
|
}
|
|
1190
1465
|
);
|
|
1466
|
+
|
|
1467
|
+
const expectedMeetingData = {
|
|
1468
|
+
correlationId: 'my-correlationId',
|
|
1469
|
+
callStateForMetrics: {
|
|
1470
|
+
correlationId: 'my-correlationId',
|
|
1471
|
+
joinTrigger: 'my-join-trigger',
|
|
1472
|
+
loginType: 'my-login-type',
|
|
1473
|
+
},
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
checkCreateWithoutDelay(
|
|
1477
|
+
meeting,
|
|
1478
|
+
'test destination',
|
|
1479
|
+
'test type',
|
|
1480
|
+
{},
|
|
1481
|
+
expectedMeetingData,
|
|
1482
|
+
true
|
|
1483
|
+
);
|
|
1191
1484
|
});
|
|
1192
1485
|
});
|
|
1486
|
+
|
|
1487
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
1488
|
+
beforeEach(() => {
|
|
1489
|
+
console.error = sinon.stub().returns(false);
|
|
1490
|
+
TriggerProxy.trigger.reset();
|
|
1491
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1492
|
+
.stub()
|
|
1493
|
+
.returns(Promise.reject(new Error('test')));
|
|
1494
|
+
webex.meetings.destroy = sinon.stub().returns(Promise.resolve());
|
|
1495
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1496
|
+
});
|
|
1497
|
+
|
|
1498
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1499
|
+
try {
|
|
1500
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1501
|
+
'test destination',
|
|
1502
|
+
'test type',
|
|
1503
|
+
undefined,
|
|
1504
|
+
undefined,
|
|
1505
|
+
undefined,
|
|
1506
|
+
failOnMissingMeetingInfo
|
|
1507
|
+
);
|
|
1508
|
+
|
|
1509
|
+
assert.instanceOf(
|
|
1510
|
+
meeting,
|
|
1511
|
+
Meeting,
|
|
1512
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1513
|
+
);
|
|
1514
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1515
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1516
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1517
|
+
assert.calledWith(
|
|
1518
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1519
|
+
'test destination',
|
|
1520
|
+
'test type'
|
|
1521
|
+
);
|
|
1522
|
+
|
|
1523
|
+
if (destroy) {
|
|
1524
|
+
assert.calledWith(
|
|
1525
|
+
webex.meetings.destroy,
|
|
1526
|
+
sinon.match.instanceOf(Meeting),
|
|
1527
|
+
'MISSING_MEETING_INFO'
|
|
1528
|
+
);
|
|
1529
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1530
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1531
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1532
|
+
} else {
|
|
1533
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1534
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1535
|
+
assert.calledWith(
|
|
1536
|
+
TriggerProxy.trigger,
|
|
1537
|
+
sinon.match.instanceOf(Meetings),
|
|
1538
|
+
{
|
|
1539
|
+
file: 'meetings',
|
|
1540
|
+
function: 'createMeeting',
|
|
1541
|
+
},
|
|
1542
|
+
'meeting:added',
|
|
1543
|
+
{
|
|
1544
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1545
|
+
type: 'test meeting added type',
|
|
1546
|
+
}
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
} catch (err) {
|
|
1550
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1553
|
+
|
|
1554
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1555
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1556
|
+
});
|
|
1557
|
+
|
|
1558
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1559
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1560
|
+
});
|
|
1561
|
+
});
|
|
1562
|
+
|
|
1563
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1564
|
+
forEach(
|
|
1565
|
+
[
|
|
1566
|
+
{
|
|
1567
|
+
error: new CaptchaError(),
|
|
1568
|
+
debugLogMessage:
|
|
1569
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
error: new PasswordError(),
|
|
1573
|
+
debugLogMessage:
|
|
1574
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1575
|
+
},
|
|
1576
|
+
{
|
|
1577
|
+
error: new PermissionError(),
|
|
1578
|
+
debugLogMessage:
|
|
1579
|
+
'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.',
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
error: new Error(),
|
|
1583
|
+
infoLogMessage: true,
|
|
1584
|
+
debugLogMessage:
|
|
1585
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1586
|
+
},
|
|
1587
|
+
],
|
|
1588
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1589
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1590
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1591
|
+
.stub()
|
|
1592
|
+
.returns(Promise.reject(error));
|
|
1593
|
+
|
|
1594
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1595
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1596
|
+
|
|
1597
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1598
|
+
|
|
1599
|
+
assert.instanceOf(
|
|
1600
|
+
meeting,
|
|
1601
|
+
Meeting,
|
|
1602
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1603
|
+
);
|
|
1604
|
+
|
|
1605
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1606
|
+
|
|
1607
|
+
if (infoLogMessage) {
|
|
1608
|
+
assert.calledWith(
|
|
1609
|
+
LoggerProxy.logger.info,
|
|
1610
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1611
|
+
);
|
|
1612
|
+
} else {
|
|
1613
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
);
|
|
1618
|
+
});
|
|
1193
1619
|
});
|
|
1194
1620
|
});
|
|
1195
1621
|
describe('Public Event Triggers', () => {
|
|
1196
1622
|
describe('#destroy', () => {
|
|
1197
1623
|
beforeEach(() => {
|
|
1198
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
1199
1624
|
MeetingUtil.cleanUp = sinon.stub();
|
|
1200
1625
|
});
|
|
1201
1626
|
it('should have #destroy', () => {
|
|
@@ -1269,6 +1694,8 @@ describe('plugin-meetings', () => {
|
|
|
1269
1694
|
});
|
|
1270
1695
|
|
|
1271
1696
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1697
|
+
let loggerProxySpy;
|
|
1698
|
+
|
|
1272
1699
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1273
1700
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1274
1701
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1276,7 +1703,22 @@ describe('plugin-meetings', () => {
|
|
|
1276
1703
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1277
1704
|
});
|
|
1278
1705
|
|
|
1706
|
+
const setup = ({user} = {}) => {
|
|
1707
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1708
|
+
|
|
1709
|
+
Object.assign(webex.internal, {
|
|
1710
|
+
services: {
|
|
1711
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1712
|
+
},
|
|
1713
|
+
user: {
|
|
1714
|
+
get: sinon.stub().returns(Promise.resolve(user)),
|
|
1715
|
+
},
|
|
1716
|
+
});
|
|
1717
|
+
};
|
|
1718
|
+
|
|
1279
1719
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1720
|
+
setup();
|
|
1721
|
+
|
|
1280
1722
|
Object.assign(webex.internal, {
|
|
1281
1723
|
services: {
|
|
1282
1724
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
@@ -1286,7 +1728,115 @@ describe('plugin-meetings', () => {
|
|
|
1286
1728
|
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1287
1729
|
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1288
1730
|
});
|
|
1731
|
+
assert.calledOnceWithExactly(
|
|
1732
|
+
loggerProxySpy,
|
|
1733
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1734
|
+
);
|
|
1735
|
+
});
|
|
1736
|
+
|
|
1737
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1738
|
+
setup({
|
|
1739
|
+
user: {
|
|
1740
|
+
userPreferences: {
|
|
1741
|
+
userPreferencesItems: {
|
|
1742
|
+
preferredWebExSite: 'site.webex.com',
|
|
1743
|
+
},
|
|
1744
|
+
},
|
|
1745
|
+
},
|
|
1746
|
+
});
|
|
1747
|
+
|
|
1748
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1749
|
+
|
|
1750
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1751
|
+
assert.notCalled(loggerProxySpy);
|
|
1752
|
+
});
|
|
1753
|
+
|
|
1754
|
+
forEach(
|
|
1755
|
+
[
|
|
1756
|
+
{user: undefined},
|
|
1757
|
+
{user: {userPreferences: {}}},
|
|
1758
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1759
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1760
|
+
],
|
|
1761
|
+
({user}) => {
|
|
1762
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1763
|
+
setup({user});
|
|
1764
|
+
|
|
1765
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1766
|
+
|
|
1767
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1768
|
+
assert.calledOnceWithExactly(
|
|
1769
|
+
loggerProxySpy,
|
|
1770
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1771
|
+
);
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1774
|
+
);
|
|
1775
|
+
|
|
1776
|
+
it('should handle a get user failure', async () => {
|
|
1777
|
+
setup();
|
|
1778
|
+
|
|
1779
|
+
webex.internal.user.get.rejects(new Error());
|
|
1780
|
+
|
|
1781
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1782
|
+
|
|
1783
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1784
|
+
assert.calledOnceWithExactly(
|
|
1785
|
+
loggerProxySpy,
|
|
1786
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1787
|
+
);
|
|
1788
|
+
});
|
|
1789
|
+
|
|
1790
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1791
|
+
setup({
|
|
1792
|
+
user: {
|
|
1793
|
+
userPreferences: {
|
|
1794
|
+
userPreferencesItems: {
|
|
1795
|
+
preferredWebExSite: 'site.webex.com',
|
|
1796
|
+
},
|
|
1797
|
+
},
|
|
1798
|
+
},
|
|
1799
|
+
});
|
|
1800
|
+
|
|
1801
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1802
|
+
|
|
1803
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1804
|
+
assert.notCalled(loggerProxySpy);
|
|
1805
|
+
});
|
|
1806
|
+
|
|
1807
|
+
forEach([
|
|
1808
|
+
{user: undefined},
|
|
1809
|
+
{user: {userPreferences: {}}},
|
|
1810
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1811
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1812
|
+
], ({user}) => {
|
|
1813
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1814
|
+
setup({user});
|
|
1815
|
+
|
|
1816
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1817
|
+
|
|
1818
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1819
|
+
assert.calledOnceWithExactly(
|
|
1820
|
+
loggerProxySpy,
|
|
1821
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1822
|
+
);
|
|
1823
|
+
});
|
|
1824
|
+
});
|
|
1825
|
+
|
|
1826
|
+
it('should handle a get user failure', async () => {
|
|
1827
|
+
setup();
|
|
1828
|
+
|
|
1829
|
+
webex.internal.user.get.rejects(new Error());
|
|
1830
|
+
|
|
1831
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1832
|
+
|
|
1833
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1834
|
+
assert.calledOnceWithExactly(
|
|
1835
|
+
loggerProxySpy,
|
|
1836
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1837
|
+
);
|
|
1289
1838
|
});
|
|
1839
|
+
|
|
1290
1840
|
});
|
|
1291
1841
|
});
|
|
1292
1842
|
|
|
@@ -1294,7 +1844,6 @@ describe('plugin-meetings', () => {
|
|
|
1294
1844
|
let meeting;
|
|
1295
1845
|
|
|
1296
1846
|
beforeEach(async () => {
|
|
1297
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
1298
1847
|
webex.internal.device.userId = uuid1;
|
|
1299
1848
|
webex.internal.device.url = url1;
|
|
1300
1849
|
MeetingCollection.set = sinon.stub().returns(true);
|
|
@@ -1371,5 +1920,523 @@ describe('plugin-meetings', () => {
|
|
|
1371
1920
|
);
|
|
1372
1921
|
});
|
|
1373
1922
|
});
|
|
1923
|
+
|
|
1924
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
1925
|
+
let meeting;
|
|
1926
|
+
let newLocus;
|
|
1927
|
+
beforeEach(() => {
|
|
1928
|
+
meeting = {
|
|
1929
|
+
controls: {},
|
|
1930
|
+
self: {},
|
|
1931
|
+
};
|
|
1932
|
+
newLocus = {
|
|
1933
|
+
controls: {},
|
|
1934
|
+
self: {},
|
|
1935
|
+
};
|
|
1936
|
+
});
|
|
1937
|
+
afterEach(() => {
|
|
1938
|
+
sinon.restore();
|
|
1939
|
+
});
|
|
1940
|
+
it('check normal case will return true', () => {
|
|
1941
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1942
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1943
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1944
|
+
assert.equal(result, true);
|
|
1945
|
+
assert.calledWith(
|
|
1946
|
+
LoggerProxy.logger.log,
|
|
1947
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1948
|
+
);
|
|
1949
|
+
});
|
|
1950
|
+
|
|
1951
|
+
it('check self joined and joined on this device, return true', () => {
|
|
1952
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1953
|
+
newLocus.self.state = 'JOINED';
|
|
1954
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1955
|
+
|
|
1956
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1957
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1958
|
+
assert.equal(result, true);
|
|
1959
|
+
assert.calledWith(
|
|
1960
|
+
LoggerProxy.logger.log,
|
|
1961
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
1962
|
+
);
|
|
1963
|
+
});
|
|
1964
|
+
|
|
1965
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
1966
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1967
|
+
joinedWith: {
|
|
1968
|
+
replaces: [
|
|
1969
|
+
{
|
|
1970
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
1971
|
+
},
|
|
1972
|
+
],
|
|
1973
|
+
},
|
|
1974
|
+
});
|
|
1975
|
+
newLocus.self.state = 'JOINED';
|
|
1976
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1977
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1978
|
+
replaces: [
|
|
1979
|
+
{
|
|
1980
|
+
replaceAt: '2023-03-27T02:17:01.506Z',
|
|
1981
|
+
},
|
|
1982
|
+
],
|
|
1983
|
+
});
|
|
1984
|
+
|
|
1985
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1986
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1987
|
+
assert.equal(result, false);
|
|
1988
|
+
assert.calledWith(
|
|
1989
|
+
LoggerProxy.logger.log,
|
|
1990
|
+
`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`
|
|
1991
|
+
);
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
1995
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1996
|
+
joinedWith: {
|
|
1997
|
+
correlationId: '111',
|
|
1998
|
+
},
|
|
1999
|
+
});
|
|
2000
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
2001
|
+
meeting.correlationId = '111';
|
|
2002
|
+
|
|
2003
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2004
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2005
|
+
assert.equal(result, false);
|
|
2006
|
+
assert.calledWith(
|
|
2007
|
+
LoggerProxy.logger.log,
|
|
2008
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
2009
|
+
);
|
|
2010
|
+
});
|
|
2011
|
+
|
|
2012
|
+
it('check self is moved and removed, return false', () => {
|
|
2013
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2014
|
+
newLocus.self.state = 'LEFT';
|
|
2015
|
+
newLocus.self.reason = 'MOVED';
|
|
2016
|
+
newLocus.self.removed = true;
|
|
2017
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2018
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2019
|
+
assert.equal(result, false);
|
|
2020
|
+
assert.calledWith(
|
|
2021
|
+
LoggerProxy.logger.log,
|
|
2022
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2023
|
+
);
|
|
2024
|
+
});
|
|
2025
|
+
|
|
2026
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
2027
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2028
|
+
newLocus.self.state = 'LEFT';
|
|
2029
|
+
newLocus.self.reason = 'MOVED';
|
|
2030
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2031
|
+
state: 'LEFT',
|
|
2032
|
+
reason: 'MOVED',
|
|
2033
|
+
});
|
|
2034
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2035
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2036
|
+
assert.equal(result, false);
|
|
2037
|
+
assert.calledWith(
|
|
2038
|
+
LoggerProxy.logger.log,
|
|
2039
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2040
|
+
);
|
|
2041
|
+
});
|
|
2042
|
+
|
|
2043
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
2044
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2045
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
2046
|
+
newLocus.self.state = 'JOINED';
|
|
2047
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2048
|
+
state: 'LEFT',
|
|
2049
|
+
reason: 'MOVED',
|
|
2050
|
+
});
|
|
2051
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2052
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2053
|
+
assert.equal(result, false);
|
|
2054
|
+
assert.calledWith(
|
|
2055
|
+
LoggerProxy.logger.log,
|
|
2056
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
2057
|
+
);
|
|
2058
|
+
});
|
|
2059
|
+
});
|
|
2060
|
+
|
|
2061
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
2062
|
+
let meeting;
|
|
2063
|
+
let newLocus;
|
|
2064
|
+
beforeEach(() => {
|
|
2065
|
+
meeting = {
|
|
2066
|
+
controls: {},
|
|
2067
|
+
self: {},
|
|
2068
|
+
};
|
|
2069
|
+
newLocus = {
|
|
2070
|
+
controls: {},
|
|
2071
|
+
self: {},
|
|
2072
|
+
};
|
|
2073
|
+
});
|
|
2074
|
+
afterEach(() => {
|
|
2075
|
+
sinon.restore();
|
|
2076
|
+
});
|
|
2077
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
2078
|
+
newLocus.controls.breakout = {
|
|
2079
|
+
sessionType: 'BREAKOUT',
|
|
2080
|
+
};
|
|
2081
|
+
newLocus.self.state = 'JOINED';
|
|
2082
|
+
newLocus.fullState = {
|
|
2083
|
+
active: true,
|
|
2084
|
+
};
|
|
2085
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2086
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
2087
|
+
assert.equal(result, true);
|
|
2088
|
+
assert.calledWith(
|
|
2089
|
+
LoggerProxy.logger.log,
|
|
2090
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
2091
|
+
);
|
|
2092
|
+
});
|
|
2093
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
2094
|
+
newLocus.controls.breakout = {
|
|
2095
|
+
sessionType: 'MAIN',
|
|
2096
|
+
};
|
|
2097
|
+
newLocus.self.state = 'JOINED';
|
|
2098
|
+
|
|
2099
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2100
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2101
|
+
assert.equal(result, true);
|
|
2102
|
+
assert.calledWith(
|
|
2103
|
+
LoggerProxy.logger.log,
|
|
2104
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
2105
|
+
);
|
|
2106
|
+
});
|
|
2107
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
2108
|
+
newLocus.controls.breakout = {
|
|
2109
|
+
sessionType: 'BREAKOUT',
|
|
2110
|
+
};
|
|
2111
|
+
newLocus.self.state = 'LEFT';
|
|
2112
|
+
newLocus.self.reason = 'MOVED';
|
|
2113
|
+
|
|
2114
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2115
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2116
|
+
assert.equal(result, false);
|
|
2117
|
+
});
|
|
2118
|
+
});
|
|
2119
|
+
|
|
2120
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
2121
|
+
let locus;
|
|
2122
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
2123
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
2124
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
2125
|
+
if (key === keyWillReturnMeeting) {
|
|
2126
|
+
return mockReturnMeeting;
|
|
2127
|
+
}
|
|
2128
|
+
return null;
|
|
2129
|
+
});
|
|
2130
|
+
};
|
|
2131
|
+
|
|
2132
|
+
beforeEach(() => {
|
|
2133
|
+
locus = {
|
|
2134
|
+
controls: {},
|
|
2135
|
+
self: {
|
|
2136
|
+
callbackInfo: {
|
|
2137
|
+
callbackAddress: 'address1',
|
|
2138
|
+
},
|
|
2139
|
+
},
|
|
2140
|
+
info: {
|
|
2141
|
+
webExMeetingId: '123456',
|
|
2142
|
+
isUnifiedSpaceMeeting: false,
|
|
2143
|
+
},
|
|
2144
|
+
conversationUrl: 'conversationUrl1',
|
|
2145
|
+
};
|
|
2146
|
+
|
|
2147
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
2148
|
+
});
|
|
2149
|
+
afterEach(() => {
|
|
2150
|
+
sinon.restore();
|
|
2151
|
+
});
|
|
2152
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
2153
|
+
mockGetByKey();
|
|
2154
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2155
|
+
assert.isNull(result);
|
|
2156
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2157
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2158
|
+
assert.calledWith(
|
|
2159
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2160
|
+
'correlationId',
|
|
2161
|
+
'correlationId1'
|
|
2162
|
+
);
|
|
2163
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2164
|
+
assert.calledWith(
|
|
2165
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2166
|
+
'conversationUrl',
|
|
2167
|
+
'conversationUrl1'
|
|
2168
|
+
);
|
|
2169
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2170
|
+
});
|
|
2171
|
+
|
|
2172
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
2173
|
+
mockGetByKey();
|
|
2174
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
2175
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2176
|
+
assert.isNull(result);
|
|
2177
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2178
|
+
});
|
|
2179
|
+
|
|
2180
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
2181
|
+
mockGetByKey('locusUrl');
|
|
2182
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2183
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2184
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
2185
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2186
|
+
});
|
|
2187
|
+
|
|
2188
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
2189
|
+
mockGetByKey('correlationId');
|
|
2190
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2191
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2192
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
2193
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2194
|
+
assert.calledWith(
|
|
2195
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2196
|
+
'correlationId',
|
|
2197
|
+
'correlationId1'
|
|
2198
|
+
);
|
|
2199
|
+
});
|
|
2200
|
+
|
|
2201
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
2202
|
+
mockGetByKey('sipUri');
|
|
2203
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2204
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2205
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
2206
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2207
|
+
assert.calledWith(
|
|
2208
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2209
|
+
'correlationId',
|
|
2210
|
+
'correlationId1'
|
|
2211
|
+
);
|
|
2212
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2213
|
+
});
|
|
2214
|
+
|
|
2215
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
2216
|
+
mockGetByKey('conversationUrl');
|
|
2217
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2218
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2219
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2220
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2221
|
+
assert.calledWith(
|
|
2222
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2223
|
+
'correlationId',
|
|
2224
|
+
'correlationId1'
|
|
2225
|
+
);
|
|
2226
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2227
|
+
assert.calledWith(
|
|
2228
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2229
|
+
'conversationUrl',
|
|
2230
|
+
'conversationUrl1'
|
|
2231
|
+
);
|
|
2232
|
+
});
|
|
2233
|
+
|
|
2234
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
2235
|
+
mockGetByKey('meetingNumber');
|
|
2236
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2237
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2238
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2239
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2240
|
+
assert.calledWith(
|
|
2241
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2242
|
+
'correlationId',
|
|
2243
|
+
'correlationId1'
|
|
2244
|
+
);
|
|
2245
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2246
|
+
assert.calledWith(
|
|
2247
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2248
|
+
'conversationUrl',
|
|
2249
|
+
'conversationUrl1'
|
|
2250
|
+
);
|
|
2251
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2252
|
+
});
|
|
2253
|
+
});
|
|
2254
|
+
|
|
2255
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
2256
|
+
let lociArray;
|
|
2257
|
+
let mainLocus;
|
|
2258
|
+
let breakoutLocus;
|
|
2259
|
+
beforeEach(() => {
|
|
2260
|
+
mainLocus = {
|
|
2261
|
+
url: 'mainUrl1',
|
|
2262
|
+
controls: {
|
|
2263
|
+
breakout: {
|
|
2264
|
+
sessionType: 'MAIN',
|
|
2265
|
+
url: 'breakoutUnifiedUrl1',
|
|
2266
|
+
},
|
|
2267
|
+
},
|
|
2268
|
+
};
|
|
2269
|
+
breakoutLocus = {
|
|
2270
|
+
url: 'breakoutUrl1',
|
|
2271
|
+
controls: {
|
|
2272
|
+
breakout: {
|
|
2273
|
+
sessionType: 'BREAKOUT',
|
|
2274
|
+
url: 'breakoutUnifiedUrl1',
|
|
2275
|
+
},
|
|
2276
|
+
},
|
|
2277
|
+
};
|
|
2278
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2279
|
+
|
|
2280
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2281
|
+
return locus.url === 'breakoutUrl1';
|
|
2282
|
+
});
|
|
2283
|
+
});
|
|
2284
|
+
afterEach(() => {
|
|
2285
|
+
sinon.restore();
|
|
2286
|
+
});
|
|
2287
|
+
|
|
2288
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2289
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2290
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2291
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2292
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2293
|
+
});
|
|
2294
|
+
|
|
2295
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2296
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2297
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2298
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2299
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2300
|
+
});
|
|
2301
|
+
|
|
2302
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2303
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2304
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2305
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2306
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2307
|
+
});
|
|
2308
|
+
});
|
|
2309
|
+
|
|
2310
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2311
|
+
let breakoutLocus;
|
|
2312
|
+
beforeEach(() => {
|
|
2313
|
+
breakoutLocus = {
|
|
2314
|
+
url: 'breakoutUrl1',
|
|
2315
|
+
controls: {
|
|
2316
|
+
breakout: {
|
|
2317
|
+
sessionType: 'BREAKOUT',
|
|
2318
|
+
url: 'breakoutUnifiedUrl1',
|
|
2319
|
+
},
|
|
2320
|
+
},
|
|
2321
|
+
};
|
|
2322
|
+
|
|
2323
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2324
|
+
});
|
|
2325
|
+
afterEach(() => {
|
|
2326
|
+
sinon.restore();
|
|
2327
|
+
});
|
|
2328
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2329
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2330
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2331
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2332
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2333
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2334
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2335
|
+
});
|
|
2336
|
+
|
|
2337
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2338
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2339
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2340
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2341
|
+
});
|
|
2342
|
+
|
|
2343
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2344
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2345
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2346
|
+
controls: {
|
|
2347
|
+
breakout: {
|
|
2348
|
+
sessionType: 'MAIN',
|
|
2349
|
+
url: 'breakoutUnifiedUrl2',
|
|
2350
|
+
},
|
|
2351
|
+
},
|
|
2352
|
+
});
|
|
2353
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2354
|
+
});
|
|
2355
|
+
|
|
2356
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2357
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2358
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2359
|
+
controls: {
|
|
2360
|
+
breakout: {
|
|
2361
|
+
sessionType: 'MAIN',
|
|
2362
|
+
url: 'breakoutUnifiedUrl1',
|
|
2363
|
+
},
|
|
2364
|
+
},
|
|
2365
|
+
});
|
|
2366
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {
|
|
2367
|
+
locus: breakoutLocus,
|
|
2368
|
+
locusUrl: breakoutLocus.url,
|
|
2369
|
+
});
|
|
2370
|
+
});
|
|
2371
|
+
});
|
|
2372
|
+
|
|
2373
|
+
describe('uploading of logs', () => {
|
|
2374
|
+
let metricsSpy;
|
|
2375
|
+
let meeting;
|
|
2376
|
+
|
|
2377
|
+
beforeEach(async () => {
|
|
2378
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2379
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2380
|
+
|
|
2381
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2382
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2383
|
+
|
|
2384
|
+
triggerProxyStub.restore();
|
|
2385
|
+
|
|
2386
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2387
|
+
|
|
2388
|
+
meeting = await webex.meetings.create('test');
|
|
2389
|
+
|
|
2390
|
+
meeting.locusId = 'locus id';
|
|
2391
|
+
meeting.correlationId = 'correlation id';
|
|
2392
|
+
meeting.locusInfo = {
|
|
2393
|
+
fullState: {lastActive: 'last active', sessionId: 'locus session id'},
|
|
2394
|
+
info: {webExMeetingId: 'meeting id'},
|
|
2395
|
+
};
|
|
2396
|
+
});
|
|
2397
|
+
|
|
2398
|
+
afterEach(() => {
|
|
2399
|
+
sinon.restore();
|
|
2400
|
+
});
|
|
2401
|
+
|
|
2402
|
+
it('sends metrics on success', async () => {
|
|
2403
|
+
await meeting.uploadLogs();
|
|
2404
|
+
|
|
2405
|
+
await testUtils.flushPromises();
|
|
2406
|
+
|
|
2407
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2408
|
+
callStart: 'last active',
|
|
2409
|
+
correlationId: 'correlation id',
|
|
2410
|
+
feedbackId: 'correlation id',
|
|
2411
|
+
locusId: 'locus id',
|
|
2412
|
+
meetingId: 'meeting id',
|
|
2413
|
+
autoupload: true,
|
|
2414
|
+
locussessionid: 'locus session id',
|
|
2415
|
+
});
|
|
2416
|
+
});
|
|
2417
|
+
|
|
2418
|
+
it('sends metrics on failure', async () => {
|
|
2419
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2420
|
+
|
|
2421
|
+
await meeting.uploadLogs();
|
|
2422
|
+
|
|
2423
|
+
await testUtils.flushPromises();
|
|
2424
|
+
|
|
2425
|
+
assert.calledOnceWithExactly(
|
|
2426
|
+
metricsSpy,
|
|
2427
|
+
'js_sdk_upload_logs_failure',
|
|
2428
|
+
sinon.match({
|
|
2429
|
+
callStart: 'last active',
|
|
2430
|
+
correlationId: 'correlation id',
|
|
2431
|
+
feedbackId: 'correlation id',
|
|
2432
|
+
locusId: 'locus id',
|
|
2433
|
+
meetingId: 'meeting id',
|
|
2434
|
+
reason: 'fake error',
|
|
2435
|
+
autoupload: true,
|
|
2436
|
+
locussessionid: 'locus session id',
|
|
2437
|
+
})
|
|
2438
|
+
);
|
|
2439
|
+
});
|
|
2440
|
+
});
|
|
1374
2441
|
});
|
|
1375
2442
|
});
|