@webex/plugin-meetings 3.0.0-beta.4 → 3.0.0-beta.400
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 +58 -8
- package/UPGRADING.md +9 -9
- package/browsers.js +19 -24
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +216 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.js +23 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/edit-lock-error.js +52 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +1048 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/breakouts/request.js +78 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.js +67 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/browser-detection.js +1 -20
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +5 -20
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +0 -7
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +10 -24
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +11 -24
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +12 -25
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +10 -24
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/parameter.js +5 -33
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +10 -24
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +9 -23
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/reconnection-in-progress.js +0 -17
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +10 -24
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +10 -24
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js +54 -48
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +5 -25
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +0 -22
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +0 -23
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +0 -12
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +0 -15
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +0 -4
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -8
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +41 -60
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +28 -23
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +11 -15
- package/dist/config.js.map +1 -1
- package/dist/constants.js +347 -74
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +14 -0
- package/dist/controls-options-manager/constants.js.map +1 -0
- package/dist/controls-options-manager/enums.js +27 -0
- package/dist/controls-options-manager/enums.js.map +1 -0
- package/dist/controls-options-manager/index.js +297 -0
- package/dist/controls-options-manager/index.js.map +1 -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.js +319 -0
- package/dist/controls-options-manager/util.js.map +1 -0
- package/dist/index.js +125 -18
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +380 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +101 -29
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -26
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +0 -15
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +4 -12
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +564 -246
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +10 -38
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +82 -38
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +314 -163
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +110 -92
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +107 -231
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +137 -222
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +2 -9
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +316 -501
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +97 -14
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +5311 -3871
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +260 -183
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +421 -347
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js +7 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +21 -31
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.js +672 -585
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +172 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/collection.js +6 -25
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +87 -39
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +352 -283
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +3 -15
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +99 -183
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +147 -234
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +43 -19
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +895 -600
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +26 -41
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +184 -157
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +134 -85
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +158 -88
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +13 -12
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +194 -204
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +113 -68
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +324 -259
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +19 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +11 -558
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +263 -50
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +58 -65
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +76 -95
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +62 -76
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +82 -45
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +657 -448
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +255 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/networkQualityMonitor/index.js +40 -59
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +21 -45
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +1 -31
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +0 -13
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +297 -460
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +20 -26
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reactions/constants.js +13 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.js +109 -0
- package/dist/reactions/reactions.js.map +1 -0
- package/dist/reactions/reactions.type.js +36 -0
- package/dist/reactions/reactions.type.js.map +1 -0
- package/dist/reconnection-manager/index.js +413 -483
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +17 -0
- package/dist/recording-controller/enums.js.map +1 -0
- package/dist/recording-controller/index.js +362 -0
- package/dist/recording-controller/index.js.map +1 -0
- package/dist/recording-controller/util.js +64 -0
- package/dist/recording-controller/util.js.map +1 -0
- package/dist/roap/index.js +102 -86
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +131 -135
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +437 -116
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +179 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.js +1 -95
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +557 -583
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +326 -130
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +22 -47
- package/dist/transcription/index.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/breakout.d.ts +8 -0
- package/dist/types/breakouts/collection.d.ts +5 -0
- package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/index.d.ts +5 -0
- package/dist/types/breakouts/request.d.ts +22 -0
- package/dist/types/breakouts/utils.d.ts +15 -0
- package/dist/types/common/browser-detection.d.ts +9 -0
- package/dist/types/common/collection.d.ts +48 -0
- package/dist/types/common/config.d.ts +2 -0
- package/dist/types/common/errors/captcha-error.d.ts +15 -0
- package/dist/types/common/errors/intent-to-join.d.ts +16 -0
- package/dist/types/common/errors/join-meeting.d.ts +17 -0
- package/dist/types/common/errors/media.d.ts +15 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/parameter.d.ts +15 -0
- package/dist/types/common/errors/password-error.d.ts +15 -0
- package/dist/types/common/errors/permission.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
- package/dist/types/common/errors/reconnection.d.ts +15 -0
- package/dist/types/common/errors/stats.d.ts +15 -0
- package/dist/types/common/errors/webex-errors.d.ts +93 -0
- package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
- package/dist/types/common/events/events-scope.d.ts +17 -0
- package/dist/types/common/events/events.d.ts +12 -0
- package/dist/types/common/events/trigger-proxy.d.ts +2 -0
- package/dist/types/common/events/util.d.ts +2 -0
- package/dist/types/common/logs/logger-config.d.ts +2 -0
- package/dist/types/common/logs/logger-proxy.d.ts +2 -0
- package/dist/types/common/logs/request.d.ts +36 -0
- package/dist/types/common/queue.d.ts +34 -0
- package/dist/types/config.d.ts +72 -0
- package/dist/types/constants.d.ts +1088 -0
- package/dist/types/controls-options-manager/constants.d.ts +4 -0
- package/dist/types/controls-options-manager/enums.d.ts +15 -0
- package/dist/types/controls-options-manager/index.d.ts +136 -0
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/controlsUtils.d.ts +2 -0
- package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
- package/dist/types/locus-info/fullState.d.ts +2 -0
- package/dist/types/locus-info/hostUtils.d.ts +2 -0
- package/dist/types/locus-info/index.d.ts +322 -0
- package/dist/types/locus-info/infoUtils.d.ts +2 -0
- package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
- package/dist/types/locus-info/parser.d.ts +272 -0
- package/dist/types/locus-info/selfUtils.d.ts +2 -0
- package/dist/types/media/index.d.ts +34 -0
- package/dist/types/media/properties.d.ts +93 -0
- package/dist/types/media/util.d.ts +2 -0
- package/dist/types/mediaQualityMetrics/config.d.ts +241 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +167 -0
- package/dist/types/meeting/index.d.ts +1824 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +178 -0
- package/dist/types/meeting/request.d.ts +293 -0
- package/dist/types/meeting/request.type.d.ts +11 -0
- package/dist/types/meeting/state.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +118 -0
- package/dist/types/meeting/voicea-meeting.d.ts +16 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +69 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +123 -0
- package/dist/types/meeting-info/request.d.ts +22 -0
- package/dist/types/meeting-info/util.d.ts +2 -0
- package/dist/types/meeting-info/utilv2.d.ts +2 -0
- package/dist/types/meetings/collection.d.ts +40 -0
- package/dist/types/meetings/index.d.ts +389 -0
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/meetings/request.d.ts +27 -0
- package/dist/types/meetings/util.d.ts +18 -0
- package/dist/types/member/index.d.ts +160 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/member/util.d.ts +2 -0
- package/dist/types/members/collection.d.ts +29 -0
- package/dist/types/members/index.d.ts +353 -0
- package/dist/types/members/request.d.ts +114 -0
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +215 -0
- package/dist/types/metrics/constants.d.ts +70 -0
- package/dist/types/metrics/index.d.ts +45 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +120 -0
- package/dist/types/multistream/receiveSlot.d.ts +68 -0
- package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/types/multistream/remoteMedia.d.ts +72 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +49 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +301 -0
- package/dist/types/multistream/sendSlotManager.d.ts +70 -0
- package/dist/types/networkQualityMonitor/index.d.ts +70 -0
- package/dist/types/personal-meeting-room/index.d.ts +47 -0
- package/dist/types/personal-meeting-room/request.d.ts +14 -0
- package/dist/types/personal-meeting-room/util.d.ts +2 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +105 -0
- package/dist/types/reachability/request.d.ts +39 -0
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reactions/constants.d.ts +3 -0
- package/dist/types/reactions/reactions.d.ts +4 -0
- package/dist/types/reactions/reactions.type.d.ts +52 -0
- package/dist/types/reconnection-manager/index.d.ts +136 -0
- package/dist/types/recording-controller/enums.d.ts +7 -0
- package/dist/types/recording-controller/index.d.ts +207 -0
- package/dist/types/recording-controller/util.d.ts +14 -0
- package/dist/types/roap/index.d.ts +86 -0
- package/dist/types/roap/request.d.ts +39 -0
- package/dist/types/roap/turnDiscovery.d.ts +155 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +61 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +217 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +48 -0
- package/dist/types/transcription/index.d.ts +64 -0
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/internal-README.md +7 -6
- package/package.json +30 -21
- 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/{browser-detection.js → browser-detection.ts} +9 -6
- package/src/common/collection.ts +9 -7
- package/src/common/{config.js → config.ts} +1 -1
- package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
- package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
- package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
- package/src/common/errors/{media.js → media.ts} +11 -7
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/parameter.ts +11 -7
- package/src/common/errors/{password-error.js → password-error.ts} +11 -7
- package/src/common/errors/{permission.js → permission.ts} +10 -6
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
- package/src/common/errors/{stats.js → stats.ts} +11 -7
- package/src/common/errors/{webex-errors.js → webex-errors.ts} +51 -8
- package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
- package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
- package/src/common/events/{events.js → events.ts} +5 -1
- package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
- package/src/common/events/{util.js → util.ts} +2 -3
- package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
- package/src/common/logs/logger-proxy.ts +44 -0
- package/src/common/logs/{request.js → request.ts} +26 -9
- package/src/common/queue.ts +22 -9
- package/src/{config.js → config.ts} +19 -21
- package/src/constants.ts +296 -27
- package/src/controls-options-manager/constants.ts +5 -0
- package/src/controls-options-manager/enums.ts +18 -0
- package/src/controls-options-manager/index.ts +278 -0
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +300 -0
- package/src/index.ts +45 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +349 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +222 -0
- package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
- package/src/locus-info/{fullState.js → fullState.ts} +16 -12
- package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
- package/src/locus-info/{index.js → index.ts} +561 -119
- package/src/locus-info/{infoUtils.js → infoUtils.ts} +29 -10
- package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +97 -17
- package/src/locus-info/{parser.js → parser.ts} +303 -104
- package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
- package/src/media/index.ts +460 -0
- package/src/media/properties.ts +283 -0
- package/src/media/{util.js → util.ts} +2 -2
- package/src/mediaQualityMetrics/config.ts +249 -0
- package/src/meeting/in-meeting-actions.ts +199 -3
- package/src/meeting/index.ts +8494 -0
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +465 -0
- package/src/meeting/request.ts +912 -0
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/{state.js → state.ts} +50 -35
- package/src/meeting/util.ts +799 -0
- package/src/meeting/voicea-meeting.ts +122 -0
- package/src/meeting-info/{collection.js → collection.ts} +6 -2
- package/src/meeting-info/index.ts +210 -0
- package/src/meeting-info/meeting-info-v2.ts +423 -0
- package/src/meeting-info/{request.js → request.ts} +14 -4
- package/src/meeting-info/{util.js → util.ts} +70 -58
- package/src/meeting-info/{utilv2.js → utilv2.ts} +99 -82
- package/src/meetings/collection.ts +76 -0
- package/src/meetings/index.ts +1539 -0
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/{request.js → request.ts} +34 -25
- package/src/meetings/{util.js → util.ts} +133 -38
- package/src/member/{index.js → index.ts} +159 -56
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +397 -0
- package/src/members/{collection.js → collection.ts} +10 -2
- package/src/members/{index.js → index.ts} +351 -146
- package/src/members/request.ts +255 -0
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +353 -0
- package/src/metrics/{constants.js → constants.ts} +17 -6
- package/src/metrics/index.ts +73 -0
- package/src/multistream/mediaRequestManager.ts +341 -64
- package/src/multistream/receiveSlot.ts +69 -26
- package/src/multistream/receiveSlotManager.ts +66 -42
- package/src/multistream/remoteMedia.ts +40 -5
- package/src/multistream/remoteMediaGroup.ts +82 -3
- package/src/multistream/remoteMediaManager.ts +401 -81
- package/src/multistream/sendSlotManager.ts +199 -0
- package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
- package/src/personal-meeting-room/{index.js → index.ts} +28 -19
- package/src/personal-meeting-room/{request.js → request.ts} +13 -4
- package/src/personal-meeting-room/{util.js → util.ts} +4 -4
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +371 -0
- package/src/reachability/request.ts +50 -35
- package/src/reachability/util.ts +24 -0
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.ts +104 -0
- package/src/reactions/reactions.type.ts +62 -0
- package/src/reconnection-manager/index.ts +643 -0
- package/src/recording-controller/enums.ts +8 -0
- package/src/recording-controller/index.ts +332 -0
- package/src/recording-controller/util.ts +75 -0
- package/src/roap/index.ts +288 -0
- package/src/roap/request.ts +153 -0
- package/src/roap/turnDiscovery.ts +374 -70
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +166 -0
- package/src/statsAnalyzer/global.ts +37 -0
- package/src/statsAnalyzer/index.ts +1275 -0
- package/src/statsAnalyzer/mqaUtil.ts +440 -0
- package/src/transcription/{index.js → index.ts} +46 -39
- 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 +791 -531
- package/test/integration/spec/space-meeting.js +391 -204
- package/test/integration/spec/transcription.js +7 -8
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +238 -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 +1793 -0
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/browser-detection.js +9 -28
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +287 -0
- package/test/unit/spec/controls-options-manager/util.js +582 -0
- package/test/unit/spec/fixture/locus.js +93 -90
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +625 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +325 -32
- package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
- package/test/unit/spec/locus-info/index.js +1458 -21
- package/test/unit/spec/locus-info/infoUtils.js +71 -40
- package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
- package/test/unit/spec/locus-info/lib/SeqCmp.json +529 -685
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
- package/test/unit/spec/locus-info/parser.js +119 -44
- package/test/unit/spec/locus-info/selfConstant.js +120 -103
- package/test/unit/spec/locus-info/selfUtils.js +291 -12
- package/test/unit/spec/media/index.ts +194 -111
- package/test/unit/spec/media/properties.ts +11 -11
- package/test/unit/spec/meeting/in-meeting-actions.ts +96 -3
- package/test/unit/spec/meeting/index.js +8616 -1921
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +568 -207
- package/test/unit/spec/meeting/request.js +602 -82
- package/test/unit/spec/meeting/utils.js +867 -179
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +631 -78
- package/test/unit/spec/meeting-info/request.js +7 -9
- package/test/unit/spec/meeting-info/util.js +11 -12
- package/test/unit/spec/meeting-info/utilv2.js +131 -74
- package/test/unit/spec/meetings/collection.js +27 -1
- package/test/unit/spec/meetings/index.js +1826 -374
- package/test/unit/spec/meetings/utils.js +243 -14
- package/test/unit/spec/member/index.js +61 -7
- package/test/unit/spec/member/util.js +526 -26
- package/test/unit/spec/members/index.js +536 -55
- package/test/unit/spec/members/request.js +228 -40
- package/test/unit/spec/members/utils.js +217 -4
- package/test/unit/spec/metrics/index.js +13 -68
- package/test/unit/spec/multistream/mediaRequestManager.ts +1032 -110
- package/test/unit/spec/multistream/receiveSlot.ts +77 -18
- package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
- package/test/unit/spec/multistream/remoteMedia.ts +40 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +350 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +937 -65
- package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
- package/test/unit/spec/networkQualityMonitor/index.js +24 -18
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +606 -26
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +222 -34
- package/test/unit/spec/recording-controller/index.js +306 -0
- package/test/unit/spec/recording-controller/util.js +229 -0
- package/test/unit/spec/roap/index.ts +238 -82
- package/test/unit/spec/roap/request.ts +255 -0
- package/test/unit/spec/roap/turnDiscovery.ts +707 -110
- package/test/unit/spec/rtcMetrics/index.ts +122 -0
- package/test/unit/spec/stats-analyzer/index.js +1331 -62
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/cmr.js +44 -42
- package/test/utils/constants.js +9 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +63 -99
- package/test/utils/webex-config.js +22 -18
- package/test/utils/webex-test-users.js +65 -50
- package/tsconfig.json +6 -0
- package/dist/media/internal-media-core-wrapper.js +0 -22
- package/dist/media/internal-media-core-wrapper.js.map +0 -1
- package/dist/meeting/effectsState.js +0 -327
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.js +0 -301
- package/dist/metrics/config.js.map +0 -1
- package/dist/multistream/multistreamMedia.js +0 -116
- package/dist/multistream/multistreamMedia.js.map +0 -1
- package/dist/peer-connection-manager/util.js +0 -124
- package/dist/peer-connection-manager/util.js.map +0 -1
- package/src/common/logs/logger-proxy.js +0 -33
- package/src/index.js +0 -15
- package/src/locus-info/controlsUtils.js +0 -102
- package/src/media/index.js +0 -459
- package/src/media/internal-media-core-wrapper.ts +0 -9
- package/src/media/properties.js +0 -289
- package/src/mediaQualityMetrics/config.js +0 -382
- package/src/meeting/effectsState.js +0 -205
- package/src/meeting/index.js +0 -6284
- package/src/meeting/muteState.js +0 -318
- package/src/meeting/request.js +0 -684
- package/src/meeting/util.js +0 -506
- package/src/meeting-info/index.js +0 -131
- package/src/meeting-info/meeting-info-v2.js +0 -255
- package/src/meetings/collection.js +0 -40
- package/src/meetings/index.js +0 -1015
- package/src/member/util.js +0 -254
- package/src/members/request.js +0 -131
- package/src/members/util.js +0 -258
- package/src/metrics/config.js +0 -324
- package/src/metrics/index.js +0 -530
- package/src/multistream/multistreamMedia.ts +0 -92
- package/src/peer-connection-manager/util.ts +0 -117
- package/src/reachability/index.js +0 -464
- package/src/reconnection-manager/index.js +0 -519
- package/src/roap/index.js +0 -220
- package/src/roap/request.js +0 -127
- package/src/statsAnalyzer/global.js +0 -133
- package/src/statsAnalyzer/index.js +0 -1006
- package/src/statsAnalyzer/mqaUtil.js +0 -173
- package/test/unit/spec/meeting/effectsState.js +0 -291
- package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
- /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
|
@@ -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,14 +15,16 @@ 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 Meeting from '@webex/plugin-meetings/src/meeting';
|
|
20
|
+
import Meeting, {CallStateForMetrics} from '@webex/plugin-meetings/src/meeting';
|
|
16
21
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
17
22
|
import Meetings from '@webex/plugin-meetings/src/meetings';
|
|
18
23
|
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
19
24
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
20
25
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
21
26
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
27
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
22
28
|
|
|
23
29
|
import testUtils from '../../../utils/testUtils';
|
|
24
30
|
import {
|
|
@@ -27,8 +33,14 @@ import {
|
|
|
27
33
|
ONLINE,
|
|
28
34
|
ROAP,
|
|
29
35
|
LOCUSINFO,
|
|
30
|
-
EVENT_TRIGGERS
|
|
36
|
+
EVENT_TRIGGERS,
|
|
31
37
|
} from '../../../../src/constants';
|
|
38
|
+
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
|
|
39
|
+
import {forEach} from 'lodash';
|
|
40
|
+
import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
|
|
41
|
+
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
42
|
+
import {NoiseReductionEffect, VirtualBackgroundEffect} from '@webex/media-helpers';
|
|
43
|
+
import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
|
|
32
44
|
|
|
33
45
|
describe('plugin-meetings', () => {
|
|
34
46
|
const logger = {
|
|
@@ -37,19 +49,23 @@ describe('plugin-meetings', () => {
|
|
|
37
49
|
error: () => {},
|
|
38
50
|
warn: () => {},
|
|
39
51
|
trace: () => {},
|
|
40
|
-
debug: () => {}
|
|
52
|
+
debug: () => {},
|
|
41
53
|
};
|
|
42
54
|
|
|
55
|
+
let triggerProxyStub;
|
|
56
|
+
|
|
43
57
|
beforeEach(() => {
|
|
44
58
|
StaticConfig.set({
|
|
45
59
|
bandwidth: {
|
|
46
|
-
audio: 50,
|
|
47
|
-
|
|
60
|
+
audio: 50,
|
|
61
|
+
video: 500,
|
|
62
|
+
},
|
|
48
63
|
});
|
|
49
64
|
LoggerConfig.set({
|
|
50
|
-
verboseEvents: true,
|
|
65
|
+
verboseEvents: true,
|
|
66
|
+
enable: false,
|
|
51
67
|
});
|
|
52
|
-
|
|
68
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
53
69
|
});
|
|
54
70
|
|
|
55
71
|
let webex;
|
|
@@ -58,6 +74,7 @@ describe('plugin-meetings', () => {
|
|
|
58
74
|
let url1;
|
|
59
75
|
let test1;
|
|
60
76
|
let test2;
|
|
77
|
+
let locusInfo;
|
|
61
78
|
|
|
62
79
|
describe('meetings index', () => {
|
|
63
80
|
beforeEach(() => {
|
|
@@ -67,17 +84,20 @@ describe('plugin-meetings', () => {
|
|
|
67
84
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
68
85
|
test1 = `test-${uuid.v4()}`;
|
|
69
86
|
test2 = `test2-${uuid.v4()}`;
|
|
87
|
+
locusInfo = {
|
|
88
|
+
parse: sinon.stub().returns(true),
|
|
89
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
90
|
+
};
|
|
70
91
|
webex = new MockWebex({
|
|
71
92
|
children: {
|
|
72
93
|
device: Device,
|
|
73
94
|
mercury: Mercury,
|
|
74
|
-
meetings: Meetings
|
|
75
|
-
}
|
|
95
|
+
meetings: Meetings,
|
|
96
|
+
},
|
|
76
97
|
});
|
|
77
98
|
|
|
78
|
-
|
|
79
99
|
Object.assign(webex, {
|
|
80
|
-
logging: logger
|
|
100
|
+
logging: logger,
|
|
81
101
|
});
|
|
82
102
|
|
|
83
103
|
Object.assign(webex.meetings.config, {
|
|
@@ -86,68 +106,74 @@ describe('plugin-meetings', () => {
|
|
|
86
106
|
// the server supports, minimums have to be tested
|
|
87
107
|
audio: 64000,
|
|
88
108
|
video: 4000000,
|
|
89
|
-
startBitrate: 2000
|
|
109
|
+
startBitrate: 2000,
|
|
90
110
|
},
|
|
91
111
|
experimental: {
|
|
92
|
-
enableUnifiedMeetings: true
|
|
112
|
+
enableUnifiedMeetings: true,
|
|
93
113
|
},
|
|
94
114
|
logging: {
|
|
95
115
|
enable: true,
|
|
96
|
-
verboseEvents: true
|
|
97
|
-
}
|
|
116
|
+
verboseEvents: true,
|
|
117
|
+
},
|
|
98
118
|
});
|
|
99
119
|
|
|
100
120
|
Object.assign(webex, {
|
|
101
|
-
logger
|
|
121
|
+
logger,
|
|
102
122
|
});
|
|
103
123
|
|
|
104
124
|
Object.assign(webex.meetings, {
|
|
105
|
-
startReachability: sinon.stub().returns(Promise.resolve())
|
|
125
|
+
startReachability: sinon.stub().returns(Promise.resolve()),
|
|
106
126
|
});
|
|
107
127
|
|
|
108
128
|
Object.assign(webex.internal, {
|
|
129
|
+
llm: {on: sinon.stub()},
|
|
109
130
|
device: {
|
|
110
131
|
deviceType: 'FAKE_DEVICE',
|
|
111
132
|
register: sinon.stub().returns(Promise.resolve()),
|
|
112
|
-
unregister: sinon.stub().returns(Promise.resolve())
|
|
133
|
+
unregister: sinon.stub().returns(Promise.resolve()),
|
|
113
134
|
},
|
|
114
135
|
mercury: {
|
|
115
136
|
connect: sinon.stub().returns(Promise.resolve()),
|
|
116
137
|
disconnect: sinon.stub().returns(Promise.resolve()),
|
|
117
138
|
on: () => {},
|
|
118
|
-
off: () => {}
|
|
139
|
+
off: () => {},
|
|
119
140
|
},
|
|
120
141
|
services: {
|
|
121
|
-
getMeetingPreferences: sinon.stub().returns(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
getMeetingPreferences: sinon.stub().returns(
|
|
143
|
+
Promise.resolve({
|
|
144
|
+
sites: [
|
|
145
|
+
{
|
|
146
|
+
siteUrl: 'site1-example.webex.com',
|
|
147
|
+
default: false,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
siteUrl: 'site2-example.webex.com',
|
|
151
|
+
default: false,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
siteUrl: 'site3-example.webex.com',
|
|
155
|
+
default: false,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
siteUrl: 'go.webex.com',
|
|
159
|
+
default: true,
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
})
|
|
163
|
+
),
|
|
164
|
+
fetchClientRegionInfo: sinon.stub().returns(Promise.resolve()),
|
|
142
165
|
},
|
|
143
166
|
metrics: {
|
|
144
|
-
submitClientMetrics: sinon.stub().returns(Promise.resolve())
|
|
145
|
-
}
|
|
146
|
-
|
|
167
|
+
submitClientMetrics: sinon.stub().returns(Promise.resolve()),
|
|
168
|
+
},
|
|
147
169
|
});
|
|
148
170
|
webex.emit('ready');
|
|
149
171
|
});
|
|
150
172
|
|
|
173
|
+
afterEach(() => {
|
|
174
|
+
sinon.restore();
|
|
175
|
+
});
|
|
176
|
+
|
|
151
177
|
it('has a webex instance with a meetings property', () => {
|
|
152
178
|
assert.exists(webex, 'webex was initialized with children');
|
|
153
179
|
assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
|
|
@@ -177,10 +203,14 @@ describe('plugin-meetings', () => {
|
|
|
177
203
|
|
|
178
204
|
describe('failure', () => {
|
|
179
205
|
it('should not accept non boolean input', () => {
|
|
180
|
-
const currentEnableUnifiedMeetings =
|
|
206
|
+
const currentEnableUnifiedMeetings =
|
|
207
|
+
webex.meetings.config.experimental.enableUnifiedMeetings;
|
|
181
208
|
|
|
182
209
|
webex.meetings._toggleUnifiedMeetings('test');
|
|
183
|
-
assert.equal(
|
|
210
|
+
assert.equal(
|
|
211
|
+
webex.meetings.config.experimental.enableUnifiedMeetings,
|
|
212
|
+
currentEnableUnifiedMeetings
|
|
213
|
+
);
|
|
184
214
|
});
|
|
185
215
|
});
|
|
186
216
|
});
|
|
@@ -202,43 +232,38 @@ describe('plugin-meetings', () => {
|
|
|
202
232
|
const currentEnableAdhocMeetings = webex.meetings.config.experimental.enableAdhocMeetings;
|
|
203
233
|
|
|
204
234
|
webex.meetings._toggleAdhocMeetings('test');
|
|
205
|
-
assert.equal(
|
|
235
|
+
assert.equal(
|
|
236
|
+
webex.meetings.config.experimental.enableAdhocMeetings,
|
|
237
|
+
currentEnableAdhocMeetings
|
|
238
|
+
);
|
|
206
239
|
});
|
|
207
240
|
});
|
|
208
241
|
});
|
|
209
242
|
|
|
210
|
-
describe('#
|
|
211
|
-
it('should have
|
|
212
|
-
assert.equal(typeof webex.meetings.
|
|
243
|
+
describe('#_toggleTcpReachability', () => {
|
|
244
|
+
it('should have _toggleTcpReachability', () => {
|
|
245
|
+
assert.equal(typeof webex.meetings._toggleTcpReachability, 'function');
|
|
213
246
|
});
|
|
214
247
|
|
|
215
248
|
describe('success', () => {
|
|
216
|
-
it('should update meetings to do
|
|
217
|
-
webex.meetings.
|
|
218
|
-
assert.equal(webex.meetings.config.experimental.
|
|
219
|
-
|
|
220
|
-
webex.meetings._toggleTurnDiscovery(false);
|
|
221
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, false);
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
describe('failure', () => {
|
|
226
|
-
it('should not accept non boolean input', () => {
|
|
227
|
-
const currentEnableTurnDiscovery = webex.meetings.config.experimental.enableTurnDiscovery;
|
|
228
|
-
|
|
229
|
-
webex.meetings._toggleTurnDiscovery('test');
|
|
230
|
-
assert.equal(webex.meetings.config.experimental.enableAdhocMeetings, currentEnableTurnDiscovery);
|
|
249
|
+
it('should update meetings to do TCP reachability', () => {
|
|
250
|
+
webex.meetings._toggleTcpReachability(true);
|
|
251
|
+
assert.equal(webex.meetings.config.experimental.enableTcpReachability, true);
|
|
231
252
|
});
|
|
232
253
|
});
|
|
233
254
|
});
|
|
234
255
|
|
|
235
|
-
|
|
236
256
|
describe('Public API Contracts', () => {
|
|
237
257
|
describe('#register', () => {
|
|
238
258
|
it('emits an event and resolves when register succeeds', async () => {
|
|
239
259
|
webex.canAuthorize = true;
|
|
240
260
|
await webex.meetings.register();
|
|
241
|
-
assert.calledWith(
|
|
261
|
+
assert.calledWith(
|
|
262
|
+
TriggerProxy.trigger,
|
|
263
|
+
sinon.match.instanceOf(Meetings),
|
|
264
|
+
{file: 'meetings', function: 'register'},
|
|
265
|
+
'meetings:registered'
|
|
266
|
+
);
|
|
242
267
|
assert.isTrue(webex.meetings.registered);
|
|
243
268
|
});
|
|
244
269
|
|
|
@@ -284,9 +309,15 @@ describe('plugin-meetings', () => {
|
|
|
284
309
|
it('emits an event and resolves when unregister succeeds', (done) => {
|
|
285
310
|
webex.meetings.registered = true;
|
|
286
311
|
webex.meetings.unregister().then(() => {
|
|
287
|
-
assert.calledWith(
|
|
288
|
-
|
|
289
|
-
|
|
312
|
+
assert.calledWith(
|
|
313
|
+
TriggerProxy.trigger,
|
|
314
|
+
sinon.match.instanceOf(Meetings),
|
|
315
|
+
{
|
|
316
|
+
file: 'meetings',
|
|
317
|
+
function: 'unregister',
|
|
318
|
+
},
|
|
319
|
+
'meetings:unregistered'
|
|
320
|
+
);
|
|
290
321
|
assert.isFalse(webex.meetings.registered);
|
|
291
322
|
done();
|
|
292
323
|
});
|
|
@@ -315,31 +346,110 @@ describe('plugin-meetings', () => {
|
|
|
315
346
|
});
|
|
316
347
|
});
|
|
317
348
|
|
|
349
|
+
describe('virtual background effect', () => {
|
|
350
|
+
beforeEach(() => {
|
|
351
|
+
webex.credentials = {
|
|
352
|
+
supertoken: {
|
|
353
|
+
access_token: 'fake_token',
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('creates background effect', async () => {
|
|
359
|
+
const result = await webex.meetings.createVirtualBackgroundEffect();
|
|
360
|
+
|
|
361
|
+
assert.exists(result);
|
|
362
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
363
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
364
|
+
assert.deepEqual(result.options, {
|
|
365
|
+
mode: 'BLUR',
|
|
366
|
+
blurStrength: 'STRONG',
|
|
367
|
+
generator: 'worker',
|
|
368
|
+
quality: 'LOW',
|
|
369
|
+
authToken: 'fake_token',
|
|
370
|
+
mirror: false,
|
|
371
|
+
});
|
|
372
|
+
assert.exists(result.enable);
|
|
373
|
+
assert.exists(result.disable);
|
|
374
|
+
assert.exists(result.dispose);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('creates background effect with custom options passed', async () => {
|
|
378
|
+
const effectOptions = {
|
|
379
|
+
generator: 'local',
|
|
380
|
+
frameRate: 45,
|
|
381
|
+
mode: 'IMAGE',
|
|
382
|
+
mirror: false,
|
|
383
|
+
quality: 'HIGH',
|
|
384
|
+
blurStrength: 'STRONG',
|
|
385
|
+
bgImageUrl: 'https://test.webex.com/landscape.5a535788.jpg',
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const result = await webex.meetings.createVirtualBackgroundEffect(effectOptions);
|
|
389
|
+
|
|
390
|
+
assert.exists(result);
|
|
391
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
392
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
393
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
394
|
+
assert.exists(result.enable);
|
|
395
|
+
assert.exists(result.disable);
|
|
396
|
+
assert.exists(result.dispose);
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
describe('noise reduction effect', () => {
|
|
401
|
+
beforeEach(() => {
|
|
402
|
+
webex.credentials = {
|
|
403
|
+
supertoken: {
|
|
404
|
+
access_token: 'fake_token',
|
|
405
|
+
},
|
|
406
|
+
};
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('creates noise reduction effect', async () => {
|
|
410
|
+
const result = await webex.meetings.createNoiseReductionEffect({audioContext: {}});
|
|
411
|
+
|
|
412
|
+
assert.exists(result);
|
|
413
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
414
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
415
|
+
assert.deepEqual(result.options, {
|
|
416
|
+
authToken: 'fake_token',
|
|
417
|
+
audioContext: {},
|
|
418
|
+
});
|
|
419
|
+
assert.exists(result.enable);
|
|
420
|
+
assert.exists(result.disable);
|
|
421
|
+
assert.exists(result.dispose);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it('creates noise reduction effect with custom options passed', async () => {
|
|
425
|
+
const effectOptions = {
|
|
426
|
+
audioContext: {},
|
|
427
|
+
mode: 'WORKLET',
|
|
428
|
+
env: 'prod',
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const result = await webex.meetings.createNoiseReductionEffect(effectOptions);
|
|
432
|
+
|
|
433
|
+
assert.exists(result);
|
|
434
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
435
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
436
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
437
|
+
assert.exists(result.enable);
|
|
438
|
+
assert.exists(result.disable);
|
|
439
|
+
assert.exists(result.dispose);
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
|
|
318
443
|
describe('gets', () => {
|
|
319
444
|
describe('#getReachability', () => {
|
|
320
445
|
it('should have #getReachability', () => {
|
|
321
446
|
assert.exists(webex.meetings.getReachability);
|
|
322
447
|
});
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const reachability = webex.meetings.getReachability();
|
|
326
|
-
|
|
327
|
-
assert.notExists(reachability, 'reachability is undefined because #setReachability has not been called');
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
describe('after #setReachability', () => {
|
|
331
|
-
beforeEach(() => {
|
|
332
|
-
webex.meetings.setReachability();
|
|
333
|
-
const reachabilityMocker = webex.meetings.getReachability();
|
|
334
|
-
|
|
335
|
-
sinon.stub(reachabilityMocker, 'gatherReachability').returns(true);
|
|
336
|
-
});
|
|
337
|
-
it('gets the reachability data instance from webex.meetings', () => {
|
|
338
|
-
const reachability = webex.meetings.getReachability();
|
|
448
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
449
|
+
const reachability = webex.meetings.getReachability();
|
|
339
450
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
});
|
|
451
|
+
assert.exists(reachability, 'reachability is defined');
|
|
452
|
+
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
343
453
|
});
|
|
344
454
|
});
|
|
345
455
|
describe('#getPersonalMeetingRoom', () => {
|
|
@@ -349,8 +459,15 @@ describe('plugin-meetings', () => {
|
|
|
349
459
|
it('gets the personal meeting room instance from webex.meetings', () => {
|
|
350
460
|
const personalMeetingRoom = webex.meetings.getPersonalMeetingRoom();
|
|
351
461
|
|
|
352
|
-
assert.exists(
|
|
353
|
-
|
|
462
|
+
assert.exists(
|
|
463
|
+
personalMeetingRoom,
|
|
464
|
+
'personal meeting room instance is set up at object creation'
|
|
465
|
+
);
|
|
466
|
+
assert.instanceOf(
|
|
467
|
+
personalMeetingRoom,
|
|
468
|
+
PersonalMeetingRoom,
|
|
469
|
+
'should be a personal meeting room instance'
|
|
470
|
+
);
|
|
354
471
|
});
|
|
355
472
|
});
|
|
356
473
|
describe('Static shortcut proxy methods', () => {
|
|
@@ -379,11 +496,11 @@ describe('plugin-meetings', () => {
|
|
|
379
496
|
describe('#getAllMeetings', () => {
|
|
380
497
|
it('calls MeetingCollection to get all meetings with supplied options', () => {
|
|
381
498
|
webex.meetings.getAllMeetings({
|
|
382
|
-
test: test1
|
|
499
|
+
test: test1,
|
|
383
500
|
});
|
|
384
501
|
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
385
502
|
assert.calledWith(webex.meetings.meetingCollection.getAll, {
|
|
386
|
-
test: test1
|
|
503
|
+
test: test1,
|
|
387
504
|
});
|
|
388
505
|
});
|
|
389
506
|
});
|
|
@@ -394,30 +511,50 @@ describe('plugin-meetings', () => {
|
|
|
394
511
|
it('should have #syncMeetings', () => {
|
|
395
512
|
assert.exists(webex.meetings.syncMeetings);
|
|
396
513
|
});
|
|
514
|
+
it('should do nothing and return a resolved promise if unverified guest', async () => {
|
|
515
|
+
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
516
|
+
Promise.resolve({
|
|
517
|
+
loci: [
|
|
518
|
+
{
|
|
519
|
+
url: url1,
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
})
|
|
523
|
+
);
|
|
524
|
+
webex.credentials.isUnverifiedGuest = true;
|
|
525
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
526
|
+
|
|
527
|
+
await webex.meetings.syncMeetings();
|
|
528
|
+
|
|
529
|
+
assert.notCalled(webex.meetings.request.getActiveMeetings);
|
|
530
|
+
assert.calledWith(
|
|
531
|
+
LoggerProxy.logger.info,
|
|
532
|
+
'Meetings:index#syncMeetings --> skipping meeting sync as unverified guest'
|
|
533
|
+
);
|
|
534
|
+
});
|
|
397
535
|
describe('succesful requests', () => {
|
|
398
536
|
beforeEach(() => {
|
|
399
|
-
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
537
|
+
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
538
|
+
Promise.resolve({
|
|
539
|
+
loci: [
|
|
540
|
+
{
|
|
541
|
+
url: url1,
|
|
542
|
+
},
|
|
543
|
+
],
|
|
544
|
+
})
|
|
545
|
+
);
|
|
404
546
|
});
|
|
405
547
|
describe('when meeting is returned', () => {
|
|
406
|
-
let parse;
|
|
407
|
-
|
|
408
548
|
beforeEach(() => {
|
|
409
|
-
parse = sinon.stub().returns(true);
|
|
410
549
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
411
|
-
locusInfo
|
|
412
|
-
parse
|
|
413
|
-
}
|
|
550
|
+
locusInfo,
|
|
414
551
|
});
|
|
415
552
|
});
|
|
416
553
|
it('tests the sync meeting calls for existing meeting', async () => {
|
|
417
554
|
await webex.meetings.syncMeetings();
|
|
418
555
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
419
556
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
420
|
-
assert.calledOnce(parse);
|
|
557
|
+
assert.calledOnce(locusInfo.parse);
|
|
421
558
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
422
559
|
});
|
|
423
560
|
});
|
|
@@ -427,63 +564,105 @@ describe('plugin-meetings', () => {
|
|
|
427
564
|
beforeEach(() => {
|
|
428
565
|
initialSetup = sinon.stub().returns(true);
|
|
429
566
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(null);
|
|
430
|
-
webex.meetings.create = sinon.stub().returns(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
567
|
+
webex.meetings.create = sinon.stub().returns(
|
|
568
|
+
Promise.resolve({
|
|
569
|
+
locusInfo: {
|
|
570
|
+
...locusInfo,
|
|
571
|
+
initialSetup,
|
|
572
|
+
},
|
|
573
|
+
})
|
|
574
|
+
);
|
|
435
575
|
});
|
|
436
576
|
it('tests the sync meeting calls for not existing meeting', async () => {
|
|
437
577
|
await webex.meetings.syncMeetings();
|
|
438
578
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
439
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
579
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
440
580
|
assert.calledOnce(initialSetup);
|
|
441
581
|
assert.calledOnce(webex.meetings.create);
|
|
442
582
|
assert.calledWith(webex.meetings.request.getActiveMeetings);
|
|
443
583
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
444
|
-
assert.calledWith(
|
|
445
|
-
|
|
446
|
-
|
|
584
|
+
assert.calledWith(
|
|
585
|
+
webex.meetings.create,
|
|
586
|
+
{
|
|
587
|
+
url: url1,
|
|
588
|
+
},
|
|
589
|
+
'LOCUS_ID'
|
|
590
|
+
);
|
|
447
591
|
assert.calledWith(initialSetup, {
|
|
448
|
-
url: url1
|
|
592
|
+
url: url1,
|
|
449
593
|
});
|
|
450
594
|
});
|
|
451
595
|
});
|
|
452
|
-
describe('
|
|
453
|
-
let initialSetup;
|
|
454
|
-
let parse;
|
|
596
|
+
describe('when destroying meeting is needed', () => {
|
|
455
597
|
let destroySpy;
|
|
598
|
+
let cleanUpSpy;
|
|
599
|
+
|
|
600
|
+
const meetingCollectionMeetings = {
|
|
601
|
+
stillValidLocusMeeting: {
|
|
602
|
+
locusUrl: 'still-valid-locus-url',
|
|
603
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
604
|
+
},
|
|
605
|
+
noLongerValidLocusMeeting: {
|
|
606
|
+
locusUrl: 'no-longer-valid-locus-url',
|
|
607
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
608
|
+
},
|
|
609
|
+
otherNonLocusMeeting1: {
|
|
610
|
+
locusUrl: null,
|
|
611
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
612
|
+
},
|
|
613
|
+
otherNonLocusMeeting2: {
|
|
614
|
+
locusUrl: undefined,
|
|
615
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
616
|
+
},
|
|
617
|
+
};
|
|
456
618
|
|
|
457
619
|
beforeEach(() => {
|
|
458
620
|
destroySpy = sinon.spy(webex.meetings, 'destroy');
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
webex.meetings.create = sinon.stub().returns(Promise.resolve({
|
|
473
|
-
locusInfo: {
|
|
474
|
-
initialSetup
|
|
475
|
-
},
|
|
476
|
-
sendCallAnalyzerMetrics: sinon.stub()
|
|
477
|
-
}));
|
|
478
|
-
webex.meetings.request.getActiveMeetings = sinon.stub().returns(Promise.resolve({
|
|
479
|
-
loci: []
|
|
480
|
-
}));
|
|
481
|
-
MeetingUtil.cleanUp = sinon.stub().returns(Promise.resolve());
|
|
621
|
+
webex.meetings.meetingCollection.getAll = sinon
|
|
622
|
+
.stub()
|
|
623
|
+
.returns(meetingCollectionMeetings);
|
|
624
|
+
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
625
|
+
Promise.resolve({
|
|
626
|
+
loci: [{url: 'still-valid-locus-url'}],
|
|
627
|
+
})
|
|
628
|
+
);
|
|
629
|
+
cleanUpSpy = sinon.stub(MeetingUtil, 'cleanUp').returns(Promise.resolve());
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
afterEach(() => {
|
|
633
|
+
cleanUpSpy.restore();
|
|
482
634
|
});
|
|
483
|
-
|
|
635
|
+
|
|
636
|
+
it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings is not defined', async () => {
|
|
484
637
|
await webex.meetings.syncMeetings();
|
|
485
638
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
486
|
-
assert.calledOnce(
|
|
639
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
640
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
641
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
|
|
642
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
|
|
643
|
+
assert.callCount(destroySpy, 3);
|
|
644
|
+
|
|
645
|
+
assert.callCount(MeetingUtil.cleanUp, 3);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings === true', async () => {
|
|
649
|
+
await webex.meetings.syncMeetings({keepOnlyLocusMeetings: true});
|
|
650
|
+
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
651
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
652
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
653
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
|
|
654
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
|
|
655
|
+
assert.callCount(destroySpy, 3);
|
|
656
|
+
|
|
657
|
+
assert.callCount(MeetingUtil.cleanUp, 3);
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
it('destroy any LOCUS meetings that have no active locus url if keepOnlyLocusMeetings === false', async () => {
|
|
661
|
+
await webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
|
|
662
|
+
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
663
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
664
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
665
|
+
assert.callCount(destroySpy, 1);
|
|
487
666
|
|
|
488
667
|
assert.calledOnce(MeetingUtil.cleanUp);
|
|
489
668
|
});
|
|
@@ -499,43 +678,163 @@ describe('plugin-meetings', () => {
|
|
|
499
678
|
beforeEach(() => {
|
|
500
679
|
infoOptions = {
|
|
501
680
|
destination: 'dest-example',
|
|
502
|
-
type: 'CONVERSATION_URL'
|
|
681
|
+
type: 'CONVERSATION_URL',
|
|
503
682
|
};
|
|
504
683
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns();
|
|
505
|
-
webex.meetings.createMeeting = sinon.stub().returns(
|
|
506
|
-
|
|
507
|
-
|
|
684
|
+
webex.meetings.createMeeting = sinon.stub().returns(
|
|
685
|
+
Promise.resolve({
|
|
686
|
+
on: () => true,
|
|
687
|
+
})
|
|
688
|
+
);
|
|
508
689
|
});
|
|
509
690
|
|
|
510
|
-
it('should call MeetingInfo#fetchInfoOptions() with proper params',
|
|
511
|
-
()
|
|
512
|
-
webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(
|
|
513
|
-
infoOptions
|
|
514
|
-
);
|
|
691
|
+
it('should call MeetingInfo#fetchInfoOptions() with proper params', () => {
|
|
692
|
+
webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(infoOptions);
|
|
515
693
|
|
|
516
|
-
|
|
694
|
+
return webex.meetings.create(infoOptions.destination, infoOptions.type).then(() => {
|
|
695
|
+
assert.calledWith(
|
|
696
|
+
webex.meetings.meetingInfo.fetchInfoOptions,
|
|
517
697
|
infoOptions.destination,
|
|
518
698
|
infoOptions.type
|
|
519
|
-
)
|
|
520
|
-
.then(() => {
|
|
521
|
-
assert.calledWith(
|
|
522
|
-
webex.meetings.meetingInfo.fetchInfoOptions,
|
|
523
|
-
infoOptions.destination,
|
|
524
|
-
infoOptions.type
|
|
525
|
-
);
|
|
699
|
+
);
|
|
526
700
|
|
|
527
|
-
|
|
528
|
-
|
|
701
|
+
assert.calledTwice(webex.meetings.meetingCollection.getByKey);
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
706
|
+
const correlationId = 'my-correlationId';
|
|
707
|
+
const callStateForMetrics = {
|
|
708
|
+
correlationId: 'my-correlationId2',
|
|
709
|
+
joinTrigger: 'my-join-trigger',
|
|
710
|
+
loginType: 'my-login-type',
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
it('should call setCallStateForMetrics on any pre-existing meeting', async () => {
|
|
714
|
+
const fakeMeeting = {setCallStateForMetrics: sinon.mock()};
|
|
715
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(fakeMeeting);
|
|
716
|
+
await webex.meetings.create(
|
|
717
|
+
test1,
|
|
718
|
+
test2,
|
|
719
|
+
FAKE_USE_RANDOM_DELAY,
|
|
720
|
+
{},
|
|
721
|
+
correlationId,
|
|
722
|
+
true,
|
|
723
|
+
callStateForMetrics
|
|
724
|
+
);
|
|
725
|
+
assert.calledOnceWithExactly(fakeMeeting.setCallStateForMetrics, {
|
|
726
|
+
...callStateForMetrics,
|
|
727
|
+
correlationId,
|
|
529
728
|
});
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
732
|
+
const create = webex.meetings.create(...createParameters);
|
|
733
|
+
|
|
734
|
+
assert.exists(create.then);
|
|
735
|
+
await create;
|
|
736
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
737
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
738
|
+
};
|
|
530
739
|
|
|
531
740
|
it('calls createMeeting and returns its promise', async () => {
|
|
532
|
-
|
|
533
|
-
|
|
741
|
+
await checkCallCreateMeeting(
|
|
742
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true],
|
|
743
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true]
|
|
744
|
+
);
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it('calls createMeeting, pass the meeting info param and returns its promise', async () => {
|
|
748
|
+
const meetingInfo = {};
|
|
749
|
+
await checkCallCreateMeeting(
|
|
750
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, undefined, meetingInfo],
|
|
751
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true, meetingInfo]
|
|
752
|
+
);
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
it('calls createMeeting, pass the meeting info and meetingLookupURL param and returns its promise', async () => {
|
|
756
|
+
const meetingInfo = {};
|
|
757
|
+
await checkCallCreateMeeting(
|
|
758
|
+
[
|
|
759
|
+
test1,
|
|
760
|
+
test2,
|
|
761
|
+
FAKE_USE_RANDOM_DELAY,
|
|
762
|
+
{},
|
|
763
|
+
correlationId,
|
|
764
|
+
true,
|
|
765
|
+
undefined,
|
|
766
|
+
meetingInfo,
|
|
767
|
+
'meetingLookupURL',
|
|
768
|
+
],
|
|
769
|
+
[
|
|
770
|
+
test1,
|
|
771
|
+
test2,
|
|
772
|
+
FAKE_USE_RANDOM_DELAY,
|
|
773
|
+
{},
|
|
774
|
+
{correlationId},
|
|
775
|
+
true,
|
|
776
|
+
meetingInfo,
|
|
777
|
+
'meetingLookupURL',
|
|
778
|
+
]
|
|
779
|
+
);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
783
|
+
await checkCallCreateMeeting(
|
|
784
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
|
|
785
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
786
|
+
);
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
790
|
+
await checkCallCreateMeeting(
|
|
791
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false],
|
|
792
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
793
|
+
);
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it('calls createMeeting with callStateForMetrics and returns its promise', async () => {
|
|
797
|
+
await checkCallCreateMeeting(
|
|
798
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, undefined, true, callStateForMetrics],
|
|
799
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, callStateForMetrics, true]
|
|
800
|
+
);
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
it('calls createMeeting with callStateForMetrics overwritten with correlationId and returns its promise', async () => {
|
|
804
|
+
await checkCallCreateMeeting(
|
|
805
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, callStateForMetrics],
|
|
806
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {...callStateForMetrics, correlationId}, true]
|
|
807
|
+
);
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
811
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
812
|
+
const correlationId = 'my-correlationId';
|
|
813
|
+
|
|
814
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
815
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
816
|
+
joinTXId: 'TSmrX61wNF',
|
|
817
|
+
};
|
|
818
|
+
const create = webex.meetings.create(
|
|
819
|
+
test1,
|
|
820
|
+
test2,
|
|
821
|
+
FAKE_USE_RANDOM_DELAY,
|
|
822
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
823
|
+
correlationId
|
|
824
|
+
);
|
|
534
825
|
|
|
535
826
|
assert.exists(create.then);
|
|
536
827
|
await create;
|
|
537
828
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
538
|
-
assert.calledWith(
|
|
829
|
+
assert.calledWith(
|
|
830
|
+
webex.meetings.createMeeting,
|
|
831
|
+
test1,
|
|
832
|
+
test2,
|
|
833
|
+
FAKE_USE_RANDOM_DELAY,
|
|
834
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
835
|
+
{correlationId},
|
|
836
|
+
false
|
|
837
|
+
);
|
|
539
838
|
});
|
|
540
839
|
|
|
541
840
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -565,9 +864,9 @@ describe('plugin-meetings', () => {
|
|
|
565
864
|
return undefined;
|
|
566
865
|
});
|
|
567
866
|
|
|
568
|
-
webex.meetings.meetingInfo.fetchInfoOptions = sinon
|
|
569
|
-
|
|
570
|
-
|
|
867
|
+
webex.meetings.meetingInfo.fetchInfoOptions = sinon
|
|
868
|
+
.stub()
|
|
869
|
+
.resolves(scheduledMeetingFixture);
|
|
571
870
|
|
|
572
871
|
webex.meetings.meetingCollection.set(scheduledMeetingFixture);
|
|
573
872
|
|
|
@@ -602,99 +901,129 @@ describe('plugin-meetings', () => {
|
|
|
602
901
|
it('doesnt call handle locus mercury for a locus roap event', () => {
|
|
603
902
|
webex.meetings.handleLocusMercury({
|
|
604
903
|
data: {
|
|
605
|
-
eventType: 'locus.message.roap'
|
|
606
|
-
}
|
|
904
|
+
eventType: 'locus.message.roap',
|
|
905
|
+
},
|
|
607
906
|
});
|
|
608
907
|
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
609
908
|
});
|
|
610
909
|
it('doesnt call handle locus mercury for an undefined eventType', () => {
|
|
611
910
|
webex.meetings.handleLocusMercury({
|
|
612
|
-
data: {
|
|
613
|
-
}
|
|
911
|
+
data: {},
|
|
614
912
|
});
|
|
615
913
|
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
616
914
|
});
|
|
617
915
|
it('calls handle locus mercury for all locus events', () => {
|
|
618
916
|
webex.meetings.handleLocusMercury({
|
|
619
917
|
data: {
|
|
620
|
-
eventType: test1
|
|
621
|
-
}
|
|
918
|
+
eventType: test1,
|
|
919
|
+
},
|
|
622
920
|
});
|
|
623
921
|
assert.calledOnce(webex.meetings.handleLocusEvent);
|
|
624
|
-
assert.calledWith(
|
|
625
|
-
|
|
626
|
-
|
|
922
|
+
assert.calledWith(
|
|
923
|
+
webex.meetings.handleLocusEvent,
|
|
924
|
+
{
|
|
925
|
+
eventType: test1,
|
|
926
|
+
},
|
|
927
|
+
true
|
|
928
|
+
);
|
|
627
929
|
});
|
|
628
930
|
});
|
|
629
931
|
describe('#handleLocusEvent', () => {
|
|
630
932
|
describe('there was a meeting', () => {
|
|
631
|
-
let parse;
|
|
632
|
-
|
|
633
933
|
beforeEach(() => {
|
|
634
|
-
parse = sinon.stub().returns(true);
|
|
635
934
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
636
|
-
locusInfo
|
|
637
|
-
parse
|
|
638
|
-
}
|
|
935
|
+
locusInfo,
|
|
639
936
|
});
|
|
640
937
|
});
|
|
641
|
-
it('should parse the meeting info', () => {
|
|
938
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
939
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
642
940
|
webex.meetings.handleLocusEvent({
|
|
643
|
-
locusUrl: url1
|
|
941
|
+
locusUrl: url1,
|
|
644
942
|
});
|
|
645
943
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
646
944
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
647
|
-
assert.calledOnce(parse);
|
|
648
|
-
assert.
|
|
649
|
-
|
|
650
|
-
|
|
945
|
+
assert.calledOnce(locusInfo.parse);
|
|
946
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
947
|
+
assert.calledWith(
|
|
948
|
+
locusInfo.parse,
|
|
949
|
+
{
|
|
950
|
+
locusInfo,
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
locusUrl: url1,
|
|
651
954
|
}
|
|
652
|
-
|
|
653
|
-
|
|
955
|
+
);
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
it('should not update main session locus cache', () => {
|
|
959
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
960
|
+
webex.meetings.handleLocusEvent({
|
|
961
|
+
locusUrl: url1,
|
|
654
962
|
});
|
|
963
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
655
964
|
});
|
|
656
965
|
});
|
|
657
966
|
describe('there was not a meeting', () => {
|
|
658
967
|
let initialSetup;
|
|
968
|
+
const webExMeetingId = '123456';
|
|
659
969
|
|
|
660
970
|
beforeEach(() => {
|
|
661
971
|
initialSetup = sinon.stub().returns(true);
|
|
662
972
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
663
|
-
webex.meetings.create = sinon.stub().returns(
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
973
|
+
webex.meetings.create = sinon.stub().returns(
|
|
974
|
+
Promise.resolve({
|
|
975
|
+
id: 'meeting-id',
|
|
976
|
+
locusInfo: {
|
|
977
|
+
...locusInfo,
|
|
978
|
+
initialSetup,
|
|
979
|
+
},
|
|
980
|
+
})
|
|
981
|
+
);
|
|
668
982
|
});
|
|
669
983
|
it('should setup the meeting by difference event', async () => {
|
|
670
984
|
await webex.meetings.handleLocusEvent({
|
|
671
985
|
locus: {
|
|
672
986
|
id: uuid1,
|
|
673
|
-
replaces: [
|
|
674
|
-
|
|
675
|
-
|
|
987
|
+
replaces: [
|
|
988
|
+
{
|
|
989
|
+
locusUrl: 'http:locusUrl',
|
|
990
|
+
},
|
|
991
|
+
],
|
|
676
992
|
self: {
|
|
677
993
|
callBackInfo: {
|
|
678
|
-
callbackAddress: uri1
|
|
679
|
-
}
|
|
680
|
-
}
|
|
994
|
+
callbackAddress: uri1,
|
|
995
|
+
},
|
|
996
|
+
},
|
|
997
|
+
info: {
|
|
998
|
+
webExMeetingId,
|
|
999
|
+
},
|
|
681
1000
|
},
|
|
682
1001
|
eventType: 'locus.difference',
|
|
683
|
-
locusUrl: url1
|
|
1002
|
+
locusUrl: url1,
|
|
684
1003
|
});
|
|
685
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1004
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
686
1005
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1006
|
+
assert.calledWith(
|
|
1007
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1008
|
+
'meetingNumber',
|
|
1009
|
+
webExMeetingId
|
|
1010
|
+
);
|
|
687
1011
|
assert.calledOnce(initialSetup);
|
|
688
1012
|
assert.calledWith(initialSetup, {
|
|
689
1013
|
id: uuid1,
|
|
690
|
-
replaces: [
|
|
691
|
-
|
|
692
|
-
|
|
1014
|
+
replaces: [
|
|
1015
|
+
{
|
|
1016
|
+
locusUrl: 'http:locusUrl',
|
|
1017
|
+
},
|
|
1018
|
+
],
|
|
693
1019
|
self: {
|
|
694
1020
|
callBackInfo: {
|
|
695
|
-
callbackAddress: uri1
|
|
696
|
-
}
|
|
697
|
-
}
|
|
1021
|
+
callbackAddress: uri1,
|
|
1022
|
+
},
|
|
1023
|
+
},
|
|
1024
|
+
info: {
|
|
1025
|
+
webExMeetingId,
|
|
1026
|
+
},
|
|
698
1027
|
});
|
|
699
1028
|
});
|
|
700
1029
|
it('should setup the meeting by difference event without replaces', async () => {
|
|
@@ -703,48 +1032,103 @@ describe('plugin-meetings', () => {
|
|
|
703
1032
|
id: uuid1,
|
|
704
1033
|
self: {
|
|
705
1034
|
callBackInfo: {
|
|
706
|
-
callbackAddress: uri1
|
|
707
|
-
}
|
|
708
|
-
}
|
|
1035
|
+
callbackAddress: uri1,
|
|
1036
|
+
},
|
|
1037
|
+
},
|
|
1038
|
+
info: {
|
|
1039
|
+
webExMeetingId,
|
|
1040
|
+
},
|
|
709
1041
|
},
|
|
710
1042
|
eventType: 'locus.difference',
|
|
711
|
-
locusUrl: url1
|
|
1043
|
+
locusUrl: url1,
|
|
712
1044
|
});
|
|
713
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1045
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
714
1046
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1047
|
+
assert.calledWith(
|
|
1048
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1049
|
+
'meetingNumber',
|
|
1050
|
+
webExMeetingId
|
|
1051
|
+
);
|
|
715
1052
|
assert.calledOnce(initialSetup);
|
|
716
1053
|
assert.calledWith(initialSetup, {
|
|
717
1054
|
id: uuid1,
|
|
718
1055
|
self: {
|
|
719
1056
|
callBackInfo: {
|
|
720
|
-
callbackAddress: uri1
|
|
721
|
-
}
|
|
722
|
-
}
|
|
1057
|
+
callbackAddress: uri1,
|
|
1058
|
+
},
|
|
1059
|
+
},
|
|
1060
|
+
info: {
|
|
1061
|
+
webExMeetingId,
|
|
1062
|
+
},
|
|
1063
|
+
});
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
it('sends client event correctly on finally', async () => {
|
|
1067
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
1068
|
+
|
|
1069
|
+
await webex.meetings.handleLocusEvent({
|
|
1070
|
+
locus: {
|
|
1071
|
+
id: uuid1,
|
|
1072
|
+
self: {
|
|
1073
|
+
callBackInfo: {
|
|
1074
|
+
callbackAddress: uri1,
|
|
1075
|
+
},
|
|
1076
|
+
},
|
|
1077
|
+
info: {
|
|
1078
|
+
webExMeetingId,
|
|
1079
|
+
},
|
|
1080
|
+
},
|
|
1081
|
+
eventType: 'locus.difference',
|
|
1082
|
+
locusUrl: url1,
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
await testUtils.flushPromises();
|
|
1086
|
+
|
|
1087
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
1088
|
+
name: 'client.call.remote-started',
|
|
1089
|
+
payload: {
|
|
1090
|
+
trigger: 'mercury-event',
|
|
1091
|
+
},
|
|
1092
|
+
options: {
|
|
1093
|
+
meetingId: 'meeting-id',
|
|
1094
|
+
},
|
|
723
1095
|
});
|
|
724
1096
|
});
|
|
1097
|
+
|
|
725
1098
|
it('should setup the meeting by a not difference event', async () => {
|
|
726
1099
|
await webex.meetings.handleLocusEvent({
|
|
727
1100
|
locus: {
|
|
728
1101
|
id: uuid1,
|
|
729
1102
|
self: {
|
|
730
1103
|
callBackInfo: {
|
|
731
|
-
callbackAddress: uri1
|
|
732
|
-
}
|
|
733
|
-
}
|
|
1104
|
+
callbackAddress: uri1,
|
|
1105
|
+
},
|
|
1106
|
+
},
|
|
1107
|
+
info: {
|
|
1108
|
+
webExMeetingId,
|
|
1109
|
+
},
|
|
734
1110
|
},
|
|
735
1111
|
eventType: test1,
|
|
736
|
-
locusUrl: url1
|
|
1112
|
+
locusUrl: url1,
|
|
737
1113
|
});
|
|
738
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1114
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
739
1115
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1116
|
+
assert.calledWith(
|
|
1117
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1118
|
+
'meetingNumber',
|
|
1119
|
+
webExMeetingId
|
|
1120
|
+
);
|
|
740
1121
|
assert.calledOnce(initialSetup);
|
|
741
1122
|
assert.calledWith(initialSetup, {
|
|
742
1123
|
id: uuid1,
|
|
743
1124
|
self: {
|
|
744
1125
|
callBackInfo: {
|
|
745
|
-
callbackAddress: uri1
|
|
746
|
-
}
|
|
747
|
-
}
|
|
1126
|
+
callbackAddress: uri1,
|
|
1127
|
+
},
|
|
1128
|
+
},
|
|
1129
|
+
info: {
|
|
1130
|
+
webExMeetingId,
|
|
1131
|
+
},
|
|
748
1132
|
});
|
|
749
1133
|
});
|
|
750
1134
|
|
|
@@ -753,13 +1137,13 @@ describe('plugin-meetings', () => {
|
|
|
753
1137
|
id: uuid1,
|
|
754
1138
|
self: {
|
|
755
1139
|
callbackInfo: {
|
|
756
|
-
callbackAddress: uri1
|
|
757
|
-
}
|
|
1140
|
+
callbackAddress: uri1,
|
|
1141
|
+
},
|
|
758
1142
|
},
|
|
759
1143
|
info: {
|
|
760
|
-
isUnifiedSpaceMeeting
|
|
1144
|
+
isUnifiedSpaceMeeting,
|
|
761
1145
|
},
|
|
762
|
-
conversationUrl: 'fakeConvoUrl'
|
|
1146
|
+
conversationUrl: 'fakeConvoUrl',
|
|
763
1147
|
},
|
|
764
1148
|
eventType: test1,
|
|
765
1149
|
locusUrl: url1,
|
|
@@ -767,19 +1151,40 @@ describe('plugin-meetings', () => {
|
|
|
767
1151
|
|
|
768
1152
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
769
1153
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
|
|
770
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
771
|
-
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
772
|
-
|
|
773
|
-
|
|
1154
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
1155
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
1156
|
+
'locusUrl',
|
|
1157
|
+
url1,
|
|
1158
|
+
]);
|
|
1159
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, [
|
|
1160
|
+
'correlationId',
|
|
1161
|
+
false,
|
|
1162
|
+
]);
|
|
1163
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, [
|
|
1164
|
+
'sipUri',
|
|
1165
|
+
uri1,
|
|
1166
|
+
]);
|
|
774
1167
|
assert.calledOnce(initialSetup);
|
|
775
1168
|
});
|
|
776
1169
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
777
1170
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
|
|
778
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
779
|
-
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
1171
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
1172
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
1173
|
+
'locusUrl',
|
|
1174
|
+
url1,
|
|
1175
|
+
]);
|
|
1176
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, [
|
|
1177
|
+
'correlationId',
|
|
1178
|
+
false,
|
|
1179
|
+
]);
|
|
1180
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, [
|
|
1181
|
+
'sipUri',
|
|
1182
|
+
uri1,
|
|
1183
|
+
]);
|
|
1184
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(3).args, [
|
|
1185
|
+
'conversationUrl',
|
|
1186
|
+
'fakeConvoUrl',
|
|
1187
|
+
]);
|
|
783
1188
|
assert.calledOnce(initialSetup);
|
|
784
1189
|
});
|
|
785
1190
|
});
|
|
@@ -794,15 +1199,23 @@ describe('plugin-meetings', () => {
|
|
|
794
1199
|
});
|
|
795
1200
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
796
1201
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1202
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
1203
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
1204
|
+
joinTXId: 'TSmrX61wNF',
|
|
1205
|
+
};
|
|
797
1206
|
|
|
798
1207
|
beforeEach(() => {
|
|
799
1208
|
clock = sinon.useFakeTimers();
|
|
800
1209
|
setTimeoutSpy = sinon.spy(clock, 'setTimeout');
|
|
801
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
1210
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
1211
|
+
Promise.resolve({
|
|
1212
|
+
body: {
|
|
1213
|
+
permissionToken:
|
|
1214
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
1215
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1216
|
+
},
|
|
1217
|
+
})
|
|
1218
|
+
);
|
|
806
1219
|
const nowTimeStamp = Date.now();
|
|
807
1220
|
|
|
808
1221
|
FAKE_TIME_TO_START = 0.1 * 60 * 1000;
|
|
@@ -816,12 +1229,41 @@ describe('plugin-meetings', () => {
|
|
|
816
1229
|
clock.restore();
|
|
817
1230
|
});
|
|
818
1231
|
|
|
819
|
-
const checkCreateWithoutDelay = (
|
|
820
|
-
|
|
1232
|
+
const checkCreateWithoutDelay = (
|
|
1233
|
+
meeting,
|
|
1234
|
+
destination,
|
|
1235
|
+
type,
|
|
1236
|
+
extraParams = {},
|
|
1237
|
+
expectedMeetingData = {},
|
|
1238
|
+
sendCAevents = false,
|
|
1239
|
+
injectMeetingInfo = false
|
|
1240
|
+
) => {
|
|
1241
|
+
if (injectMeetingInfo) {
|
|
1242
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1243
|
+
} else {
|
|
1244
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
821
1247
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
822
1248
|
assert.notCalled(setTimeoutSpy);
|
|
823
|
-
assert.
|
|
824
|
-
|
|
1249
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1250
|
+
|
|
1251
|
+
if (injectMeetingInfo) {
|
|
1252
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1253
|
+
} else {
|
|
1254
|
+
assert.calledWith(
|
|
1255
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1256
|
+
destination,
|
|
1257
|
+
type,
|
|
1258
|
+
null,
|
|
1259
|
+
null,
|
|
1260
|
+
undefined,
|
|
1261
|
+
undefined,
|
|
1262
|
+
extraParams,
|
|
1263
|
+
{meetingId: meeting.id, sendCAevents}
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
825
1267
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
826
1268
|
|
|
827
1269
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -830,94 +1272,257 @@ describe('plugin-meetings', () => {
|
|
|
830
1272
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
831
1273
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
832
1274
|
}
|
|
1275
|
+
if (expectedMeetingData.correlationId) {
|
|
1276
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1277
|
+
}
|
|
1278
|
+
if (expectedMeetingData.callStateForMetrics) {
|
|
1279
|
+
assert.deepEqual(
|
|
1280
|
+
meeting.callStateForMetrics,
|
|
1281
|
+
expectedMeetingData.callStateForMetrics
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
if (expectedMeetingData.meetingLookupUrl) {
|
|
1285
|
+
assert.equal(
|
|
1286
|
+
meeting.meetingInfo.meetingLookupUrl,
|
|
1287
|
+
expectedMeetingData.meetingLookupUrl
|
|
1288
|
+
);
|
|
1289
|
+
}
|
|
833
1290
|
assert.equal(meeting.destination, destination);
|
|
834
1291
|
assert.equal(meeting.destinationType, type);
|
|
835
|
-
assert.calledWith(
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
1292
|
+
assert.calledWith(
|
|
1293
|
+
TriggerProxy.trigger,
|
|
1294
|
+
sinon.match.instanceOf(Meetings),
|
|
1295
|
+
{
|
|
1296
|
+
file: 'meetings',
|
|
1297
|
+
function: 'createMeeting',
|
|
1298
|
+
},
|
|
1299
|
+
'meeting:added',
|
|
1300
|
+
{
|
|
1301
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1302
|
+
type: 'test meeting added type',
|
|
1303
|
+
}
|
|
1304
|
+
);
|
|
1305
|
+
assert.calledWith(
|
|
1306
|
+
TriggerProxy.trigger,
|
|
1307
|
+
meeting,
|
|
1308
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1309
|
+
'meeting:meetingInfoAvailable'
|
|
1310
|
+
);
|
|
841
1311
|
};
|
|
842
1312
|
|
|
843
1313
|
it('creates the meeting from a successful meeting info fetch promise testing', async () => {
|
|
844
1314
|
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
845
1315
|
|
|
846
1316
|
const expectedMeetingData = {
|
|
847
|
-
permissionToken:
|
|
848
|
-
|
|
1317
|
+
permissionToken:
|
|
1318
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
1319
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1320
|
+
correlationId: meeting.id,
|
|
849
1321
|
};
|
|
850
1322
|
|
|
851
|
-
checkCreateWithoutDelay(
|
|
1323
|
+
checkCreateWithoutDelay(
|
|
1324
|
+
meeting,
|
|
1325
|
+
'test destination',
|
|
1326
|
+
'test type',
|
|
1327
|
+
{},
|
|
1328
|
+
expectedMeetingData
|
|
1329
|
+
);
|
|
852
1330
|
});
|
|
853
1331
|
|
|
854
|
-
it('
|
|
855
|
-
const
|
|
1332
|
+
it('accepts injected meeting info', async () => {
|
|
1333
|
+
const meetingInfo = {
|
|
1334
|
+
permissionToken:
|
|
1335
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
1336
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1340
|
+
'test destination',
|
|
1341
|
+
'test type',
|
|
1342
|
+
false,
|
|
1343
|
+
{},
|
|
1344
|
+
undefined,
|
|
1345
|
+
false,
|
|
1346
|
+
meetingInfo
|
|
1347
|
+
);
|
|
1348
|
+
|
|
856
1349
|
const expectedMeetingData = {
|
|
857
|
-
|
|
858
|
-
|
|
1350
|
+
...meetingInfo,
|
|
1351
|
+
correlationId: meeting.id,
|
|
859
1352
|
};
|
|
860
1353
|
|
|
861
|
-
|
|
862
|
-
|
|
1354
|
+
checkCreateWithoutDelay(
|
|
1355
|
+
meeting,
|
|
1356
|
+
'test destination',
|
|
1357
|
+
'test type',
|
|
1358
|
+
{},
|
|
1359
|
+
expectedMeetingData,
|
|
1360
|
+
false,
|
|
1361
|
+
true
|
|
1362
|
+
);
|
|
863
1363
|
});
|
|
864
1364
|
|
|
865
|
-
it('
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
webExMeetingId: 'locusMeetingId',
|
|
871
|
-
sipUri: 'locusSipUri',
|
|
872
|
-
owner: 'locusOwner'
|
|
873
|
-
},
|
|
874
|
-
meeting: {
|
|
875
|
-
startTime: fakeMeetingStartTimeString
|
|
876
|
-
},
|
|
877
|
-
fullState: {
|
|
878
|
-
active: false
|
|
879
|
-
}
|
|
1365
|
+
it('accepts injected meeting info with meeting lookup url', async () => {
|
|
1366
|
+
const meetingInfo = {
|
|
1367
|
+
permissionToken:
|
|
1368
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
1369
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
880
1370
|
};
|
|
881
1371
|
|
|
882
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1372
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1373
|
+
'test destination',
|
|
1374
|
+
'test type',
|
|
1375
|
+
false,
|
|
1376
|
+
{},
|
|
1377
|
+
undefined,
|
|
1378
|
+
false,
|
|
1379
|
+
meetingInfo,
|
|
1380
|
+
'meetingLookupUrl'
|
|
1381
|
+
);
|
|
883
1382
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1383
|
+
const expectedMeetingData = {
|
|
1384
|
+
...meetingInfo,
|
|
1385
|
+
meetingLookupUrl: 'meetingLookupUrl',
|
|
1386
|
+
correlationId: meeting.id,
|
|
1387
|
+
};
|
|
887
1388
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1389
|
+
checkCreateWithoutDelay(
|
|
1390
|
+
meeting,
|
|
1391
|
+
'test destination',
|
|
1392
|
+
'test type',
|
|
1393
|
+
{},
|
|
1394
|
+
expectedMeetingData,
|
|
1395
|
+
false,
|
|
1396
|
+
true
|
|
1397
|
+
);
|
|
1398
|
+
});
|
|
896
1399
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
}
|
|
903
|
-
meeting
|
|
1400
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1401
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
1402
|
+
|
|
1403
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${
|
|
1404
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1405
|
+
}`, async () => {
|
|
1406
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1407
|
+
'test destination',
|
|
1408
|
+
'test type',
|
|
1409
|
+
false,
|
|
1410
|
+
infoExtraParams
|
|
1411
|
+
);
|
|
1412
|
+
const expectedMeetingData = {
|
|
1413
|
+
permissionToken:
|
|
1414
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
1415
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1416
|
+
};
|
|
1417
|
+
|
|
1418
|
+
assert.instanceOf(
|
|
1419
|
+
meeting,
|
|
1420
|
+
Meeting,
|
|
1421
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1422
|
+
);
|
|
1423
|
+
checkCreateWithoutDelay(
|
|
1424
|
+
meeting,
|
|
1425
|
+
'test destination',
|
|
1426
|
+
'test type',
|
|
1427
|
+
infoExtraParamsProvided ? infoExtraParams : {},
|
|
1428
|
+
expectedMeetingData
|
|
1429
|
+
);
|
|
904
1430
|
});
|
|
905
1431
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1432
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${
|
|
1433
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1434
|
+
}`, async () => {
|
|
1435
|
+
const FAKE_LOCUS_MEETING = {
|
|
1436
|
+
conversationUrl: 'locusConvURL',
|
|
1437
|
+
url: 'locusUrl',
|
|
1438
|
+
info: {
|
|
1439
|
+
webExMeetingId: 'locusMeetingId',
|
|
1440
|
+
sipUri: 'locusSipUri',
|
|
1441
|
+
owner: 'locusOwner',
|
|
1442
|
+
},
|
|
1443
|
+
meeting: {
|
|
1444
|
+
startTime: fakeMeetingStartTimeString,
|
|
1445
|
+
},
|
|
1446
|
+
fullState: {
|
|
1447
|
+
active: false,
|
|
1448
|
+
},
|
|
1449
|
+
};
|
|
1450
|
+
|
|
1451
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1452
|
+
FAKE_LOCUS_MEETING,
|
|
1453
|
+
'test type',
|
|
1454
|
+
true,
|
|
1455
|
+
infoExtraParams
|
|
1456
|
+
);
|
|
1457
|
+
|
|
1458
|
+
assert.instanceOf(
|
|
1459
|
+
meeting,
|
|
1460
|
+
Meeting,
|
|
1461
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1462
|
+
);
|
|
1463
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1464
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1465
|
+
|
|
1466
|
+
// Parse meeting info with locus object
|
|
1467
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1468
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1469
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1470
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1471
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1472
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1473
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1474
|
+
|
|
1475
|
+
// Add meeting and send trigger
|
|
1476
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1477
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1478
|
+
assert.calledWith(
|
|
1479
|
+
TriggerProxy.trigger,
|
|
1480
|
+
sinon.match.instanceOf(Meetings),
|
|
1481
|
+
{
|
|
1482
|
+
file: 'meetings',
|
|
1483
|
+
function: 'createMeeting',
|
|
1484
|
+
},
|
|
1485
|
+
'meeting:added',
|
|
1486
|
+
{
|
|
1487
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1488
|
+
type: 'test meeting added type',
|
|
1489
|
+
}
|
|
1490
|
+
);
|
|
1491
|
+
|
|
1492
|
+
// When timer expires
|
|
1493
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1494
|
+
await testUtils.flushPromises();
|
|
1495
|
+
|
|
1496
|
+
assert.calledWith(
|
|
1497
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1498
|
+
FAKE_LOCUS_MEETING,
|
|
1499
|
+
'test type',
|
|
1500
|
+
null,
|
|
1501
|
+
null,
|
|
1502
|
+
undefined,
|
|
1503
|
+
undefined,
|
|
1504
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1505
|
+
);
|
|
1506
|
+
|
|
1507
|
+
// Parse meeting info is called again with new meeting info
|
|
1508
|
+
await testUtils.flushPromises();
|
|
1509
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1510
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1511
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1512
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1513
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1514
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1515
|
+
assert.equal(
|
|
1516
|
+
meeting.permissionToken,
|
|
1517
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0'
|
|
1518
|
+
);
|
|
1519
|
+
assert.calledWith(
|
|
1520
|
+
TriggerProxy.trigger,
|
|
1521
|
+
meeting,
|
|
1522
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1523
|
+
'meeting:meetingInfoAvailable'
|
|
1524
|
+
);
|
|
1525
|
+
});
|
|
921
1526
|
});
|
|
922
1527
|
|
|
923
1528
|
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
@@ -927,19 +1532,27 @@ describe('plugin-meetings', () => {
|
|
|
927
1532
|
info: {
|
|
928
1533
|
webExMeetingId: 'locusMeetingId',
|
|
929
1534
|
sipUri: 'locusSipUri',
|
|
930
|
-
owner: 'locusOwner'
|
|
1535
|
+
owner: 'locusOwner',
|
|
931
1536
|
},
|
|
932
1537
|
meeting: {
|
|
933
|
-
startTime: fakeMeetingStartTimeString
|
|
1538
|
+
startTime: fakeMeetingStartTimeString,
|
|
934
1539
|
},
|
|
935
1540
|
fullState: {
|
|
936
|
-
active: true
|
|
937
|
-
}
|
|
1541
|
+
active: true,
|
|
1542
|
+
},
|
|
938
1543
|
};
|
|
939
1544
|
|
|
940
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1545
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1546
|
+
FAKE_LOCUS_MEETING,
|
|
1547
|
+
'test type',
|
|
1548
|
+
true
|
|
1549
|
+
);
|
|
941
1550
|
|
|
942
|
-
assert.instanceOf(
|
|
1551
|
+
assert.instanceOf(
|
|
1552
|
+
meeting,
|
|
1553
|
+
Meeting,
|
|
1554
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1555
|
+
);
|
|
943
1556
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
944
1557
|
});
|
|
945
1558
|
|
|
@@ -950,27 +1563,35 @@ describe('plugin-meetings', () => {
|
|
|
950
1563
|
info: {
|
|
951
1564
|
webExMeetingId: 'locusMeetingId',
|
|
952
1565
|
sipUri: 'locusSipUri',
|
|
953
|
-
owner: 'locusOwner'
|
|
1566
|
+
owner: 'locusOwner',
|
|
954
1567
|
},
|
|
955
1568
|
meeting: {
|
|
956
|
-
startTime: fakeMeetingStartTimeString -
|
|
1569
|
+
startTime: fakeMeetingStartTimeString - 1 * 60 * 60 * 1000,
|
|
957
1570
|
},
|
|
958
1571
|
fullState: {
|
|
959
|
-
active: false
|
|
960
|
-
}
|
|
1572
|
+
active: false,
|
|
1573
|
+
},
|
|
961
1574
|
};
|
|
962
1575
|
|
|
963
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1576
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1577
|
+
FAKE_LOCUS_MEETING,
|
|
1578
|
+
'test type',
|
|
1579
|
+
true
|
|
1580
|
+
);
|
|
964
1581
|
|
|
965
|
-
assert.instanceOf(
|
|
1582
|
+
assert.instanceOf(
|
|
1583
|
+
meeting,
|
|
1584
|
+
Meeting,
|
|
1585
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1586
|
+
);
|
|
966
1587
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
967
1588
|
});
|
|
968
1589
|
|
|
969
1590
|
it('creates the meeting from a successful meeting info fetch that has no random delay because enableUnifiedMeetings is disabled', async () => {
|
|
970
1591
|
Object.assign(webex.meetings.config, {
|
|
971
1592
|
experimental: {
|
|
972
|
-
enableUnifiedMeetings: false
|
|
973
|
-
}
|
|
1593
|
+
enableUnifiedMeetings: false,
|
|
1594
|
+
},
|
|
974
1595
|
});
|
|
975
1596
|
const FAKE_LOCUS_MEETING = {
|
|
976
1597
|
conversationUrl: 'locusConvURL',
|
|
@@ -978,51 +1599,228 @@ describe('plugin-meetings', () => {
|
|
|
978
1599
|
info: {
|
|
979
1600
|
webExMeetingId: 'locusMeetingId',
|
|
980
1601
|
sipUri: 'locusSipUri',
|
|
981
|
-
owner: 'locusOwner'
|
|
1602
|
+
owner: 'locusOwner',
|
|
982
1603
|
},
|
|
983
1604
|
meeting: {
|
|
984
|
-
startTime: fakeMeetingStartTimeString
|
|
1605
|
+
startTime: fakeMeetingStartTimeString,
|
|
985
1606
|
},
|
|
986
1607
|
fullState: {
|
|
987
|
-
active: false
|
|
988
|
-
}
|
|
1608
|
+
active: false,
|
|
1609
|
+
},
|
|
989
1610
|
};
|
|
990
1611
|
|
|
991
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1612
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1613
|
+
FAKE_LOCUS_MEETING,
|
|
1614
|
+
'test type',
|
|
1615
|
+
true
|
|
1616
|
+
);
|
|
992
1617
|
|
|
993
|
-
assert.instanceOf(
|
|
1618
|
+
assert.instanceOf(
|
|
1619
|
+
meeting,
|
|
1620
|
+
Meeting,
|
|
1621
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1622
|
+
);
|
|
994
1623
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
995
1624
|
});
|
|
1625
|
+
|
|
1626
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1627
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1628
|
+
'test destination',
|
|
1629
|
+
'test type',
|
|
1630
|
+
false,
|
|
1631
|
+
{},
|
|
1632
|
+
{correlationId: 'my-correlationId'}
|
|
1633
|
+
);
|
|
1634
|
+
|
|
1635
|
+
const expectedMeetingData = {
|
|
1636
|
+
correlationId: 'my-correlationId',
|
|
1637
|
+
};
|
|
1638
|
+
|
|
1639
|
+
checkCreateWithoutDelay(
|
|
1640
|
+
meeting,
|
|
1641
|
+
'test destination',
|
|
1642
|
+
'test type',
|
|
1643
|
+
{},
|
|
1644
|
+
expectedMeetingData,
|
|
1645
|
+
true
|
|
1646
|
+
);
|
|
1647
|
+
});
|
|
1648
|
+
|
|
1649
|
+
it('creates meeting with the callStateForMetrics provided', async () => {
|
|
1650
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1651
|
+
'test destination',
|
|
1652
|
+
'test type',
|
|
1653
|
+
false,
|
|
1654
|
+
{},
|
|
1655
|
+
{
|
|
1656
|
+
correlationId: 'my-correlationId',
|
|
1657
|
+
joinTrigger: 'my-join-trigger',
|
|
1658
|
+
loginType: 'my-login-type',
|
|
1659
|
+
}
|
|
1660
|
+
);
|
|
1661
|
+
|
|
1662
|
+
const expectedMeetingData = {
|
|
1663
|
+
correlationId: 'my-correlationId',
|
|
1664
|
+
callStateForMetrics: {
|
|
1665
|
+
correlationId: 'my-correlationId',
|
|
1666
|
+
joinTrigger: 'my-join-trigger',
|
|
1667
|
+
loginType: 'my-login-type',
|
|
1668
|
+
},
|
|
1669
|
+
};
|
|
1670
|
+
|
|
1671
|
+
checkCreateWithoutDelay(
|
|
1672
|
+
meeting,
|
|
1673
|
+
'test destination',
|
|
1674
|
+
'test type',
|
|
1675
|
+
{},
|
|
1676
|
+
expectedMeetingData,
|
|
1677
|
+
true
|
|
1678
|
+
);
|
|
1679
|
+
});
|
|
996
1680
|
});
|
|
997
1681
|
|
|
998
1682
|
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
999
1683
|
beforeEach(() => {
|
|
1000
1684
|
console.error = sinon.stub().returns(false);
|
|
1001
1685
|
TriggerProxy.trigger.reset();
|
|
1002
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1686
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1687
|
+
.stub()
|
|
1688
|
+
.returns(Promise.reject(new Error('test')));
|
|
1689
|
+
webex.meetings.destroy = sinon.stub().returns(Promise.resolve());
|
|
1690
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1003
1691
|
});
|
|
1692
|
+
|
|
1693
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1694
|
+
try {
|
|
1695
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1696
|
+
'test destination',
|
|
1697
|
+
'test type',
|
|
1698
|
+
undefined,
|
|
1699
|
+
undefined,
|
|
1700
|
+
undefined,
|
|
1701
|
+
failOnMissingMeetingInfo
|
|
1702
|
+
);
|
|
1703
|
+
|
|
1704
|
+
assert.instanceOf(
|
|
1705
|
+
meeting,
|
|
1706
|
+
Meeting,
|
|
1707
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1708
|
+
);
|
|
1709
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1710
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1711
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1712
|
+
assert.calledWith(
|
|
1713
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1714
|
+
'test destination',
|
|
1715
|
+
'test type'
|
|
1716
|
+
);
|
|
1717
|
+
|
|
1718
|
+
if (destroy) {
|
|
1719
|
+
assert.calledWith(
|
|
1720
|
+
webex.meetings.destroy,
|
|
1721
|
+
sinon.match.instanceOf(Meeting),
|
|
1722
|
+
'MISSING_MEETING_INFO'
|
|
1723
|
+
);
|
|
1724
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1725
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1726
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1727
|
+
} else {
|
|
1728
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1729
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1730
|
+
assert.calledWith(
|
|
1731
|
+
TriggerProxy.trigger,
|
|
1732
|
+
sinon.match.instanceOf(Meetings),
|
|
1733
|
+
{
|
|
1734
|
+
file: 'meetings',
|
|
1735
|
+
function: 'createMeeting',
|
|
1736
|
+
},
|
|
1737
|
+
'meeting:added',
|
|
1738
|
+
{
|
|
1739
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1740
|
+
type: 'test meeting added type',
|
|
1741
|
+
}
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
} catch (err) {
|
|
1745
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
|
|
1004
1749
|
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1005
|
-
|
|
1750
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1751
|
+
});
|
|
1006
1752
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1010
|
-
assert.calledTwice(TriggerProxy.trigger);
|
|
1011
|
-
assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, 'test destination', 'test type');
|
|
1012
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1013
|
-
assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
|
|
1014
|
-
file: 'meetings', function: 'createMeeting'
|
|
1015
|
-
}, 'meeting:added', {
|
|
1016
|
-
meeting: sinon.match.instanceOf(Meeting), type: 'test meeting added type'
|
|
1017
|
-
});
|
|
1753
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1754
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1018
1755
|
});
|
|
1019
1756
|
});
|
|
1757
|
+
|
|
1758
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1759
|
+
forEach(
|
|
1760
|
+
[
|
|
1761
|
+
{
|
|
1762
|
+
error: new CaptchaError(),
|
|
1763
|
+
debugLogMessage:
|
|
1764
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1765
|
+
},
|
|
1766
|
+
{
|
|
1767
|
+
error: new PasswordError(),
|
|
1768
|
+
debugLogMessage:
|
|
1769
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1770
|
+
},
|
|
1771
|
+
{
|
|
1772
|
+
error: new PermissionError(),
|
|
1773
|
+
debugLogMessage:
|
|
1774
|
+
'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.',
|
|
1775
|
+
},
|
|
1776
|
+
{
|
|
1777
|
+
error: new Error(),
|
|
1778
|
+
infoLogMessage: true,
|
|
1779
|
+
debugLogMessage:
|
|
1780
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1781
|
+
},
|
|
1782
|
+
],
|
|
1783
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1784
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1785
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1786
|
+
.stub()
|
|
1787
|
+
.returns(Promise.reject(error));
|
|
1788
|
+
|
|
1789
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1790
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1791
|
+
|
|
1792
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1793
|
+
|
|
1794
|
+
assert.instanceOf(
|
|
1795
|
+
meeting,
|
|
1796
|
+
Meeting,
|
|
1797
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1798
|
+
);
|
|
1799
|
+
|
|
1800
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1801
|
+
|
|
1802
|
+
if (infoLogMessage) {
|
|
1803
|
+
assert.calledWith(
|
|
1804
|
+
LoggerProxy.logger.info,
|
|
1805
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1806
|
+
);
|
|
1807
|
+
} else {
|
|
1808
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
);
|
|
1813
|
+
});
|
|
1020
1814
|
});
|
|
1021
1815
|
});
|
|
1022
1816
|
describe('Public Event Triggers', () => {
|
|
1817
|
+
let cleanUpSpy;
|
|
1023
1818
|
describe('#destroy', () => {
|
|
1024
1819
|
beforeEach(() => {
|
|
1025
|
-
|
|
1820
|
+
cleanUpSpy = sinon.stub(MeetingUtil, 'cleanUp');
|
|
1821
|
+
});
|
|
1822
|
+
afterEach(() => {
|
|
1823
|
+
cleanUpSpy.restore();
|
|
1026
1824
|
});
|
|
1027
1825
|
it('should have #destroy', () => {
|
|
1028
1826
|
assert.exists(webex.meetings.destroy);
|
|
@@ -1039,11 +1837,19 @@ describe('plugin-meetings', () => {
|
|
|
1039
1837
|
|
|
1040
1838
|
assert.calledOnce(webex.meetings.meetingCollection.delete);
|
|
1041
1839
|
assert.calledWith(webex.meetings.meetingCollection.delete, meeting.id);
|
|
1042
|
-
assert.calledWith(
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1840
|
+
assert.calledWith(
|
|
1841
|
+
TriggerProxy.trigger,
|
|
1842
|
+
sinon.match.instanceOf(Meetings),
|
|
1843
|
+
{
|
|
1844
|
+
file: 'meetings',
|
|
1845
|
+
function: 'destroy',
|
|
1846
|
+
},
|
|
1847
|
+
'meeting:removed',
|
|
1848
|
+
{
|
|
1849
|
+
meetingId: meeting.id,
|
|
1850
|
+
reason: test1,
|
|
1851
|
+
}
|
|
1852
|
+
);
|
|
1047
1853
|
});
|
|
1048
1854
|
});
|
|
1049
1855
|
|
|
@@ -1068,7 +1874,8 @@ describe('plugin-meetings', () => {
|
|
|
1068
1874
|
it('should trigger event upon mercury disconnect', () => {
|
|
1069
1875
|
const {meetings} = webex;
|
|
1070
1876
|
const SCOPE = {
|
|
1071
|
-
file: 'meetings/index',
|
|
1877
|
+
file: 'meetings/index',
|
|
1878
|
+
function: 'handleMercuryOffline',
|
|
1072
1879
|
};
|
|
1073
1880
|
const EVENT = 'network:disconnected';
|
|
1074
1881
|
|
|
@@ -1086,6 +1893,8 @@ describe('plugin-meetings', () => {
|
|
|
1086
1893
|
});
|
|
1087
1894
|
|
|
1088
1895
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1896
|
+
let loggerProxySpy;
|
|
1897
|
+
|
|
1089
1898
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1090
1899
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1091
1900
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1093,19 +1902,140 @@ describe('plugin-meetings', () => {
|
|
|
1093
1902
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1094
1903
|
});
|
|
1095
1904
|
|
|
1905
|
+
const setup = ({user} = {}) => {
|
|
1906
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1907
|
+
|
|
1908
|
+
Object.assign(webex.internal, {
|
|
1909
|
+
services: {
|
|
1910
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1911
|
+
},
|
|
1912
|
+
user: {
|
|
1913
|
+
get: sinon.stub().returns(Promise.resolve(user)),
|
|
1914
|
+
},
|
|
1915
|
+
});
|
|
1916
|
+
};
|
|
1917
|
+
|
|
1096
1918
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1919
|
+
setup();
|
|
1920
|
+
|
|
1097
1921
|
Object.assign(webex.internal, {
|
|
1098
1922
|
services: {
|
|
1099
1923
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1100
1924
|
},
|
|
1925
|
+
});
|
|
1926
|
+
|
|
1927
|
+
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1928
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1929
|
+
});
|
|
1930
|
+
assert.calledOnceWithExactly(
|
|
1931
|
+
loggerProxySpy,
|
|
1932
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1933
|
+
);
|
|
1934
|
+
});
|
|
1101
1935
|
|
|
1936
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1937
|
+
setup({
|
|
1938
|
+
user: {
|
|
1939
|
+
userPreferences: {
|
|
1940
|
+
userPreferencesItems: {
|
|
1941
|
+
preferredWebExSite: 'site.webex.com',
|
|
1942
|
+
},
|
|
1943
|
+
},
|
|
1944
|
+
},
|
|
1102
1945
|
});
|
|
1103
1946
|
|
|
1104
|
-
await webex.meetings.fetchUserPreferredWebexSite()
|
|
1105
|
-
|
|
1947
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1948
|
+
|
|
1949
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1950
|
+
assert.notCalled(loggerProxySpy);
|
|
1951
|
+
});
|
|
1952
|
+
|
|
1953
|
+
forEach(
|
|
1954
|
+
[
|
|
1955
|
+
{user: undefined},
|
|
1956
|
+
{user: {userPreferences: {}}},
|
|
1957
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1958
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1959
|
+
],
|
|
1960
|
+
({user}) => {
|
|
1961
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1962
|
+
setup({user});
|
|
1963
|
+
|
|
1964
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1965
|
+
|
|
1106
1966
|
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1967
|
+
assert.calledOnceWithExactly(
|
|
1968
|
+
loggerProxySpy,
|
|
1969
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1970
|
+
);
|
|
1107
1971
|
});
|
|
1972
|
+
}
|
|
1973
|
+
);
|
|
1974
|
+
|
|
1975
|
+
it('should handle a get user failure', async () => {
|
|
1976
|
+
setup();
|
|
1977
|
+
|
|
1978
|
+
webex.internal.user.get.rejects(new Error());
|
|
1979
|
+
|
|
1980
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1981
|
+
|
|
1982
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1983
|
+
assert.calledOnceWithExactly(
|
|
1984
|
+
loggerProxySpy,
|
|
1985
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1986
|
+
);
|
|
1987
|
+
});
|
|
1988
|
+
|
|
1989
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1990
|
+
setup({
|
|
1991
|
+
user: {
|
|
1992
|
+
userPreferences: {
|
|
1993
|
+
userPreferencesItems: {
|
|
1994
|
+
preferredWebExSite: 'site.webex.com',
|
|
1995
|
+
},
|
|
1996
|
+
},
|
|
1997
|
+
},
|
|
1998
|
+
});
|
|
1999
|
+
|
|
2000
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
2001
|
+
|
|
2002
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
2003
|
+
assert.notCalled(loggerProxySpy);
|
|
2004
|
+
});
|
|
2005
|
+
|
|
2006
|
+
forEach([
|
|
2007
|
+
{user: undefined},
|
|
2008
|
+
{user: {userPreferences: {}}},
|
|
2009
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
2010
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
2011
|
+
], ({user}) => {
|
|
2012
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
2013
|
+
setup({user});
|
|
2014
|
+
|
|
2015
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
2016
|
+
|
|
2017
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
2018
|
+
assert.calledOnceWithExactly(
|
|
2019
|
+
loggerProxySpy,
|
|
2020
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
2021
|
+
);
|
|
2022
|
+
});
|
|
2023
|
+
});
|
|
2024
|
+
|
|
2025
|
+
it('should handle a get user failure', async () => {
|
|
2026
|
+
setup();
|
|
2027
|
+
|
|
2028
|
+
webex.internal.user.get.rejects(new Error());
|
|
2029
|
+
|
|
2030
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
2031
|
+
|
|
2032
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
2033
|
+
assert.calledOnceWithExactly(
|
|
2034
|
+
loggerProxySpy,
|
|
2035
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
2036
|
+
);
|
|
1108
2037
|
});
|
|
2038
|
+
|
|
1109
2039
|
});
|
|
1110
2040
|
});
|
|
1111
2041
|
|
|
@@ -1120,11 +2050,15 @@ describe('plugin-meetings', () => {
|
|
|
1120
2050
|
TriggerProxy.trigger.reset();
|
|
1121
2051
|
// clock = sinon.useFakeTimers();
|
|
1122
2052
|
// setTimeoutSpy = sinon.spy(clock, 'setTimeout');
|
|
1123
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
2053
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
2054
|
+
Promise.resolve({
|
|
2055
|
+
body: {
|
|
2056
|
+
permissionToken:
|
|
2057
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
2058
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
2059
|
+
},
|
|
2060
|
+
})
|
|
2061
|
+
);
|
|
1128
2062
|
|
|
1129
2063
|
meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1130
2064
|
|
|
@@ -1132,37 +2066,37 @@ describe('plugin-meetings', () => {
|
|
|
1132
2066
|
});
|
|
1133
2067
|
|
|
1134
2068
|
it('triggers correct event when CONTROLS_ENTRY_EXIT_TONE_UPDATED emitted', async () => {
|
|
1135
|
-
await meeting.locusInfo.emitScoped(
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
{entryExitTone: 'foo'}
|
|
1139
|
-
);
|
|
2069
|
+
await meeting.locusInfo.emitScoped({}, LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED, {
|
|
2070
|
+
entryExitTone: 'foo',
|
|
2071
|
+
});
|
|
1140
2072
|
|
|
1141
2073
|
assert.calledOnce(TriggerProxy.trigger);
|
|
1142
|
-
assert.calledWith(
|
|
2074
|
+
assert.calledWith(
|
|
2075
|
+
TriggerProxy.trigger,
|
|
2076
|
+
sinon.match.instanceOf(Meeting),
|
|
1143
2077
|
{
|
|
1144
2078
|
file: 'meeting/index',
|
|
1145
|
-
function: 'setupLocusControlsListener'
|
|
2079
|
+
function: 'setupLocusControlsListener',
|
|
1146
2080
|
},
|
|
1147
2081
|
EVENT_TRIGGERS.MEETING_ENTRY_EXIT_TONE_UPDATE,
|
|
1148
|
-
{entryExitTone: 'foo'}
|
|
2082
|
+
{entryExitTone: 'foo'}
|
|
2083
|
+
);
|
|
1149
2084
|
});
|
|
1150
2085
|
|
|
1151
2086
|
const checkSelfTrigger = async (inEvent, outEvent) => {
|
|
1152
|
-
await meeting.locusInfo.emitScoped(
|
|
1153
|
-
{},
|
|
1154
|
-
inEvent,
|
|
1155
|
-
{foo: 'bar'}
|
|
1156
|
-
);
|
|
2087
|
+
await meeting.locusInfo.emitScoped({}, inEvent, {foo: 'bar'});
|
|
1157
2088
|
|
|
1158
2089
|
assert.calledOnce(TriggerProxy.trigger);
|
|
1159
|
-
assert.calledWith(
|
|
2090
|
+
assert.calledWith(
|
|
2091
|
+
TriggerProxy.trigger,
|
|
2092
|
+
sinon.match.instanceOf(Meeting),
|
|
1160
2093
|
{
|
|
1161
2094
|
file: 'meeting/index',
|
|
1162
|
-
function: 'setUpLocusInfoSelfListener'
|
|
2095
|
+
function: 'setUpLocusInfoSelfListener',
|
|
1163
2096
|
},
|
|
1164
2097
|
outEvent,
|
|
1165
|
-
{payload: {foo: 'bar'}}
|
|
2098
|
+
{payload: {foo: 'bar'}}
|
|
2099
|
+
);
|
|
1166
2100
|
};
|
|
1167
2101
|
|
|
1168
2102
|
it('triggers correct event when SELF_CANNOT_VIEW_PARTICIPANT_LIST_CHANGE emitted', async () => {
|
|
@@ -1186,5 +2120,523 @@ describe('plugin-meetings', () => {
|
|
|
1186
2120
|
);
|
|
1187
2121
|
});
|
|
1188
2122
|
});
|
|
2123
|
+
|
|
2124
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
2125
|
+
let meeting;
|
|
2126
|
+
let newLocus;
|
|
2127
|
+
beforeEach(() => {
|
|
2128
|
+
meeting = {
|
|
2129
|
+
controls: {},
|
|
2130
|
+
self: {},
|
|
2131
|
+
};
|
|
2132
|
+
newLocus = {
|
|
2133
|
+
controls: {},
|
|
2134
|
+
self: {},
|
|
2135
|
+
};
|
|
2136
|
+
});
|
|
2137
|
+
afterEach(() => {
|
|
2138
|
+
sinon.restore();
|
|
2139
|
+
});
|
|
2140
|
+
it('check normal case will return true', () => {
|
|
2141
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
2142
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2143
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2144
|
+
assert.equal(result, true);
|
|
2145
|
+
assert.calledWith(
|
|
2146
|
+
LoggerProxy.logger.log,
|
|
2147
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
2148
|
+
);
|
|
2149
|
+
});
|
|
2150
|
+
|
|
2151
|
+
it('check self joined and joined on this device, return true', () => {
|
|
2152
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
2153
|
+
newLocus.self.state = 'JOINED';
|
|
2154
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
2155
|
+
|
|
2156
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2157
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2158
|
+
assert.equal(result, true);
|
|
2159
|
+
assert.calledWith(
|
|
2160
|
+
LoggerProxy.logger.log,
|
|
2161
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
2162
|
+
);
|
|
2163
|
+
});
|
|
2164
|
+
|
|
2165
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
2166
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
2167
|
+
joinedWith: {
|
|
2168
|
+
replaces: [
|
|
2169
|
+
{
|
|
2170
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
2171
|
+
},
|
|
2172
|
+
],
|
|
2173
|
+
},
|
|
2174
|
+
});
|
|
2175
|
+
newLocus.self.state = 'JOINED';
|
|
2176
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
2177
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2178
|
+
replaces: [
|
|
2179
|
+
{
|
|
2180
|
+
replaceAt: '2023-03-27T02:17:01.506Z',
|
|
2181
|
+
},
|
|
2182
|
+
],
|
|
2183
|
+
});
|
|
2184
|
+
|
|
2185
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2186
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2187
|
+
assert.equal(result, false);
|
|
2188
|
+
assert.calledWith(
|
|
2189
|
+
LoggerProxy.logger.log,
|
|
2190
|
+
`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`
|
|
2191
|
+
);
|
|
2192
|
+
});
|
|
2193
|
+
|
|
2194
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
2195
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
2196
|
+
joinedWith: {
|
|
2197
|
+
correlationId: '111',
|
|
2198
|
+
},
|
|
2199
|
+
});
|
|
2200
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
2201
|
+
meeting.correlationId = '111';
|
|
2202
|
+
|
|
2203
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2204
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2205
|
+
assert.equal(result, false);
|
|
2206
|
+
assert.calledWith(
|
|
2207
|
+
LoggerProxy.logger.log,
|
|
2208
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
2209
|
+
);
|
|
2210
|
+
});
|
|
2211
|
+
|
|
2212
|
+
it('check self is moved and removed, return false', () => {
|
|
2213
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2214
|
+
newLocus.self.state = 'LEFT';
|
|
2215
|
+
newLocus.self.reason = 'MOVED';
|
|
2216
|
+
newLocus.self.removed = true;
|
|
2217
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2218
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2219
|
+
assert.equal(result, false);
|
|
2220
|
+
assert.calledWith(
|
|
2221
|
+
LoggerProxy.logger.log,
|
|
2222
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2223
|
+
);
|
|
2224
|
+
});
|
|
2225
|
+
|
|
2226
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
2227
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2228
|
+
newLocus.self.state = 'LEFT';
|
|
2229
|
+
newLocus.self.reason = 'MOVED';
|
|
2230
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2231
|
+
state: 'LEFT',
|
|
2232
|
+
reason: 'MOVED',
|
|
2233
|
+
});
|
|
2234
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2235
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2236
|
+
assert.equal(result, false);
|
|
2237
|
+
assert.calledWith(
|
|
2238
|
+
LoggerProxy.logger.log,
|
|
2239
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2240
|
+
);
|
|
2241
|
+
});
|
|
2242
|
+
|
|
2243
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
2244
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2245
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
2246
|
+
newLocus.self.state = 'JOINED';
|
|
2247
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2248
|
+
state: 'LEFT',
|
|
2249
|
+
reason: 'MOVED',
|
|
2250
|
+
});
|
|
2251
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2252
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2253
|
+
assert.equal(result, false);
|
|
2254
|
+
assert.calledWith(
|
|
2255
|
+
LoggerProxy.logger.log,
|
|
2256
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
2257
|
+
);
|
|
2258
|
+
});
|
|
2259
|
+
});
|
|
2260
|
+
|
|
2261
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
2262
|
+
let meeting;
|
|
2263
|
+
let newLocus;
|
|
2264
|
+
beforeEach(() => {
|
|
2265
|
+
meeting = {
|
|
2266
|
+
controls: {},
|
|
2267
|
+
self: {},
|
|
2268
|
+
};
|
|
2269
|
+
newLocus = {
|
|
2270
|
+
controls: {},
|
|
2271
|
+
self: {},
|
|
2272
|
+
};
|
|
2273
|
+
});
|
|
2274
|
+
afterEach(() => {
|
|
2275
|
+
sinon.restore();
|
|
2276
|
+
});
|
|
2277
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
2278
|
+
newLocus.controls.breakout = {
|
|
2279
|
+
sessionType: 'BREAKOUT',
|
|
2280
|
+
};
|
|
2281
|
+
newLocus.self.state = 'JOINED';
|
|
2282
|
+
newLocus.fullState = {
|
|
2283
|
+
active: true,
|
|
2284
|
+
};
|
|
2285
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2286
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
2287
|
+
assert.equal(result, true);
|
|
2288
|
+
assert.calledWith(
|
|
2289
|
+
LoggerProxy.logger.log,
|
|
2290
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
2291
|
+
);
|
|
2292
|
+
});
|
|
2293
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
2294
|
+
newLocus.controls.breakout = {
|
|
2295
|
+
sessionType: 'MAIN',
|
|
2296
|
+
};
|
|
2297
|
+
newLocus.self.state = 'JOINED';
|
|
2298
|
+
|
|
2299
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2300
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2301
|
+
assert.equal(result, true);
|
|
2302
|
+
assert.calledWith(
|
|
2303
|
+
LoggerProxy.logger.log,
|
|
2304
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
2305
|
+
);
|
|
2306
|
+
});
|
|
2307
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
2308
|
+
newLocus.controls.breakout = {
|
|
2309
|
+
sessionType: 'BREAKOUT',
|
|
2310
|
+
};
|
|
2311
|
+
newLocus.self.state = 'LEFT';
|
|
2312
|
+
newLocus.self.reason = 'MOVED';
|
|
2313
|
+
|
|
2314
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2315
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2316
|
+
assert.equal(result, false);
|
|
2317
|
+
});
|
|
2318
|
+
});
|
|
2319
|
+
|
|
2320
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
2321
|
+
let locus;
|
|
2322
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
2323
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
2324
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
2325
|
+
if (key === keyWillReturnMeeting) {
|
|
2326
|
+
return mockReturnMeeting;
|
|
2327
|
+
}
|
|
2328
|
+
return null;
|
|
2329
|
+
});
|
|
2330
|
+
};
|
|
2331
|
+
|
|
2332
|
+
beforeEach(() => {
|
|
2333
|
+
locus = {
|
|
2334
|
+
controls: {},
|
|
2335
|
+
self: {
|
|
2336
|
+
callbackInfo: {
|
|
2337
|
+
callbackAddress: 'address1',
|
|
2338
|
+
},
|
|
2339
|
+
},
|
|
2340
|
+
info: {
|
|
2341
|
+
webExMeetingId: '123456',
|
|
2342
|
+
isUnifiedSpaceMeeting: false,
|
|
2343
|
+
},
|
|
2344
|
+
conversationUrl: 'conversationUrl1',
|
|
2345
|
+
};
|
|
2346
|
+
|
|
2347
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
2348
|
+
});
|
|
2349
|
+
afterEach(() => {
|
|
2350
|
+
sinon.restore();
|
|
2351
|
+
});
|
|
2352
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
2353
|
+
mockGetByKey();
|
|
2354
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2355
|
+
assert.isNull(result);
|
|
2356
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2357
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2358
|
+
assert.calledWith(
|
|
2359
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2360
|
+
'correlationId',
|
|
2361
|
+
'correlationId1'
|
|
2362
|
+
);
|
|
2363
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2364
|
+
assert.calledWith(
|
|
2365
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2366
|
+
'conversationUrl',
|
|
2367
|
+
'conversationUrl1'
|
|
2368
|
+
);
|
|
2369
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2370
|
+
});
|
|
2371
|
+
|
|
2372
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
2373
|
+
mockGetByKey();
|
|
2374
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
2375
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2376
|
+
assert.isNull(result);
|
|
2377
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2378
|
+
});
|
|
2379
|
+
|
|
2380
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
2381
|
+
mockGetByKey('locusUrl');
|
|
2382
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2383
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2384
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
2385
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2386
|
+
});
|
|
2387
|
+
|
|
2388
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
2389
|
+
mockGetByKey('correlationId');
|
|
2390
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2391
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2392
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
2393
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2394
|
+
assert.calledWith(
|
|
2395
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2396
|
+
'correlationId',
|
|
2397
|
+
'correlationId1'
|
|
2398
|
+
);
|
|
2399
|
+
});
|
|
2400
|
+
|
|
2401
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
2402
|
+
mockGetByKey('sipUri');
|
|
2403
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2404
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2405
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
2406
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2407
|
+
assert.calledWith(
|
|
2408
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2409
|
+
'correlationId',
|
|
2410
|
+
'correlationId1'
|
|
2411
|
+
);
|
|
2412
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2413
|
+
});
|
|
2414
|
+
|
|
2415
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
2416
|
+
mockGetByKey('conversationUrl');
|
|
2417
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2418
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2419
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2420
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2421
|
+
assert.calledWith(
|
|
2422
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2423
|
+
'correlationId',
|
|
2424
|
+
'correlationId1'
|
|
2425
|
+
);
|
|
2426
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2427
|
+
assert.calledWith(
|
|
2428
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2429
|
+
'conversationUrl',
|
|
2430
|
+
'conversationUrl1'
|
|
2431
|
+
);
|
|
2432
|
+
});
|
|
2433
|
+
|
|
2434
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
2435
|
+
mockGetByKey('meetingNumber');
|
|
2436
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2437
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2438
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2439
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2440
|
+
assert.calledWith(
|
|
2441
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2442
|
+
'correlationId',
|
|
2443
|
+
'correlationId1'
|
|
2444
|
+
);
|
|
2445
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2446
|
+
assert.calledWith(
|
|
2447
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2448
|
+
'conversationUrl',
|
|
2449
|
+
'conversationUrl1'
|
|
2450
|
+
);
|
|
2451
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2452
|
+
});
|
|
2453
|
+
});
|
|
2454
|
+
|
|
2455
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
2456
|
+
let lociArray;
|
|
2457
|
+
let mainLocus;
|
|
2458
|
+
let breakoutLocus;
|
|
2459
|
+
beforeEach(() => {
|
|
2460
|
+
mainLocus = {
|
|
2461
|
+
url: 'mainUrl1',
|
|
2462
|
+
controls: {
|
|
2463
|
+
breakout: {
|
|
2464
|
+
sessionType: 'MAIN',
|
|
2465
|
+
url: 'breakoutUnifiedUrl1',
|
|
2466
|
+
},
|
|
2467
|
+
},
|
|
2468
|
+
};
|
|
2469
|
+
breakoutLocus = {
|
|
2470
|
+
url: 'breakoutUrl1',
|
|
2471
|
+
controls: {
|
|
2472
|
+
breakout: {
|
|
2473
|
+
sessionType: 'BREAKOUT',
|
|
2474
|
+
url: 'breakoutUnifiedUrl1',
|
|
2475
|
+
},
|
|
2476
|
+
},
|
|
2477
|
+
};
|
|
2478
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2479
|
+
|
|
2480
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2481
|
+
return locus.url === 'breakoutUrl1';
|
|
2482
|
+
});
|
|
2483
|
+
});
|
|
2484
|
+
afterEach(() => {
|
|
2485
|
+
sinon.restore();
|
|
2486
|
+
});
|
|
2487
|
+
|
|
2488
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2489
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2490
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2491
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2492
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2493
|
+
});
|
|
2494
|
+
|
|
2495
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2496
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2497
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2498
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2499
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2500
|
+
});
|
|
2501
|
+
|
|
2502
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2503
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2504
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2505
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2506
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2507
|
+
});
|
|
2508
|
+
});
|
|
2509
|
+
|
|
2510
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2511
|
+
let breakoutLocus;
|
|
2512
|
+
beforeEach(() => {
|
|
2513
|
+
breakoutLocus = {
|
|
2514
|
+
url: 'breakoutUrl1',
|
|
2515
|
+
controls: {
|
|
2516
|
+
breakout: {
|
|
2517
|
+
sessionType: 'BREAKOUT',
|
|
2518
|
+
url: 'breakoutUnifiedUrl1',
|
|
2519
|
+
},
|
|
2520
|
+
},
|
|
2521
|
+
};
|
|
2522
|
+
|
|
2523
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2524
|
+
});
|
|
2525
|
+
afterEach(() => {
|
|
2526
|
+
sinon.restore();
|
|
2527
|
+
});
|
|
2528
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2529
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2530
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2531
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2532
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2533
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2534
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2535
|
+
});
|
|
2536
|
+
|
|
2537
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2538
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2539
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2540
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2541
|
+
});
|
|
2542
|
+
|
|
2543
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2544
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2545
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2546
|
+
controls: {
|
|
2547
|
+
breakout: {
|
|
2548
|
+
sessionType: 'MAIN',
|
|
2549
|
+
url: 'breakoutUnifiedUrl2',
|
|
2550
|
+
},
|
|
2551
|
+
},
|
|
2552
|
+
});
|
|
2553
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2554
|
+
});
|
|
2555
|
+
|
|
2556
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2557
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2558
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2559
|
+
controls: {
|
|
2560
|
+
breakout: {
|
|
2561
|
+
sessionType: 'MAIN',
|
|
2562
|
+
url: 'breakoutUnifiedUrl1',
|
|
2563
|
+
},
|
|
2564
|
+
},
|
|
2565
|
+
});
|
|
2566
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {
|
|
2567
|
+
locus: breakoutLocus,
|
|
2568
|
+
locusUrl: breakoutLocus.url,
|
|
2569
|
+
});
|
|
2570
|
+
});
|
|
2571
|
+
});
|
|
2572
|
+
|
|
2573
|
+
describe('uploading of logs', () => {
|
|
2574
|
+
let metricsSpy;
|
|
2575
|
+
let meeting;
|
|
2576
|
+
|
|
2577
|
+
beforeEach(async () => {
|
|
2578
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2579
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2580
|
+
|
|
2581
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2582
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2583
|
+
|
|
2584
|
+
triggerProxyStub.restore();
|
|
2585
|
+
|
|
2586
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2587
|
+
|
|
2588
|
+
meeting = await webex.meetings.create('test');
|
|
2589
|
+
|
|
2590
|
+
meeting.locusId = 'locus id';
|
|
2591
|
+
meeting.correlationId = 'correlation id';
|
|
2592
|
+
meeting.locusInfo = {
|
|
2593
|
+
fullState: {lastActive: 'last active', sessionId: 'locus session id'},
|
|
2594
|
+
info: {webExMeetingId: 'meeting id'},
|
|
2595
|
+
};
|
|
2596
|
+
});
|
|
2597
|
+
|
|
2598
|
+
afterEach(() => {
|
|
2599
|
+
sinon.restore();
|
|
2600
|
+
});
|
|
2601
|
+
|
|
2602
|
+
it('sends metrics on success', async () => {
|
|
2603
|
+
await meeting.uploadLogs();
|
|
2604
|
+
|
|
2605
|
+
await testUtils.flushPromises();
|
|
2606
|
+
|
|
2607
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2608
|
+
callStart: 'last active',
|
|
2609
|
+
correlationId: 'correlation id',
|
|
2610
|
+
feedbackId: 'correlation id',
|
|
2611
|
+
locusId: 'locus id',
|
|
2612
|
+
meetingId: 'meeting id',
|
|
2613
|
+
autoupload: true,
|
|
2614
|
+
locussessionid: 'locus session id',
|
|
2615
|
+
});
|
|
2616
|
+
});
|
|
2617
|
+
|
|
2618
|
+
it('sends metrics on failure', async () => {
|
|
2619
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2620
|
+
|
|
2621
|
+
await meeting.uploadLogs();
|
|
2622
|
+
|
|
2623
|
+
await testUtils.flushPromises();
|
|
2624
|
+
|
|
2625
|
+
assert.calledOnceWithExactly(
|
|
2626
|
+
metricsSpy,
|
|
2627
|
+
'js_sdk_upload_logs_failure',
|
|
2628
|
+
sinon.match({
|
|
2629
|
+
callStart: 'last active',
|
|
2630
|
+
correlationId: 'correlation id',
|
|
2631
|
+
feedbackId: 'correlation id',
|
|
2632
|
+
locusId: 'locus id',
|
|
2633
|
+
meetingId: 'meeting id',
|
|
2634
|
+
reason: 'fake error',
|
|
2635
|
+
autoupload: true,
|
|
2636
|
+
locussessionid: 'locus session id',
|
|
2637
|
+
})
|
|
2638
|
+
);
|
|
2639
|
+
});
|
|
2640
|
+
});
|
|
1189
2641
|
});
|
|
1190
2642
|
});
|