@webex/plugin-meetings 3.0.0-beta.3 → 3.0.0-beta.300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -8
- package/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 +9 -15
- package/dist/config.js.map +1 -1
- package/dist/constants.js +315 -68
- 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 +114 -17
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +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 +561 -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 +68 -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 +103 -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 +505 -495
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +93 -14
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +4624 -3740
- 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 +249 -184
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +400 -346
- 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 +598 -586
- package/dist/meeting/util.js.map +1 -1
- 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 +349 -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 +98 -183
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +143 -234
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +26 -19
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +813 -596
- 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 +183 -156
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +135 -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 +14 -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 +66 -43
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +536 -439
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/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/index.js +322 -200
- 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/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 +388 -476
- 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 +99 -94
- 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 +151 -101
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.js +1 -95
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +416 -497
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +145 -88
- 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 +71 -0
- package/dist/types/constants.d.ts +1066 -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/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 +273 -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 +365 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +163 -0
- package/dist/types/meeting/index.d.ts +1676 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +184 -0
- package/dist/types/meeting/request.d.ts +290 -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 +102 -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 +31 -0
- package/dist/types/meetings/index.d.ts +367 -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 +65 -0
- package/dist/types/metrics/index.d.ts +45 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +118 -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 +47 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +285 -0
- package/dist/types/multistream/sendSlotManager.d.ts +61 -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/index.d.ts +194 -0
- package/dist/types/reachability/request.d.ts +39 -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 +126 -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 +78 -0
- package/dist/types/roap/request.d.ts +39 -0
- package/dist/types/roap/turnDiscovery.d.ts +92 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +47 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +201 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -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 +29 -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} +18 -19
- package/src/constants.ts +260 -22
- 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 +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +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} +557 -119
- package/src/locus-info/{infoUtils.js → infoUtils.ts} +29 -10
- package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +81 -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 +458 -0
- package/src/media/properties.ts +283 -0
- package/src/media/{util.js → util.ts} +2 -2
- package/src/mediaQualityMetrics/config.ts +384 -0
- package/src/meeting/in-meeting-actions.ts +191 -3
- package/src/meeting/index.ts +7882 -0
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +451 -0
- package/src/meeting/{request.js → request.ts} +421 -220
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/{state.js → state.ts} +50 -35
- package/src/meeting/util.ts +697 -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 +429 -0
- package/src/meeting-info/{request.js → request.ts} +14 -4
- package/src/meeting-info/{util.js → util.ts} +60 -51
- package/src/meeting-info/{utilv2.js → utilv2.ts} +78 -71
- package/src/meetings/{collection.js → collection.ts} +26 -3
- package/src/meetings/index.ts +1470 -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} +132 -37
- package/src/member/{index.js → index.ts} +160 -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} +12 -6
- package/src/metrics/index.ts +73 -0
- package/src/multistream/mediaRequestManager.ts +337 -63
- 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 +63 -3
- package/src/multistream/remoteMediaManager.ts +300 -66
- package/src/multistream/sendSlotManager.ts +170 -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/index.ts +671 -0
- package/src/reachability/request.ts +50 -35
- 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.js → index.ts} +258 -138
- 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.js → index.ts} +127 -79
- package/src/roap/request.ts +153 -0
- package/src/roap/turnDiscovery.ts +109 -47
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/global.ts +37 -0
- package/src/statsAnalyzer/index.ts +1250 -0
- package/src/statsAnalyzer/mqaUtil.ts +292 -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 +790 -530
- 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 +237 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1790 -0
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/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/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +325 -32
- package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
- package/test/unit/spec/locus-info/index.js +1390 -17
- 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 +32 -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 +296 -12
- package/test/unit/spec/media/index.ts +128 -77
- package/test/unit/spec/media/properties.ts +11 -11
- package/test/unit/spec/meeting/in-meeting-actions.ts +92 -3
- package/test/unit/spec/meeting/index.js +7433 -2752
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +420 -211
- package/test/unit/spec/meeting/request.js +545 -79
- package/test/unit/spec/meeting/utils.js +722 -174
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +624 -76
- 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 +15 -1
- package/test/unit/spec/meetings/index.js +1365 -377
- package/test/unit/spec/meetings/utils.js +216 -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 +12 -66
- package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
- 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 +271 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +738 -65
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -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/index.ts +598 -26
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +181 -12
- package/test/unit/spec/recording-controller/index.js +307 -0
- package/test/unit/spec/recording-controller/util.js +229 -0
- package/test/unit/spec/roap/index.ts +179 -64
- package/test/unit/spec/roap/request.ts +232 -0
- package/test/unit/spec/roap/turnDiscovery.ts +123 -58
- package/test/unit/spec/rtcMetrics/index.ts +73 -0
- package/test/unit/spec/stats-analyzer/index.js +199 -60
- 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 +57 -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/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/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/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
|
@@ -11,6 +11,7 @@ import sinon from 'sinon';
|
|
|
11
11
|
import uuid from 'uuid';
|
|
12
12
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
13
13
|
import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
14
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
14
15
|
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
15
16
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
16
17
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
@@ -19,6 +20,7 @@ import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
|
19
20
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
20
21
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
21
22
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
23
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
22
24
|
|
|
23
25
|
import testUtils from '../../../utils/testUtils';
|
|
24
26
|
import {
|
|
@@ -27,8 +29,14 @@ import {
|
|
|
27
29
|
ONLINE,
|
|
28
30
|
ROAP,
|
|
29
31
|
LOCUSINFO,
|
|
30
|
-
EVENT_TRIGGERS
|
|
32
|
+
EVENT_TRIGGERS,
|
|
31
33
|
} from '../../../../src/constants';
|
|
34
|
+
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
|
|
35
|
+
import { forEach } from 'lodash';
|
|
36
|
+
import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
|
|
37
|
+
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
38
|
+
import {NoiseReductionEffect,VirtualBackgroundEffect} from '@webex/media-helpers';
|
|
39
|
+
import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
|
|
32
40
|
|
|
33
41
|
describe('plugin-meetings', () => {
|
|
34
42
|
const logger = {
|
|
@@ -37,19 +45,23 @@ describe('plugin-meetings', () => {
|
|
|
37
45
|
error: () => {},
|
|
38
46
|
warn: () => {},
|
|
39
47
|
trace: () => {},
|
|
40
|
-
debug: () => {}
|
|
48
|
+
debug: () => {},
|
|
41
49
|
};
|
|
42
50
|
|
|
51
|
+
let triggerProxyStub;
|
|
52
|
+
|
|
43
53
|
beforeEach(() => {
|
|
44
54
|
StaticConfig.set({
|
|
45
55
|
bandwidth: {
|
|
46
|
-
audio: 50,
|
|
47
|
-
|
|
56
|
+
audio: 50,
|
|
57
|
+
video: 500,
|
|
58
|
+
},
|
|
48
59
|
});
|
|
49
60
|
LoggerConfig.set({
|
|
50
|
-
verboseEvents: true,
|
|
61
|
+
verboseEvents: true,
|
|
62
|
+
enable: false,
|
|
51
63
|
});
|
|
52
|
-
|
|
64
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
53
65
|
});
|
|
54
66
|
|
|
55
67
|
let webex;
|
|
@@ -58,26 +70,30 @@ describe('plugin-meetings', () => {
|
|
|
58
70
|
let url1;
|
|
59
71
|
let test1;
|
|
60
72
|
let test2;
|
|
73
|
+
let locusInfo;
|
|
61
74
|
|
|
62
75
|
describe('meetings index', () => {
|
|
63
76
|
beforeEach(() => {
|
|
64
77
|
MeetingsUtil.checkH264Support = sinon.stub();
|
|
65
|
-
|
|
78
|
+
uuid1 = uuid.v4();
|
|
66
79
|
url1 = `https://example.com/${uuid.v4()}`;
|
|
67
80
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
68
81
|
test1 = `test-${uuid.v4()}`;
|
|
69
82
|
test2 = `test2-${uuid.v4()}`;
|
|
83
|
+
locusInfo = {
|
|
84
|
+
parse: sinon.stub().returns(true),
|
|
85
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
86
|
+
};
|
|
70
87
|
webex = new MockWebex({
|
|
71
88
|
children: {
|
|
72
89
|
device: Device,
|
|
73
90
|
mercury: Mercury,
|
|
74
|
-
meetings: Meetings
|
|
75
|
-
}
|
|
91
|
+
meetings: Meetings,
|
|
92
|
+
},
|
|
76
93
|
});
|
|
77
94
|
|
|
78
|
-
|
|
79
95
|
Object.assign(webex, {
|
|
80
|
-
logging: logger
|
|
96
|
+
logging: logger,
|
|
81
97
|
});
|
|
82
98
|
|
|
83
99
|
Object.assign(webex.meetings.config, {
|
|
@@ -86,68 +102,74 @@ describe('plugin-meetings', () => {
|
|
|
86
102
|
// the server supports, minimums have to be tested
|
|
87
103
|
audio: 64000,
|
|
88
104
|
video: 4000000,
|
|
89
|
-
startBitrate: 2000
|
|
105
|
+
startBitrate: 2000,
|
|
90
106
|
},
|
|
91
107
|
experimental: {
|
|
92
|
-
enableUnifiedMeetings: true
|
|
108
|
+
enableUnifiedMeetings: true,
|
|
93
109
|
},
|
|
94
110
|
logging: {
|
|
95
111
|
enable: true,
|
|
96
|
-
verboseEvents: true
|
|
97
|
-
}
|
|
112
|
+
verboseEvents: true,
|
|
113
|
+
},
|
|
98
114
|
});
|
|
99
115
|
|
|
100
116
|
Object.assign(webex, {
|
|
101
|
-
logger
|
|
117
|
+
logger,
|
|
102
118
|
});
|
|
103
119
|
|
|
104
120
|
Object.assign(webex.meetings, {
|
|
105
|
-
startReachability: sinon.stub().returns(Promise.resolve())
|
|
121
|
+
startReachability: sinon.stub().returns(Promise.resolve()),
|
|
106
122
|
});
|
|
107
123
|
|
|
108
124
|
Object.assign(webex.internal, {
|
|
125
|
+
llm: {on: sinon.stub()},
|
|
109
126
|
device: {
|
|
110
127
|
deviceType: 'FAKE_DEVICE',
|
|
111
128
|
register: sinon.stub().returns(Promise.resolve()),
|
|
112
|
-
unregister: sinon.stub().returns(Promise.resolve())
|
|
129
|
+
unregister: sinon.stub().returns(Promise.resolve()),
|
|
113
130
|
},
|
|
114
131
|
mercury: {
|
|
115
132
|
connect: sinon.stub().returns(Promise.resolve()),
|
|
116
133
|
disconnect: sinon.stub().returns(Promise.resolve()),
|
|
117
134
|
on: () => {},
|
|
118
|
-
off: () => {}
|
|
135
|
+
off: () => {},
|
|
119
136
|
},
|
|
120
137
|
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
|
-
|
|
138
|
+
getMeetingPreferences: sinon.stub().returns(
|
|
139
|
+
Promise.resolve({
|
|
140
|
+
sites: [
|
|
141
|
+
{
|
|
142
|
+
siteUrl: 'site1-example.webex.com',
|
|
143
|
+
default: false,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
siteUrl: 'site2-example.webex.com',
|
|
147
|
+
default: false,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
siteUrl: 'site3-example.webex.com',
|
|
151
|
+
default: false,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
siteUrl: 'go.webex.com',
|
|
155
|
+
default: true,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
})
|
|
159
|
+
),
|
|
160
|
+
fetchClientRegionInfo: sinon.stub().returns(Promise.resolve()),
|
|
142
161
|
},
|
|
143
162
|
metrics: {
|
|
144
|
-
submitClientMetrics: sinon.stub().returns(Promise.resolve())
|
|
145
|
-
}
|
|
146
|
-
|
|
163
|
+
submitClientMetrics: sinon.stub().returns(Promise.resolve()),
|
|
164
|
+
},
|
|
147
165
|
});
|
|
148
166
|
webex.emit('ready');
|
|
149
167
|
});
|
|
150
168
|
|
|
169
|
+
afterEach(() => {
|
|
170
|
+
sinon.restore();
|
|
171
|
+
});
|
|
172
|
+
|
|
151
173
|
it('has a webex instance with a meetings property', () => {
|
|
152
174
|
assert.exists(webex, 'webex was initialized with children');
|
|
153
175
|
assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
|
|
@@ -177,10 +199,14 @@ describe('plugin-meetings', () => {
|
|
|
177
199
|
|
|
178
200
|
describe('failure', () => {
|
|
179
201
|
it('should not accept non boolean input', () => {
|
|
180
|
-
const currentEnableUnifiedMeetings =
|
|
202
|
+
const currentEnableUnifiedMeetings =
|
|
203
|
+
webex.meetings.config.experimental.enableUnifiedMeetings;
|
|
181
204
|
|
|
182
205
|
webex.meetings._toggleUnifiedMeetings('test');
|
|
183
|
-
assert.equal(
|
|
206
|
+
assert.equal(
|
|
207
|
+
webex.meetings.config.experimental.enableUnifiedMeetings,
|
|
208
|
+
currentEnableUnifiedMeetings
|
|
209
|
+
);
|
|
184
210
|
});
|
|
185
211
|
});
|
|
186
212
|
});
|
|
@@ -202,43 +228,25 @@ describe('plugin-meetings', () => {
|
|
|
202
228
|
const currentEnableAdhocMeetings = webex.meetings.config.experimental.enableAdhocMeetings;
|
|
203
229
|
|
|
204
230
|
webex.meetings._toggleAdhocMeetings('test');
|
|
205
|
-
assert.equal(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
describe('#_toggleTurnDiscovery', () => {
|
|
211
|
-
it('should have toggleAdhocMeetings', () => {
|
|
212
|
-
assert.equal(typeof webex.meetings._toggleTurnDiscovery, 'function');
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('success', () => {
|
|
216
|
-
it('should update meetings to do TURN discovery', () => {
|
|
217
|
-
webex.meetings._toggleTurnDiscovery(true);
|
|
218
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, true);
|
|
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);
|
|
231
|
+
assert.equal(
|
|
232
|
+
webex.meetings.config.experimental.enableAdhocMeetings,
|
|
233
|
+
currentEnableAdhocMeetings
|
|
234
|
+
);
|
|
231
235
|
});
|
|
232
236
|
});
|
|
233
237
|
});
|
|
234
238
|
|
|
235
|
-
|
|
236
239
|
describe('Public API Contracts', () => {
|
|
237
240
|
describe('#register', () => {
|
|
238
241
|
it('emits an event and resolves when register succeeds', async () => {
|
|
239
242
|
webex.canAuthorize = true;
|
|
240
243
|
await webex.meetings.register();
|
|
241
|
-
assert.calledWith(
|
|
244
|
+
assert.calledWith(
|
|
245
|
+
TriggerProxy.trigger,
|
|
246
|
+
sinon.match.instanceOf(Meetings),
|
|
247
|
+
{file: 'meetings', function: 'register'},
|
|
248
|
+
'meetings:registered'
|
|
249
|
+
);
|
|
242
250
|
assert.isTrue(webex.meetings.registered);
|
|
243
251
|
});
|
|
244
252
|
|
|
@@ -284,9 +292,15 @@ describe('plugin-meetings', () => {
|
|
|
284
292
|
it('emits an event and resolves when unregister succeeds', (done) => {
|
|
285
293
|
webex.meetings.registered = true;
|
|
286
294
|
webex.meetings.unregister().then(() => {
|
|
287
|
-
assert.calledWith(
|
|
288
|
-
|
|
289
|
-
|
|
295
|
+
assert.calledWith(
|
|
296
|
+
TriggerProxy.trigger,
|
|
297
|
+
sinon.match.instanceOf(Meetings),
|
|
298
|
+
{
|
|
299
|
+
file: 'meetings',
|
|
300
|
+
function: 'unregister',
|
|
301
|
+
},
|
|
302
|
+
'meetings:unregistered'
|
|
303
|
+
);
|
|
290
304
|
assert.isFalse(webex.meetings.registered);
|
|
291
305
|
done();
|
|
292
306
|
});
|
|
@@ -315,31 +329,113 @@ describe('plugin-meetings', () => {
|
|
|
315
329
|
});
|
|
316
330
|
});
|
|
317
331
|
|
|
332
|
+
describe('virtual background effect', () => {
|
|
333
|
+
beforeEach(() => {
|
|
334
|
+
webex.credentials = {
|
|
335
|
+
supertoken: {
|
|
336
|
+
access_token: "fake_token"
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
it('creates background effect', async () => {
|
|
342
|
+
const result = await webex.meetings.createVirtualBackgroundEffect();
|
|
343
|
+
|
|
344
|
+
assert.exists(result);
|
|
345
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
346
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
347
|
+
assert.deepEqual(result.options, {
|
|
348
|
+
mode: 'BLUR',
|
|
349
|
+
blurStrength: 'STRONG',
|
|
350
|
+
generator: 'worker',
|
|
351
|
+
quality: 'LOW',
|
|
352
|
+
authToken: 'fake_token',
|
|
353
|
+
mirror: false
|
|
354
|
+
});
|
|
355
|
+
assert.exists(result.enable);
|
|
356
|
+
assert.exists(result.disable);
|
|
357
|
+
assert.exists(result.dispose);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it('creates background effect with custom options passed', async () => {
|
|
361
|
+
const effectOptions = {
|
|
362
|
+
generator: "local",
|
|
363
|
+
frameRate: 45,
|
|
364
|
+
mode: "IMAGE",
|
|
365
|
+
mirror: false,
|
|
366
|
+
quality: "HIGH",
|
|
367
|
+
blurStrength: "STRONG",
|
|
368
|
+
bgImageUrl: "https://test.webex.com/landscape.5a535788.jpg",
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const result = await webex.meetings.createVirtualBackgroundEffect(effectOptions);
|
|
372
|
+
|
|
373
|
+
assert.exists(result);
|
|
374
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
375
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
376
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: "fake_token"});
|
|
377
|
+
assert.exists(result.enable);
|
|
378
|
+
assert.exists(result.disable);
|
|
379
|
+
assert.exists(result.dispose);
|
|
380
|
+
});
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
describe('noise reduction effect', () => {
|
|
384
|
+
beforeEach(() => {
|
|
385
|
+
webex.credentials = {
|
|
386
|
+
supertoken: {
|
|
387
|
+
access_token: "fake_token"
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
it('creates noise reduction effect', async () => {
|
|
393
|
+
const result = await webex.meetings.createNoiseReductionEffect({audioContext: {}});
|
|
394
|
+
|
|
395
|
+
assert.exists(result);
|
|
396
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
397
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
398
|
+
assert.deepEqual(result.options, {
|
|
399
|
+
authToken: 'fake_token',
|
|
400
|
+
audioContext: {}
|
|
401
|
+
});
|
|
402
|
+
assert.exists(result.enable);
|
|
403
|
+
assert.exists(result.disable);
|
|
404
|
+
assert.exists(result.dispose);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it('creates noise reduction effect with custom options passed', async () => {
|
|
408
|
+
const effectOptions = {
|
|
409
|
+
audioContext: {},
|
|
410
|
+
mode: "WORKLET",
|
|
411
|
+
env: "prod"
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
const result = await webex.meetings.createNoiseReductionEffect(effectOptions);
|
|
415
|
+
|
|
416
|
+
assert.exists(result);
|
|
417
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
418
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
419
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: "fake_token"});
|
|
420
|
+
assert.exists(result.enable);
|
|
421
|
+
assert.exists(result.disable);
|
|
422
|
+
assert.exists(result.dispose);
|
|
423
|
+
});
|
|
424
|
+
})
|
|
425
|
+
|
|
318
426
|
describe('gets', () => {
|
|
319
427
|
describe('#getReachability', () => {
|
|
320
428
|
it('should have #getReachability', () => {
|
|
321
429
|
assert.exists(webex.meetings.getReachability);
|
|
322
430
|
});
|
|
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();
|
|
431
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
432
|
+
const reachability = webex.meetings.getReachability();
|
|
334
433
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
assert.exists(reachability, 'reachability is defined because #setReachability has been called');
|
|
341
|
-
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
342
|
-
});
|
|
434
|
+
assert.exists(
|
|
435
|
+
reachability,
|
|
436
|
+
'reachability is defined'
|
|
437
|
+
);
|
|
438
|
+
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
343
439
|
});
|
|
344
440
|
});
|
|
345
441
|
describe('#getPersonalMeetingRoom', () => {
|
|
@@ -349,8 +445,15 @@ describe('plugin-meetings', () => {
|
|
|
349
445
|
it('gets the personal meeting room instance from webex.meetings', () => {
|
|
350
446
|
const personalMeetingRoom = webex.meetings.getPersonalMeetingRoom();
|
|
351
447
|
|
|
352
|
-
assert.exists(
|
|
353
|
-
|
|
448
|
+
assert.exists(
|
|
449
|
+
personalMeetingRoom,
|
|
450
|
+
'personal meeting room instance is set up at object creation'
|
|
451
|
+
);
|
|
452
|
+
assert.instanceOf(
|
|
453
|
+
personalMeetingRoom,
|
|
454
|
+
PersonalMeetingRoom,
|
|
455
|
+
'should be a personal meeting room instance'
|
|
456
|
+
);
|
|
354
457
|
});
|
|
355
458
|
});
|
|
356
459
|
describe('Static shortcut proxy methods', () => {
|
|
@@ -379,11 +482,11 @@ describe('plugin-meetings', () => {
|
|
|
379
482
|
describe('#getAllMeetings', () => {
|
|
380
483
|
it('calls MeetingCollection to get all meetings with supplied options', () => {
|
|
381
484
|
webex.meetings.getAllMeetings({
|
|
382
|
-
test: test1
|
|
485
|
+
test: test1,
|
|
383
486
|
});
|
|
384
487
|
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
385
488
|
assert.calledWith(webex.meetings.meetingCollection.getAll, {
|
|
386
|
-
test: test1
|
|
489
|
+
test: test1,
|
|
387
490
|
});
|
|
388
491
|
});
|
|
389
492
|
});
|
|
@@ -396,28 +499,28 @@ describe('plugin-meetings', () => {
|
|
|
396
499
|
});
|
|
397
500
|
describe('succesful requests', () => {
|
|
398
501
|
beforeEach(() => {
|
|
399
|
-
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
502
|
+
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
503
|
+
Promise.resolve({
|
|
504
|
+
loci: [
|
|
505
|
+
{
|
|
506
|
+
url: url1,
|
|
507
|
+
},
|
|
508
|
+
],
|
|
509
|
+
})
|
|
510
|
+
);
|
|
404
511
|
});
|
|
405
512
|
describe('when meeting is returned', () => {
|
|
406
|
-
let parse;
|
|
407
513
|
|
|
408
514
|
beforeEach(() => {
|
|
409
|
-
parse = sinon.stub().returns(true);
|
|
410
515
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
411
|
-
locusInfo
|
|
412
|
-
parse
|
|
413
|
-
}
|
|
516
|
+
locusInfo,
|
|
414
517
|
});
|
|
415
518
|
});
|
|
416
519
|
it('tests the sync meeting calls for existing meeting', async () => {
|
|
417
520
|
await webex.meetings.syncMeetings();
|
|
418
521
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
419
522
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
420
|
-
assert.calledOnce(parse);
|
|
523
|
+
assert.calledOnce(locusInfo.parse);
|
|
421
524
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
422
525
|
});
|
|
423
526
|
});
|
|
@@ -427,25 +530,32 @@ describe('plugin-meetings', () => {
|
|
|
427
530
|
beforeEach(() => {
|
|
428
531
|
initialSetup = sinon.stub().returns(true);
|
|
429
532
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(null);
|
|
430
|
-
webex.meetings.create = sinon.stub().returns(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
533
|
+
webex.meetings.create = sinon.stub().returns(
|
|
534
|
+
Promise.resolve({
|
|
535
|
+
locusInfo: {
|
|
536
|
+
...locusInfo,
|
|
537
|
+
initialSetup,
|
|
538
|
+
},
|
|
539
|
+
})
|
|
540
|
+
);
|
|
435
541
|
});
|
|
436
542
|
it('tests the sync meeting calls for not existing meeting', async () => {
|
|
437
543
|
await webex.meetings.syncMeetings();
|
|
438
544
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
439
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
545
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
440
546
|
assert.calledOnce(initialSetup);
|
|
441
547
|
assert.calledOnce(webex.meetings.create);
|
|
442
548
|
assert.calledWith(webex.meetings.request.getActiveMeetings);
|
|
443
549
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
444
|
-
assert.calledWith(
|
|
445
|
-
|
|
446
|
-
|
|
550
|
+
assert.calledWith(
|
|
551
|
+
webex.meetings.create,
|
|
552
|
+
{
|
|
553
|
+
url: url1,
|
|
554
|
+
},
|
|
555
|
+
'LOCUS_ID'
|
|
556
|
+
);
|
|
447
557
|
assert.calledWith(initialSetup, {
|
|
448
|
-
url: url1
|
|
558
|
+
url: url1,
|
|
449
559
|
});
|
|
450
560
|
});
|
|
451
561
|
});
|
|
@@ -456,28 +566,30 @@ describe('plugin-meetings', () => {
|
|
|
456
566
|
|
|
457
567
|
beforeEach(() => {
|
|
458
568
|
destroySpy = sinon.spy(webex.meetings, 'destroy');
|
|
459
|
-
parse = sinon.stub().returns(true);
|
|
460
569
|
initialSetup = sinon.stub().returns(true);
|
|
461
570
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
462
|
-
locusInfo
|
|
463
|
-
|
|
464
|
-
},
|
|
465
|
-
sendCallAnalyzerMetrics: sinon.stub()
|
|
571
|
+
locusInfo,
|
|
572
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
466
573
|
});
|
|
467
574
|
webex.meetings.meetingCollection.getAll = sinon.stub().returns({
|
|
468
575
|
meetingutk: {
|
|
469
|
-
locusUrl: 'fdfdjfdhj',
|
|
470
|
-
|
|
471
|
-
});
|
|
472
|
-
webex.meetings.create = sinon.stub().returns(Promise.resolve({
|
|
473
|
-
locusInfo: {
|
|
474
|
-
initialSetup
|
|
576
|
+
locusUrl: 'fdfdjfdhj',
|
|
577
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
475
578
|
},
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
579
|
+
});
|
|
580
|
+
webex.meetings.create = sinon.stub().returns(
|
|
581
|
+
Promise.resolve({
|
|
582
|
+
locusInfo: {
|
|
583
|
+
initialSetup,
|
|
584
|
+
},
|
|
585
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
586
|
+
})
|
|
587
|
+
);
|
|
588
|
+
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
589
|
+
Promise.resolve({
|
|
590
|
+
loci: [],
|
|
591
|
+
})
|
|
592
|
+
);
|
|
481
593
|
MeetingUtil.cleanUp = sinon.stub().returns(Promise.resolve());
|
|
482
594
|
});
|
|
483
595
|
it('destroy non active meetings', async () => {
|
|
@@ -499,43 +611,65 @@ describe('plugin-meetings', () => {
|
|
|
499
611
|
beforeEach(() => {
|
|
500
612
|
infoOptions = {
|
|
501
613
|
destination: 'dest-example',
|
|
502
|
-
type: 'CONVERSATION_URL'
|
|
614
|
+
type: 'CONVERSATION_URL',
|
|
503
615
|
};
|
|
504
616
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns();
|
|
505
|
-
webex.meetings.createMeeting = sinon.stub().returns(
|
|
506
|
-
|
|
507
|
-
|
|
617
|
+
webex.meetings.createMeeting = sinon.stub().returns(
|
|
618
|
+
Promise.resolve({
|
|
619
|
+
on: () => true,
|
|
620
|
+
})
|
|
621
|
+
);
|
|
508
622
|
});
|
|
509
623
|
|
|
510
|
-
it('should call MeetingInfo#fetchInfoOptions() with proper params',
|
|
511
|
-
()
|
|
512
|
-
webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(
|
|
513
|
-
infoOptions
|
|
514
|
-
);
|
|
624
|
+
it('should call MeetingInfo#fetchInfoOptions() with proper params', () => {
|
|
625
|
+
webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(infoOptions);
|
|
515
626
|
|
|
516
|
-
|
|
627
|
+
return webex.meetings.create(infoOptions.destination, infoOptions.type).then(() => {
|
|
628
|
+
assert.calledWith(
|
|
629
|
+
webex.meetings.meetingInfo.fetchInfoOptions,
|
|
517
630
|
infoOptions.destination,
|
|
518
631
|
infoOptions.type
|
|
519
|
-
)
|
|
520
|
-
.then(() => {
|
|
521
|
-
assert.calledWith(
|
|
522
|
-
webex.meetings.meetingInfo.fetchInfoOptions,
|
|
523
|
-
infoOptions.destination,
|
|
524
|
-
infoOptions.type
|
|
525
|
-
);
|
|
632
|
+
);
|
|
526
633
|
|
|
527
|
-
|
|
528
|
-
});
|
|
634
|
+
assert.calledTwice(webex.meetings.meetingCollection.getByKey);
|
|
529
635
|
});
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
639
|
+
const correlationId = 'my-correlationId';
|
|
640
|
+
|
|
641
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
642
|
+
const create = webex.meetings.create(...createParameters);
|
|
643
|
+
|
|
644
|
+
assert.exists(create.then);
|
|
645
|
+
await create;
|
|
646
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
647
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
648
|
+
}
|
|
530
649
|
|
|
531
650
|
it('calls createMeeting and returns its promise', async () => {
|
|
532
|
-
|
|
533
|
-
|
|
651
|
+
checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true]);
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
655
|
+
checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]);
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
659
|
+
checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]);
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
663
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
664
|
+
const correlationId = 'my-correlationId';
|
|
665
|
+
|
|
666
|
+
const FAKE_INFO_EXTRA_PARAMS = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
|
|
667
|
+
const create = webex.meetings.create(test1, test2, FAKE_USE_RANDOM_DELAY, FAKE_INFO_EXTRA_PARAMS, correlationId);
|
|
534
668
|
|
|
535
669
|
assert.exists(create.then);
|
|
536
670
|
await create;
|
|
537
671
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
538
|
-
assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY);
|
|
672
|
+
assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY, FAKE_INFO_EXTRA_PARAMS, correlationId);
|
|
539
673
|
});
|
|
540
674
|
|
|
541
675
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -565,9 +699,9 @@ describe('plugin-meetings', () => {
|
|
|
565
699
|
return undefined;
|
|
566
700
|
});
|
|
567
701
|
|
|
568
|
-
webex.meetings.meetingInfo.fetchInfoOptions = sinon
|
|
569
|
-
|
|
570
|
-
|
|
702
|
+
webex.meetings.meetingInfo.fetchInfoOptions = sinon
|
|
703
|
+
.stub()
|
|
704
|
+
.resolves(scheduledMeetingFixture);
|
|
571
705
|
|
|
572
706
|
webex.meetings.meetingCollection.set(scheduledMeetingFixture);
|
|
573
707
|
|
|
@@ -602,99 +736,126 @@ describe('plugin-meetings', () => {
|
|
|
602
736
|
it('doesnt call handle locus mercury for a locus roap event', () => {
|
|
603
737
|
webex.meetings.handleLocusMercury({
|
|
604
738
|
data: {
|
|
605
|
-
eventType: 'locus.message.roap'
|
|
606
|
-
}
|
|
739
|
+
eventType: 'locus.message.roap',
|
|
740
|
+
},
|
|
607
741
|
});
|
|
608
742
|
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
609
743
|
});
|
|
610
744
|
it('doesnt call handle locus mercury for an undefined eventType', () => {
|
|
611
745
|
webex.meetings.handleLocusMercury({
|
|
612
|
-
data: {
|
|
613
|
-
}
|
|
746
|
+
data: {},
|
|
614
747
|
});
|
|
615
748
|
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
616
749
|
});
|
|
617
750
|
it('calls handle locus mercury for all locus events', () => {
|
|
618
751
|
webex.meetings.handleLocusMercury({
|
|
619
752
|
data: {
|
|
620
|
-
eventType: test1
|
|
621
|
-
}
|
|
753
|
+
eventType: test1,
|
|
754
|
+
},
|
|
622
755
|
});
|
|
623
756
|
assert.calledOnce(webex.meetings.handleLocusEvent);
|
|
624
|
-
assert.calledWith(
|
|
625
|
-
|
|
626
|
-
|
|
757
|
+
assert.calledWith(
|
|
758
|
+
webex.meetings.handleLocusEvent,
|
|
759
|
+
{
|
|
760
|
+
eventType: test1,
|
|
761
|
+
},
|
|
762
|
+
true
|
|
763
|
+
);
|
|
627
764
|
});
|
|
628
765
|
});
|
|
629
766
|
describe('#handleLocusEvent', () => {
|
|
630
767
|
describe('there was a meeting', () => {
|
|
631
|
-
let parse;
|
|
632
768
|
|
|
633
769
|
beforeEach(() => {
|
|
634
|
-
parse = sinon.stub().returns(true);
|
|
635
770
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
636
|
-
locusInfo
|
|
637
|
-
parse
|
|
638
|
-
}
|
|
771
|
+
locusInfo,
|
|
639
772
|
});
|
|
640
773
|
});
|
|
641
|
-
it('should parse the meeting info', () => {
|
|
774
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
775
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
642
776
|
webex.meetings.handleLocusEvent({
|
|
643
|
-
locusUrl: url1
|
|
777
|
+
locusUrl: url1,
|
|
644
778
|
});
|
|
645
779
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
646
780
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
647
|
-
assert.calledOnce(parse);
|
|
648
|
-
assert.
|
|
649
|
-
|
|
650
|
-
|
|
781
|
+
assert.calledOnce(locusInfo.parse);
|
|
782
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
783
|
+
assert.calledWith(
|
|
784
|
+
locusInfo.parse,
|
|
785
|
+
{
|
|
786
|
+
locusInfo,
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
locusUrl: url1,
|
|
651
790
|
}
|
|
652
|
-
|
|
653
|
-
|
|
791
|
+
);
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
it('should not update main session locus cache', () => {
|
|
795
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
796
|
+
webex.meetings.handleLocusEvent({
|
|
797
|
+
locusUrl: url1,
|
|
654
798
|
});
|
|
799
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
655
800
|
});
|
|
656
801
|
});
|
|
657
802
|
describe('there was not a meeting', () => {
|
|
658
803
|
let initialSetup;
|
|
804
|
+
const webExMeetingId = '123456';
|
|
659
805
|
|
|
660
806
|
beforeEach(() => {
|
|
661
807
|
initialSetup = sinon.stub().returns(true);
|
|
662
808
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
663
|
-
webex.meetings.create = sinon.stub().returns(
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
809
|
+
webex.meetings.create = sinon.stub().returns(
|
|
810
|
+
Promise.resolve({
|
|
811
|
+
id: 'meeting-id',
|
|
812
|
+
locusInfo: {
|
|
813
|
+
...locusInfo,
|
|
814
|
+
initialSetup,
|
|
815
|
+
},
|
|
816
|
+
})
|
|
817
|
+
);
|
|
668
818
|
});
|
|
669
819
|
it('should setup the meeting by difference event', async () => {
|
|
670
820
|
await webex.meetings.handleLocusEvent({
|
|
671
821
|
locus: {
|
|
672
822
|
id: uuid1,
|
|
673
|
-
replaces: [
|
|
674
|
-
|
|
675
|
-
|
|
823
|
+
replaces: [
|
|
824
|
+
{
|
|
825
|
+
locusUrl: 'http:locusUrl',
|
|
826
|
+
},
|
|
827
|
+
],
|
|
676
828
|
self: {
|
|
677
829
|
callBackInfo: {
|
|
678
|
-
callbackAddress: uri1
|
|
679
|
-
}
|
|
680
|
-
}
|
|
830
|
+
callbackAddress: uri1,
|
|
831
|
+
},
|
|
832
|
+
},
|
|
833
|
+
info: {
|
|
834
|
+
webExMeetingId
|
|
835
|
+
},
|
|
681
836
|
},
|
|
682
837
|
eventType: 'locus.difference',
|
|
683
|
-
locusUrl: url1
|
|
838
|
+
locusUrl: url1,
|
|
684
839
|
});
|
|
685
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
840
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
686
841
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
842
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
|
|
687
843
|
assert.calledOnce(initialSetup);
|
|
688
844
|
assert.calledWith(initialSetup, {
|
|
689
845
|
id: uuid1,
|
|
690
|
-
replaces: [
|
|
691
|
-
|
|
692
|
-
|
|
846
|
+
replaces: [
|
|
847
|
+
{
|
|
848
|
+
locusUrl: 'http:locusUrl',
|
|
849
|
+
},
|
|
850
|
+
],
|
|
693
851
|
self: {
|
|
694
852
|
callBackInfo: {
|
|
695
|
-
callbackAddress: uri1
|
|
696
|
-
}
|
|
697
|
-
}
|
|
853
|
+
callbackAddress: uri1,
|
|
854
|
+
},
|
|
855
|
+
},
|
|
856
|
+
info: {
|
|
857
|
+
webExMeetingId
|
|
858
|
+
},
|
|
698
859
|
});
|
|
699
860
|
});
|
|
700
861
|
it('should setup the meeting by difference event without replaces', async () => {
|
|
@@ -703,48 +864,95 @@ describe('plugin-meetings', () => {
|
|
|
703
864
|
id: uuid1,
|
|
704
865
|
self: {
|
|
705
866
|
callBackInfo: {
|
|
706
|
-
callbackAddress: uri1
|
|
707
|
-
}
|
|
708
|
-
}
|
|
867
|
+
callbackAddress: uri1,
|
|
868
|
+
},
|
|
869
|
+
},
|
|
870
|
+
info: {
|
|
871
|
+
webExMeetingId
|
|
872
|
+
},
|
|
709
873
|
},
|
|
710
874
|
eventType: 'locus.difference',
|
|
711
|
-
locusUrl: url1
|
|
875
|
+
locusUrl: url1,
|
|
712
876
|
});
|
|
713
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
877
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
714
878
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
879
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
|
|
715
880
|
assert.calledOnce(initialSetup);
|
|
716
881
|
assert.calledWith(initialSetup, {
|
|
717
882
|
id: uuid1,
|
|
718
883
|
self: {
|
|
719
884
|
callBackInfo: {
|
|
720
|
-
callbackAddress: uri1
|
|
721
|
-
}
|
|
722
|
-
}
|
|
885
|
+
callbackAddress: uri1,
|
|
886
|
+
},
|
|
887
|
+
},
|
|
888
|
+
info: {
|
|
889
|
+
webExMeetingId
|
|
890
|
+
},
|
|
723
891
|
});
|
|
724
892
|
});
|
|
893
|
+
|
|
894
|
+
it('sends client event correctly on finally', async () => {
|
|
895
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
896
|
+
|
|
897
|
+
await webex.meetings.handleLocusEvent({
|
|
898
|
+
locus: {
|
|
899
|
+
id: uuid1,
|
|
900
|
+
self: {
|
|
901
|
+
callBackInfo: {
|
|
902
|
+
callbackAddress: uri1,
|
|
903
|
+
},
|
|
904
|
+
},
|
|
905
|
+
info: {
|
|
906
|
+
webExMeetingId,
|
|
907
|
+
},
|
|
908
|
+
},
|
|
909
|
+
eventType: 'locus.difference',
|
|
910
|
+
locusUrl: url1,
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
await testUtils.flushPromises();
|
|
914
|
+
|
|
915
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
916
|
+
name: 'client.call.remote-started',
|
|
917
|
+
payload: {
|
|
918
|
+
trigger: 'mercury-event',
|
|
919
|
+
},
|
|
920
|
+
options: {
|
|
921
|
+
meetingId: 'meeting-id',
|
|
922
|
+
},
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
|
|
725
926
|
it('should setup the meeting by a not difference event', async () => {
|
|
726
927
|
await webex.meetings.handleLocusEvent({
|
|
727
928
|
locus: {
|
|
728
929
|
id: uuid1,
|
|
729
930
|
self: {
|
|
730
931
|
callBackInfo: {
|
|
731
|
-
callbackAddress: uri1
|
|
732
|
-
}
|
|
733
|
-
}
|
|
932
|
+
callbackAddress: uri1,
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
info: {
|
|
936
|
+
webExMeetingId
|
|
937
|
+
},
|
|
734
938
|
},
|
|
735
939
|
eventType: test1,
|
|
736
|
-
locusUrl: url1
|
|
940
|
+
locusUrl: url1,
|
|
737
941
|
});
|
|
738
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
942
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
739
943
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
944
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
|
|
740
945
|
assert.calledOnce(initialSetup);
|
|
741
946
|
assert.calledWith(initialSetup, {
|
|
742
947
|
id: uuid1,
|
|
743
948
|
self: {
|
|
744
949
|
callBackInfo: {
|
|
745
|
-
callbackAddress: uri1
|
|
746
|
-
}
|
|
747
|
-
}
|
|
950
|
+
callbackAddress: uri1,
|
|
951
|
+
},
|
|
952
|
+
},
|
|
953
|
+
info: {
|
|
954
|
+
webExMeetingId
|
|
955
|
+
},
|
|
748
956
|
});
|
|
749
957
|
});
|
|
750
958
|
|
|
@@ -753,13 +961,13 @@ describe('plugin-meetings', () => {
|
|
|
753
961
|
id: uuid1,
|
|
754
962
|
self: {
|
|
755
963
|
callbackInfo: {
|
|
756
|
-
callbackAddress: uri1
|
|
757
|
-
}
|
|
964
|
+
callbackAddress: uri1,
|
|
965
|
+
},
|
|
758
966
|
},
|
|
759
967
|
info: {
|
|
760
|
-
isUnifiedSpaceMeeting
|
|
968
|
+
isUnifiedSpaceMeeting,
|
|
761
969
|
},
|
|
762
|
-
conversationUrl: 'fakeConvoUrl'
|
|
970
|
+
conversationUrl: 'fakeConvoUrl',
|
|
763
971
|
},
|
|
764
972
|
eventType: test1,
|
|
765
973
|
locusUrl: url1,
|
|
@@ -767,19 +975,40 @@ describe('plugin-meetings', () => {
|
|
|
767
975
|
|
|
768
976
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
769
977
|
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
|
-
|
|
978
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
979
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
980
|
+
'locusUrl',
|
|
981
|
+
url1,
|
|
982
|
+
]);
|
|
983
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, [
|
|
984
|
+
'correlationId',
|
|
985
|
+
false,
|
|
986
|
+
]);
|
|
987
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, [
|
|
988
|
+
'sipUri',
|
|
989
|
+
uri1,
|
|
990
|
+
]);
|
|
774
991
|
assert.calledOnce(initialSetup);
|
|
775
992
|
});
|
|
776
993
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
777
994
|
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
|
-
|
|
995
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
996
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
997
|
+
'locusUrl',
|
|
998
|
+
url1,
|
|
999
|
+
]);
|
|
1000
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, [
|
|
1001
|
+
'correlationId',
|
|
1002
|
+
false,
|
|
1003
|
+
]);
|
|
1004
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, [
|
|
1005
|
+
'sipUri',
|
|
1006
|
+
uri1,
|
|
1007
|
+
]);
|
|
1008
|
+
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(3).args, [
|
|
1009
|
+
'conversationUrl',
|
|
1010
|
+
'fakeConvoUrl',
|
|
1011
|
+
]);
|
|
783
1012
|
assert.calledOnce(initialSetup);
|
|
784
1013
|
});
|
|
785
1014
|
});
|
|
@@ -794,15 +1023,19 @@ describe('plugin-meetings', () => {
|
|
|
794
1023
|
});
|
|
795
1024
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
796
1025
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1026
|
+
const FAKE_INFO_EXTRA_PARAMS = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
|
|
797
1027
|
|
|
798
1028
|
beforeEach(() => {
|
|
799
1029
|
clock = sinon.useFakeTimers();
|
|
800
1030
|
setTimeoutSpy = sinon.spy(clock, 'setTimeout');
|
|
801
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
1031
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
1032
|
+
Promise.resolve({
|
|
1033
|
+
body: {
|
|
1034
|
+
permissionToken: 'PT',
|
|
1035
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1036
|
+
},
|
|
1037
|
+
})
|
|
1038
|
+
);
|
|
806
1039
|
const nowTimeStamp = Date.now();
|
|
807
1040
|
|
|
808
1041
|
FAKE_TIME_TO_START = 0.1 * 60 * 1000;
|
|
@@ -816,12 +1049,19 @@ describe('plugin-meetings', () => {
|
|
|
816
1049
|
clock.restore();
|
|
817
1050
|
});
|
|
818
1051
|
|
|
819
|
-
const checkCreateWithoutDelay = (
|
|
1052
|
+
const checkCreateWithoutDelay = (
|
|
1053
|
+
meeting,
|
|
1054
|
+
destination,
|
|
1055
|
+
type,
|
|
1056
|
+
extraParams = {},
|
|
1057
|
+
expectedMeetingData = {},
|
|
1058
|
+
sendCAevents = false,
|
|
1059
|
+
) => {
|
|
820
1060
|
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
821
1061
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
822
1062
|
assert.notCalled(setTimeoutSpy);
|
|
823
|
-
assert.
|
|
824
|
-
assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, destination, type);
|
|
1063
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1064
|
+
assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, destination, type, null, null, undefined, undefined, extraParams, {meetingId: meeting.id, sendCAevents});
|
|
825
1065
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
826
1066
|
|
|
827
1067
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -830,14 +1070,30 @@ describe('plugin-meetings', () => {
|
|
|
830
1070
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
831
1071
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
832
1072
|
}
|
|
1073
|
+
if(expectedMeetingData.correlationId) {
|
|
1074
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1075
|
+
}
|
|
833
1076
|
assert.equal(meeting.destination, destination);
|
|
834
1077
|
assert.equal(meeting.destinationType, type);
|
|
835
|
-
assert.calledWith(
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
1078
|
+
assert.calledWith(
|
|
1079
|
+
TriggerProxy.trigger,
|
|
1080
|
+
sinon.match.instanceOf(Meetings),
|
|
1081
|
+
{
|
|
1082
|
+
file: 'meetings',
|
|
1083
|
+
function: 'createMeeting',
|
|
1084
|
+
},
|
|
1085
|
+
'meeting:added',
|
|
1086
|
+
{
|
|
1087
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1088
|
+
type: 'test meeting added type',
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1091
|
+
assert.calledWith(
|
|
1092
|
+
TriggerProxy.trigger,
|
|
1093
|
+
meeting,
|
|
1094
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1095
|
+
'meeting:meetingInfoAvailable'
|
|
1096
|
+
);
|
|
841
1097
|
};
|
|
842
1098
|
|
|
843
1099
|
it('creates the meeting from a successful meeting info fetch promise testing', async () => {
|
|
@@ -845,80 +1101,120 @@ describe('plugin-meetings', () => {
|
|
|
845
1101
|
|
|
846
1102
|
const expectedMeetingData = {
|
|
847
1103
|
permissionToken: 'PT',
|
|
848
|
-
meetingJoinUrl: 'meetingJoinUrl'
|
|
1104
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1105
|
+
correlationId: meeting.id,
|
|
849
1106
|
};
|
|
850
1107
|
|
|
851
|
-
checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
|
|
1108
|
+
checkCreateWithoutDelay(meeting, 'test destination', 'test type', {}, expectedMeetingData);
|
|
852
1109
|
});
|
|
853
1110
|
|
|
854
|
-
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
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
|
-
}
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
const meeting = await webex.meetings.createMeeting(FAKE_LOCUS_MEETING, 'test type', true);
|
|
883
|
-
|
|
884
|
-
assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
|
|
885
|
-
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
886
|
-
assert.calledOnce(setTimeoutSpy);
|
|
887
|
-
|
|
888
|
-
// Parse meeting info with locus object
|
|
889
|
-
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
890
|
-
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
891
|
-
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
892
|
-
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
893
|
-
assert.isUndefined(meeting.meetingJoinUrl);
|
|
894
|
-
assert.equal(meeting.owner, 'locusOwner');
|
|
895
|
-
assert.isUndefined(meeting.permissionToken);
|
|
896
|
-
|
|
897
|
-
// Add meeting and send trigger
|
|
898
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
899
|
-
assert.calledTwice(TriggerProxy.trigger);
|
|
900
|
-
assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
|
|
901
|
-
file: 'meetings', function: 'createMeeting'
|
|
902
|
-
}, 'meeting:added', {
|
|
903
|
-
meeting: sinon.match.instanceOf(Meeting), type: 'test meeting added type'
|
|
1111
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1112
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
1113
|
+
|
|
1114
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
|
|
1115
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type', false, infoExtraParams);
|
|
1116
|
+
const expectedMeetingData = {
|
|
1117
|
+
permissionToken: 'PT',
|
|
1118
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1121
|
+
assert.instanceOf(
|
|
1122
|
+
meeting,
|
|
1123
|
+
Meeting,
|
|
1124
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1125
|
+
);
|
|
1126
|
+
checkCreateWithoutDelay(meeting, 'test destination', 'test type', infoExtraParamsProvided ? infoExtraParams : {}, expectedMeetingData);
|
|
904
1127
|
});
|
|
905
1128
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1129
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
|
|
1130
|
+
const FAKE_LOCUS_MEETING = {
|
|
1131
|
+
conversationUrl: 'locusConvURL',
|
|
1132
|
+
url: 'locusUrl',
|
|
1133
|
+
info: {
|
|
1134
|
+
webExMeetingId: 'locusMeetingId',
|
|
1135
|
+
sipUri: 'locusSipUri',
|
|
1136
|
+
owner: 'locusOwner',
|
|
1137
|
+
},
|
|
1138
|
+
meeting: {
|
|
1139
|
+
startTime: fakeMeetingStartTimeString,
|
|
1140
|
+
},
|
|
1141
|
+
fullState: {
|
|
1142
|
+
active: false,
|
|
1143
|
+
},
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1147
|
+
FAKE_LOCUS_MEETING,
|
|
1148
|
+
'test type',
|
|
1149
|
+
true,
|
|
1150
|
+
infoExtraParams
|
|
1151
|
+
);
|
|
1152
|
+
|
|
1153
|
+
assert.instanceOf(
|
|
1154
|
+
meeting,
|
|
1155
|
+
Meeting,
|
|
1156
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1157
|
+
);
|
|
1158
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1159
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1160
|
+
|
|
1161
|
+
// Parse meeting info with locus object
|
|
1162
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1163
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1164
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1165
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1166
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1167
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1168
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1169
|
+
|
|
1170
|
+
// Add meeting and send trigger
|
|
1171
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1172
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1173
|
+
assert.calledWith(
|
|
1174
|
+
TriggerProxy.trigger,
|
|
1175
|
+
sinon.match.instanceOf(Meetings),
|
|
1176
|
+
{
|
|
1177
|
+
file: 'meetings',
|
|
1178
|
+
function: 'createMeeting',
|
|
1179
|
+
},
|
|
1180
|
+
'meeting:added',
|
|
1181
|
+
{
|
|
1182
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1183
|
+
type: 'test meeting added type',
|
|
1184
|
+
}
|
|
1185
|
+
);
|
|
1186
|
+
|
|
1187
|
+
// When timer expires
|
|
1188
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1189
|
+
assert.calledWith(
|
|
1190
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1191
|
+
FAKE_LOCUS_MEETING,
|
|
1192
|
+
'test type',
|
|
1193
|
+
null,
|
|
1194
|
+
null,
|
|
1195
|
+
undefined,
|
|
1196
|
+
undefined,
|
|
1197
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1198
|
+
);
|
|
1199
|
+
|
|
1200
|
+
// Parse meeting info is called again with new meeting info
|
|
1201
|
+
await testUtils.flushPromises();
|
|
1202
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1203
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1204
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1205
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1206
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1207
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1208
|
+
assert.equal(meeting.permissionToken, 'PT');
|
|
1209
|
+
|
|
1210
|
+
assert.calledWith(
|
|
1211
|
+
TriggerProxy.trigger,
|
|
1212
|
+
meeting,
|
|
1213
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1214
|
+
'meeting:meetingInfoAvailable'
|
|
1215
|
+
);
|
|
1216
|
+
});
|
|
1217
|
+
})
|
|
922
1218
|
|
|
923
1219
|
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
924
1220
|
const FAKE_LOCUS_MEETING = {
|
|
@@ -927,19 +1223,27 @@ describe('plugin-meetings', () => {
|
|
|
927
1223
|
info: {
|
|
928
1224
|
webExMeetingId: 'locusMeetingId',
|
|
929
1225
|
sipUri: 'locusSipUri',
|
|
930
|
-
owner: 'locusOwner'
|
|
1226
|
+
owner: 'locusOwner',
|
|
931
1227
|
},
|
|
932
1228
|
meeting: {
|
|
933
|
-
startTime: fakeMeetingStartTimeString
|
|
1229
|
+
startTime: fakeMeetingStartTimeString,
|
|
934
1230
|
},
|
|
935
1231
|
fullState: {
|
|
936
|
-
active: true
|
|
937
|
-
}
|
|
1232
|
+
active: true,
|
|
1233
|
+
},
|
|
938
1234
|
};
|
|
939
1235
|
|
|
940
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1236
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1237
|
+
FAKE_LOCUS_MEETING,
|
|
1238
|
+
'test type',
|
|
1239
|
+
true
|
|
1240
|
+
);
|
|
941
1241
|
|
|
942
|
-
assert.instanceOf(
|
|
1242
|
+
assert.instanceOf(
|
|
1243
|
+
meeting,
|
|
1244
|
+
Meeting,
|
|
1245
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1246
|
+
);
|
|
943
1247
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
944
1248
|
});
|
|
945
1249
|
|
|
@@ -950,27 +1254,35 @@ describe('plugin-meetings', () => {
|
|
|
950
1254
|
info: {
|
|
951
1255
|
webExMeetingId: 'locusMeetingId',
|
|
952
1256
|
sipUri: 'locusSipUri',
|
|
953
|
-
owner: 'locusOwner'
|
|
1257
|
+
owner: 'locusOwner',
|
|
954
1258
|
},
|
|
955
1259
|
meeting: {
|
|
956
|
-
startTime: fakeMeetingStartTimeString -
|
|
1260
|
+
startTime: fakeMeetingStartTimeString - 1 * 60 * 60 * 1000,
|
|
957
1261
|
},
|
|
958
1262
|
fullState: {
|
|
959
|
-
active: false
|
|
960
|
-
}
|
|
1263
|
+
active: false,
|
|
1264
|
+
},
|
|
961
1265
|
};
|
|
962
1266
|
|
|
963
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1267
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1268
|
+
FAKE_LOCUS_MEETING,
|
|
1269
|
+
'test type',
|
|
1270
|
+
true
|
|
1271
|
+
);
|
|
964
1272
|
|
|
965
|
-
assert.instanceOf(
|
|
1273
|
+
assert.instanceOf(
|
|
1274
|
+
meeting,
|
|
1275
|
+
Meeting,
|
|
1276
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1277
|
+
);
|
|
966
1278
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
967
1279
|
});
|
|
968
1280
|
|
|
969
1281
|
it('creates the meeting from a successful meeting info fetch that has no random delay because enableUnifiedMeetings is disabled', async () => {
|
|
970
1282
|
Object.assign(webex.meetings.config, {
|
|
971
1283
|
experimental: {
|
|
972
|
-
enableUnifiedMeetings: false
|
|
973
|
-
}
|
|
1284
|
+
enableUnifiedMeetings: false,
|
|
1285
|
+
},
|
|
974
1286
|
});
|
|
975
1287
|
const FAKE_LOCUS_MEETING = {
|
|
976
1288
|
conversationUrl: 'locusConvURL',
|
|
@@ -978,45 +1290,164 @@ describe('plugin-meetings', () => {
|
|
|
978
1290
|
info: {
|
|
979
1291
|
webExMeetingId: 'locusMeetingId',
|
|
980
1292
|
sipUri: 'locusSipUri',
|
|
981
|
-
owner: 'locusOwner'
|
|
1293
|
+
owner: 'locusOwner',
|
|
982
1294
|
},
|
|
983
1295
|
meeting: {
|
|
984
|
-
startTime: fakeMeetingStartTimeString
|
|
1296
|
+
startTime: fakeMeetingStartTimeString,
|
|
985
1297
|
},
|
|
986
1298
|
fullState: {
|
|
987
|
-
active: false
|
|
988
|
-
}
|
|
1299
|
+
active: false,
|
|
1300
|
+
},
|
|
989
1301
|
};
|
|
990
1302
|
|
|
991
|
-
const meeting = await webex.meetings.createMeeting(
|
|
1303
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1304
|
+
FAKE_LOCUS_MEETING,
|
|
1305
|
+
'test type',
|
|
1306
|
+
true
|
|
1307
|
+
);
|
|
992
1308
|
|
|
993
|
-
assert.instanceOf(
|
|
1309
|
+
assert.instanceOf(
|
|
1310
|
+
meeting,
|
|
1311
|
+
Meeting,
|
|
1312
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1313
|
+
);
|
|
994
1314
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
995
1315
|
});
|
|
1316
|
+
|
|
1317
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1318
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type', false, {}, 'my-correlationId');
|
|
1319
|
+
|
|
1320
|
+
const expectedMeetingData = {
|
|
1321
|
+
correlationId: 'my-correlationId',
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
checkCreateWithoutDelay(meeting, 'test destination', 'test type', {}, expectedMeetingData, true);
|
|
1325
|
+
})
|
|
996
1326
|
});
|
|
997
1327
|
|
|
998
1328
|
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
999
1329
|
beforeEach(() => {
|
|
1000
1330
|
console.error = sinon.stub().returns(false);
|
|
1001
1331
|
TriggerProxy.trigger.reset();
|
|
1002
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1332
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1333
|
+
.stub()
|
|
1334
|
+
.returns(Promise.reject(new Error('test')));
|
|
1335
|
+
webex.meetings.destroy = sinon
|
|
1336
|
+
.stub()
|
|
1337
|
+
.returns(Promise.resolve());
|
|
1338
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1003
1339
|
});
|
|
1340
|
+
|
|
1341
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1342
|
+
try {
|
|
1343
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type', undefined, undefined, undefined, failOnMissingMeetingInfo);
|
|
1344
|
+
|
|
1345
|
+
assert.instanceOf(
|
|
1346
|
+
meeting,
|
|
1347
|
+
Meeting,
|
|
1348
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1349
|
+
);
|
|
1350
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1351
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1352
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1353
|
+
assert.calledWith(
|
|
1354
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1355
|
+
'test destination',
|
|
1356
|
+
'test type'
|
|
1357
|
+
);
|
|
1358
|
+
|
|
1359
|
+
if (destroy) {
|
|
1360
|
+
assert.calledWith(webex.meetings.destroy, sinon.match.instanceOf(Meeting), 'MISSING_MEETING_INFO')
|
|
1361
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1362
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1363
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1364
|
+
} else {
|
|
1365
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1366
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1367
|
+
assert.calledWith(
|
|
1368
|
+
TriggerProxy.trigger,
|
|
1369
|
+
sinon.match.instanceOf(Meetings),
|
|
1370
|
+
{
|
|
1371
|
+
file: 'meetings',
|
|
1372
|
+
function: 'createMeeting',
|
|
1373
|
+
},
|
|
1374
|
+
'meeting:added',
|
|
1375
|
+
{
|
|
1376
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1377
|
+
type: 'test meeting added type',
|
|
1378
|
+
}
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
} catch (err) {
|
|
1382
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1004
1386
|
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1005
|
-
|
|
1387
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1388
|
+
});
|
|
1006
1389
|
|
|
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
|
-
});
|
|
1390
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1391
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1018
1392
|
});
|
|
1019
1393
|
});
|
|
1394
|
+
|
|
1395
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1396
|
+
forEach(
|
|
1397
|
+
[
|
|
1398
|
+
{
|
|
1399
|
+
error: new CaptchaError(),
|
|
1400
|
+
debugLogMessage:
|
|
1401
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1402
|
+
},
|
|
1403
|
+
{
|
|
1404
|
+
error: new PasswordError(),
|
|
1405
|
+
debugLogMessage:
|
|
1406
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
error: new PermissionError(),
|
|
1410
|
+
debugLogMessage:
|
|
1411
|
+
'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.',
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
error: new Error(),
|
|
1415
|
+
infoLogMessage: true,
|
|
1416
|
+
debugLogMessage:
|
|
1417
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1418
|
+
},
|
|
1419
|
+
],
|
|
1420
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1421
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1422
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1423
|
+
.stub()
|
|
1424
|
+
.returns(Promise.reject(error));
|
|
1425
|
+
|
|
1426
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1427
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1428
|
+
|
|
1429
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1430
|
+
|
|
1431
|
+
assert.instanceOf(
|
|
1432
|
+
meeting,
|
|
1433
|
+
Meeting,
|
|
1434
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1435
|
+
);
|
|
1436
|
+
|
|
1437
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1438
|
+
|
|
1439
|
+
if (infoLogMessage) {
|
|
1440
|
+
assert.calledWith(
|
|
1441
|
+
LoggerProxy.logger.info,
|
|
1442
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1443
|
+
);
|
|
1444
|
+
} else {
|
|
1445
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
);
|
|
1450
|
+
});
|
|
1020
1451
|
});
|
|
1021
1452
|
});
|
|
1022
1453
|
describe('Public Event Triggers', () => {
|
|
@@ -1039,11 +1470,19 @@ describe('plugin-meetings', () => {
|
|
|
1039
1470
|
|
|
1040
1471
|
assert.calledOnce(webex.meetings.meetingCollection.delete);
|
|
1041
1472
|
assert.calledWith(webex.meetings.meetingCollection.delete, meeting.id);
|
|
1042
|
-
assert.calledWith(
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1473
|
+
assert.calledWith(
|
|
1474
|
+
TriggerProxy.trigger,
|
|
1475
|
+
sinon.match.instanceOf(Meetings),
|
|
1476
|
+
{
|
|
1477
|
+
file: 'meetings',
|
|
1478
|
+
function: 'destroy',
|
|
1479
|
+
},
|
|
1480
|
+
'meeting:removed',
|
|
1481
|
+
{
|
|
1482
|
+
meetingId: meeting.id,
|
|
1483
|
+
reason: test1,
|
|
1484
|
+
}
|
|
1485
|
+
);
|
|
1047
1486
|
});
|
|
1048
1487
|
});
|
|
1049
1488
|
|
|
@@ -1068,7 +1507,8 @@ describe('plugin-meetings', () => {
|
|
|
1068
1507
|
it('should trigger event upon mercury disconnect', () => {
|
|
1069
1508
|
const {meetings} = webex;
|
|
1070
1509
|
const SCOPE = {
|
|
1071
|
-
file: 'meetings/index',
|
|
1510
|
+
file: 'meetings/index',
|
|
1511
|
+
function: 'handleMercuryOffline',
|
|
1072
1512
|
};
|
|
1073
1513
|
const EVENT = 'network:disconnected';
|
|
1074
1514
|
|
|
@@ -1086,6 +1526,9 @@ describe('plugin-meetings', () => {
|
|
|
1086
1526
|
});
|
|
1087
1527
|
|
|
1088
1528
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1529
|
+
|
|
1530
|
+
let loggerProxySpy;
|
|
1531
|
+
|
|
1089
1532
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1090
1533
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1091
1534
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1093,19 +1536,89 @@ describe('plugin-meetings', () => {
|
|
|
1093
1536
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1094
1537
|
});
|
|
1095
1538
|
|
|
1539
|
+
const setup = ({user} = {}) => {
|
|
1540
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1541
|
+
|
|
1542
|
+
Object.assign(webex.internal, {
|
|
1543
|
+
services: {
|
|
1544
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1545
|
+
},
|
|
1546
|
+
user: {
|
|
1547
|
+
get: sinon.stub().returns(
|
|
1548
|
+
Promise.resolve(user)
|
|
1549
|
+
),
|
|
1550
|
+
},
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1096
1554
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1555
|
+
setup();
|
|
1556
|
+
|
|
1097
1557
|
Object.assign(webex.internal, {
|
|
1098
1558
|
services: {
|
|
1099
1559
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1100
1560
|
},
|
|
1561
|
+
});
|
|
1101
1562
|
|
|
1563
|
+
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1564
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1102
1565
|
});
|
|
1566
|
+
assert.calledOnceWithExactly(
|
|
1567
|
+
loggerProxySpy,
|
|
1568
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1569
|
+
);
|
|
1570
|
+
});
|
|
1103
1571
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1572
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1573
|
+
setup({
|
|
1574
|
+
user: {
|
|
1575
|
+
userPreferences: {
|
|
1576
|
+
userPreferencesItems: {
|
|
1577
|
+
preferredWebExSite: 'site.webex.com',
|
|
1578
|
+
},
|
|
1579
|
+
},
|
|
1580
|
+
},
|
|
1581
|
+
});
|
|
1582
|
+
|
|
1583
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1584
|
+
|
|
1585
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1586
|
+
assert.notCalled(loggerProxySpy);
|
|
1587
|
+
});
|
|
1588
|
+
|
|
1589
|
+
forEach([
|
|
1590
|
+
{user: undefined},
|
|
1591
|
+
{user: {userPreferences: {}}},
|
|
1592
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1593
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1594
|
+
], ({user}) => {
|
|
1595
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1596
|
+
setup({user});
|
|
1597
|
+
|
|
1598
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1599
|
+
|
|
1600
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1601
|
+
assert.calledOnceWithExactly(
|
|
1602
|
+
loggerProxySpy,
|
|
1603
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1604
|
+
);
|
|
1605
|
+
});
|
|
1606
|
+
});
|
|
1607
|
+
|
|
1608
|
+
it('should handle a get user failure', async () => {
|
|
1609
|
+
setup();
|
|
1610
|
+
|
|
1611
|
+
webex.internal.user.get.rejects(new Error());
|
|
1612
|
+
|
|
1613
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1614
|
+
|
|
1615
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1616
|
+
assert.calledOnceWithExactly(
|
|
1617
|
+
loggerProxySpy,
|
|
1618
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1619
|
+
);
|
|
1108
1620
|
});
|
|
1621
|
+
|
|
1109
1622
|
});
|
|
1110
1623
|
});
|
|
1111
1624
|
|
|
@@ -1120,11 +1633,14 @@ describe('plugin-meetings', () => {
|
|
|
1120
1633
|
TriggerProxy.trigger.reset();
|
|
1121
1634
|
// clock = sinon.useFakeTimers();
|
|
1122
1635
|
// setTimeoutSpy = sinon.spy(clock, 'setTimeout');
|
|
1123
|
-
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1636
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
|
|
1637
|
+
Promise.resolve({
|
|
1638
|
+
body: {
|
|
1639
|
+
permissionToken: 'PT',
|
|
1640
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1641
|
+
},
|
|
1642
|
+
})
|
|
1643
|
+
);
|
|
1128
1644
|
|
|
1129
1645
|
meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1130
1646
|
|
|
@@ -1132,37 +1648,37 @@ describe('plugin-meetings', () => {
|
|
|
1132
1648
|
});
|
|
1133
1649
|
|
|
1134
1650
|
it('triggers correct event when CONTROLS_ENTRY_EXIT_TONE_UPDATED emitted', async () => {
|
|
1135
|
-
await meeting.locusInfo.emitScoped(
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
{entryExitTone: 'foo'}
|
|
1139
|
-
);
|
|
1651
|
+
await meeting.locusInfo.emitScoped({}, LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED, {
|
|
1652
|
+
entryExitTone: 'foo',
|
|
1653
|
+
});
|
|
1140
1654
|
|
|
1141
1655
|
assert.calledOnce(TriggerProxy.trigger);
|
|
1142
|
-
assert.calledWith(
|
|
1656
|
+
assert.calledWith(
|
|
1657
|
+
TriggerProxy.trigger,
|
|
1658
|
+
sinon.match.instanceOf(Meeting),
|
|
1143
1659
|
{
|
|
1144
1660
|
file: 'meeting/index',
|
|
1145
|
-
function: 'setupLocusControlsListener'
|
|
1661
|
+
function: 'setupLocusControlsListener',
|
|
1146
1662
|
},
|
|
1147
1663
|
EVENT_TRIGGERS.MEETING_ENTRY_EXIT_TONE_UPDATE,
|
|
1148
|
-
{entryExitTone: 'foo'}
|
|
1664
|
+
{entryExitTone: 'foo'}
|
|
1665
|
+
);
|
|
1149
1666
|
});
|
|
1150
1667
|
|
|
1151
1668
|
const checkSelfTrigger = async (inEvent, outEvent) => {
|
|
1152
|
-
await meeting.locusInfo.emitScoped(
|
|
1153
|
-
{},
|
|
1154
|
-
inEvent,
|
|
1155
|
-
{foo: 'bar'}
|
|
1156
|
-
);
|
|
1669
|
+
await meeting.locusInfo.emitScoped({}, inEvent, {foo: 'bar'});
|
|
1157
1670
|
|
|
1158
1671
|
assert.calledOnce(TriggerProxy.trigger);
|
|
1159
|
-
assert.calledWith(
|
|
1672
|
+
assert.calledWith(
|
|
1673
|
+
TriggerProxy.trigger,
|
|
1674
|
+
sinon.match.instanceOf(Meeting),
|
|
1160
1675
|
{
|
|
1161
1676
|
file: 'meeting/index',
|
|
1162
|
-
function: 'setUpLocusInfoSelfListener'
|
|
1677
|
+
function: 'setUpLocusInfoSelfListener',
|
|
1163
1678
|
},
|
|
1164
1679
|
outEvent,
|
|
1165
|
-
{payload: {foo: 'bar'}}
|
|
1680
|
+
{payload: {foo: 'bar'}}
|
|
1681
|
+
);
|
|
1166
1682
|
};
|
|
1167
1683
|
|
|
1168
1684
|
it('triggers correct event when SELF_CANNOT_VIEW_PARTICIPANT_LIST_CHANGE emitted', async () => {
|
|
@@ -1186,5 +1702,477 @@ describe('plugin-meetings', () => {
|
|
|
1186
1702
|
);
|
|
1187
1703
|
});
|
|
1188
1704
|
});
|
|
1705
|
+
|
|
1706
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
1707
|
+
let meeting;
|
|
1708
|
+
let newLocus;
|
|
1709
|
+
beforeEach(() => {
|
|
1710
|
+
meeting = {
|
|
1711
|
+
controls: {},
|
|
1712
|
+
self: {},
|
|
1713
|
+
};
|
|
1714
|
+
newLocus = {
|
|
1715
|
+
controls: {},
|
|
1716
|
+
self: {},
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
afterEach(() => {
|
|
1720
|
+
sinon.restore();
|
|
1721
|
+
});
|
|
1722
|
+
it('check normal case will return true', () => {
|
|
1723
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1724
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1725
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1726
|
+
assert.equal(result, true);
|
|
1727
|
+
assert.calledWith(
|
|
1728
|
+
LoggerProxy.logger.log,
|
|
1729
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1730
|
+
);
|
|
1731
|
+
});
|
|
1732
|
+
|
|
1733
|
+
it('check self joined and joined on this device, return true', () => {
|
|
1734
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1735
|
+
newLocus.self.state = 'JOINED';
|
|
1736
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1737
|
+
|
|
1738
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1739
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1740
|
+
assert.equal(result, true);
|
|
1741
|
+
assert.calledWith(
|
|
1742
|
+
LoggerProxy.logger.log,
|
|
1743
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
1744
|
+
);
|
|
1745
|
+
});
|
|
1746
|
+
|
|
1747
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
1748
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({joinedWith: {replaces: [{
|
|
1749
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
1750
|
+
}]}});
|
|
1751
|
+
newLocus.self.state = 'JOINED';
|
|
1752
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1753
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1754
|
+
replaces: [{
|
|
1755
|
+
replaceAt: '2023-03-27T02:17:01.506Z'
|
|
1756
|
+
}]
|
|
1757
|
+
})
|
|
1758
|
+
|
|
1759
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1760
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1761
|
+
assert.equal(result, false);
|
|
1762
|
+
assert.calledWith(
|
|
1763
|
+
LoggerProxy.logger.log,
|
|
1764
|
+
`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`
|
|
1765
|
+
);
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1768
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
1769
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1770
|
+
joinedWith: {
|
|
1771
|
+
correlationId: '111',
|
|
1772
|
+
},
|
|
1773
|
+
});
|
|
1774
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
1775
|
+
meeting.correlationId = '111';
|
|
1776
|
+
|
|
1777
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1778
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1779
|
+
assert.equal(result, false);
|
|
1780
|
+
assert.calledWith(
|
|
1781
|
+
LoggerProxy.logger.log,
|
|
1782
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
1783
|
+
);
|
|
1784
|
+
});
|
|
1785
|
+
|
|
1786
|
+
it('check self is moved and removed, return false', () => {
|
|
1787
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1788
|
+
newLocus.self.state = 'LEFT';
|
|
1789
|
+
newLocus.self.reason = 'MOVED';
|
|
1790
|
+
newLocus.self.removed = true;
|
|
1791
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1792
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1793
|
+
assert.equal(result, false);
|
|
1794
|
+
assert.calledWith(
|
|
1795
|
+
LoggerProxy.logger.log,
|
|
1796
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1797
|
+
);
|
|
1798
|
+
});
|
|
1799
|
+
|
|
1800
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
1801
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1802
|
+
newLocus.self.state = 'LEFT';
|
|
1803
|
+
newLocus.self.reason = 'MOVED';
|
|
1804
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1805
|
+
state: 'LEFT',
|
|
1806
|
+
reason: 'MOVED',
|
|
1807
|
+
});
|
|
1808
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1809
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1810
|
+
assert.equal(result, false);
|
|
1811
|
+
assert.calledWith(
|
|
1812
|
+
LoggerProxy.logger.log,
|
|
1813
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
1814
|
+
);
|
|
1815
|
+
});
|
|
1816
|
+
|
|
1817
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
1818
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
1819
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
1820
|
+
newLocus.self.state = 'JOINED';
|
|
1821
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1822
|
+
state: 'LEFT',
|
|
1823
|
+
reason: 'MOVED',
|
|
1824
|
+
});
|
|
1825
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1826
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1827
|
+
assert.equal(result, false);
|
|
1828
|
+
assert.calledWith(
|
|
1829
|
+
LoggerProxy.logger.log,
|
|
1830
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
1831
|
+
);
|
|
1832
|
+
});
|
|
1833
|
+
});
|
|
1834
|
+
|
|
1835
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
1836
|
+
let meeting;
|
|
1837
|
+
let newLocus;
|
|
1838
|
+
beforeEach(() => {
|
|
1839
|
+
meeting = {
|
|
1840
|
+
controls: {},
|
|
1841
|
+
self: {},
|
|
1842
|
+
};
|
|
1843
|
+
newLocus = {
|
|
1844
|
+
controls: {},
|
|
1845
|
+
self: {},
|
|
1846
|
+
}
|
|
1847
|
+
});
|
|
1848
|
+
afterEach(() => {
|
|
1849
|
+
sinon.restore();
|
|
1850
|
+
});
|
|
1851
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
1852
|
+
newLocus.controls.breakout = {
|
|
1853
|
+
sessionType: 'BREAKOUT',
|
|
1854
|
+
};
|
|
1855
|
+
newLocus.self.state = 'JOINED';
|
|
1856
|
+
newLocus.fullState = {
|
|
1857
|
+
active: true,
|
|
1858
|
+
};
|
|
1859
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1860
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
1861
|
+
assert.equal(result, true);
|
|
1862
|
+
assert.calledWith(
|
|
1863
|
+
LoggerProxy.logger.log,
|
|
1864
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
1865
|
+
);
|
|
1866
|
+
});
|
|
1867
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
1868
|
+
newLocus.controls.breakout = {
|
|
1869
|
+
sessionType: 'MAIN',
|
|
1870
|
+
};
|
|
1871
|
+
newLocus.self.state = 'JOINED';
|
|
1872
|
+
|
|
1873
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1874
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
1875
|
+
assert.equal(result, true);
|
|
1876
|
+
assert.calledWith(
|
|
1877
|
+
LoggerProxy.logger.log,
|
|
1878
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1879
|
+
);
|
|
1880
|
+
});
|
|
1881
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
1882
|
+
newLocus.controls.breakout = {
|
|
1883
|
+
sessionType: 'BREAKOUT',
|
|
1884
|
+
};
|
|
1885
|
+
newLocus.self.state = 'LEFT';
|
|
1886
|
+
newLocus.self.reason = 'MOVED';
|
|
1887
|
+
|
|
1888
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1889
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
1890
|
+
assert.equal(result, false);
|
|
1891
|
+
});
|
|
1892
|
+
});
|
|
1893
|
+
|
|
1894
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
1895
|
+
let locus;
|
|
1896
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
1897
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
1898
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
1899
|
+
if (key === keyWillReturnMeeting) {
|
|
1900
|
+
return mockReturnMeeting;
|
|
1901
|
+
}
|
|
1902
|
+
return null;
|
|
1903
|
+
});
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1906
|
+
beforeEach(() => {
|
|
1907
|
+
locus = {
|
|
1908
|
+
controls: {},
|
|
1909
|
+
self: {
|
|
1910
|
+
callbackInfo: {
|
|
1911
|
+
callbackAddress: 'address1',
|
|
1912
|
+
}
|
|
1913
|
+
},
|
|
1914
|
+
info: {
|
|
1915
|
+
webExMeetingId: '123456',
|
|
1916
|
+
isUnifiedSpaceMeeting: false,
|
|
1917
|
+
},
|
|
1918
|
+
conversationUrl: 'conversationUrl1'
|
|
1919
|
+
};
|
|
1920
|
+
|
|
1921
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
1922
|
+
});
|
|
1923
|
+
afterEach(() => {
|
|
1924
|
+
sinon.restore();
|
|
1925
|
+
});
|
|
1926
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
1927
|
+
mockGetByKey();
|
|
1928
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1929
|
+
assert.isNull(result);
|
|
1930
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
1931
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1932
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1933
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
1934
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
|
|
1935
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
1936
|
+
});
|
|
1937
|
+
|
|
1938
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
1939
|
+
mockGetByKey();
|
|
1940
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
1941
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1942
|
+
assert.isNull(result);
|
|
1943
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
1944
|
+
})
|
|
1945
|
+
|
|
1946
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
1947
|
+
mockGetByKey('locusUrl');
|
|
1948
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1949
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1950
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
1951
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1952
|
+
});
|
|
1953
|
+
|
|
1954
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
1955
|
+
mockGetByKey('correlationId');
|
|
1956
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1957
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1958
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
1959
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1960
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
1964
|
+
mockGetByKey('sipUri');
|
|
1965
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1966
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1967
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
1968
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1969
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1970
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
1971
|
+
});
|
|
1972
|
+
|
|
1973
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
1974
|
+
mockGetByKey('conversationUrl');
|
|
1975
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1976
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1977
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
1978
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1979
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1980
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
1981
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
1985
|
+
mockGetByKey('meetingNumber');
|
|
1986
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
1987
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
1988
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
1989
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1990
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
|
|
1991
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
1992
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
|
|
1993
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
1994
|
+
});
|
|
1995
|
+
});
|
|
1996
|
+
|
|
1997
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
1998
|
+
let lociArray;
|
|
1999
|
+
let mainLocus;
|
|
2000
|
+
let breakoutLocus;
|
|
2001
|
+
beforeEach(() => {
|
|
2002
|
+
mainLocus = {
|
|
2003
|
+
url: 'mainUrl1',
|
|
2004
|
+
controls: {
|
|
2005
|
+
breakout: {
|
|
2006
|
+
sessionType: 'MAIN',
|
|
2007
|
+
url: 'breakoutUnifiedUrl1'
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
breakoutLocus = {
|
|
2012
|
+
url: 'breakoutUrl1',
|
|
2013
|
+
controls: {
|
|
2014
|
+
breakout: {
|
|
2015
|
+
sessionType: 'BREAKOUT',
|
|
2016
|
+
url: 'breakoutUnifiedUrl1'
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
};
|
|
2020
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2021
|
+
|
|
2022
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2023
|
+
return locus.url === 'breakoutUrl1';
|
|
2024
|
+
});
|
|
2025
|
+
});
|
|
2026
|
+
afterEach(() => {
|
|
2027
|
+
sinon.restore();
|
|
2028
|
+
});
|
|
2029
|
+
|
|
2030
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2031
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2032
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2033
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2034
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2035
|
+
});
|
|
2036
|
+
|
|
2037
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2038
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2039
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2040
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2041
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2042
|
+
});
|
|
2043
|
+
|
|
2044
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2045
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2046
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2047
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2048
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2049
|
+
});
|
|
2050
|
+
});
|
|
2051
|
+
|
|
2052
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2053
|
+
let breakoutLocus;
|
|
2054
|
+
beforeEach(() => {
|
|
2055
|
+
breakoutLocus = {
|
|
2056
|
+
url: 'breakoutUrl1',
|
|
2057
|
+
controls: {
|
|
2058
|
+
breakout: {
|
|
2059
|
+
sessionType: 'BREAKOUT',
|
|
2060
|
+
url: 'breakoutUnifiedUrl1',
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
};
|
|
2064
|
+
|
|
2065
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2066
|
+
});
|
|
2067
|
+
afterEach(() => {
|
|
2068
|
+
sinon.restore();
|
|
2069
|
+
});
|
|
2070
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2071
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2072
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2073
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2074
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2075
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2076
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2080
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2081
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2082
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2083
|
+
});
|
|
2084
|
+
|
|
2085
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2086
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2087
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2088
|
+
controls: {
|
|
2089
|
+
breakout: {
|
|
2090
|
+
sessionType: 'MAIN',
|
|
2091
|
+
url: 'breakoutUnifiedUrl2',
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
});
|
|
2095
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2096
|
+
});
|
|
2097
|
+
|
|
2098
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2099
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2100
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2101
|
+
controls: {
|
|
2102
|
+
breakout: {
|
|
2103
|
+
sessionType: 'MAIN',
|
|
2104
|
+
url: 'breakoutUnifiedUrl1',
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
});
|
|
2108
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {locus: breakoutLocus, locusUrl: breakoutLocus.url});
|
|
2109
|
+
});
|
|
2110
|
+
});
|
|
2111
|
+
|
|
2112
|
+
describe('uploading of logs', () => {
|
|
2113
|
+
let metricsSpy;
|
|
2114
|
+
let meeting;
|
|
2115
|
+
|
|
2116
|
+
beforeEach(async () => {
|
|
2117
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2118
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2119
|
+
|
|
2120
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2121
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2122
|
+
|
|
2123
|
+
triggerProxyStub.restore();
|
|
2124
|
+
|
|
2125
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2126
|
+
|
|
2127
|
+
meeting = await webex.meetings.create('test');
|
|
2128
|
+
|
|
2129
|
+
meeting.locusId = 'locus id';
|
|
2130
|
+
meeting.correlationId = 'correlation id';
|
|
2131
|
+
meeting.locusInfo = {
|
|
2132
|
+
fullState: { lastActive: 'last active', sessionId: 'locus session id'},
|
|
2133
|
+
info: { webExMeetingId: 'meeting id'}
|
|
2134
|
+
}
|
|
2135
|
+
});
|
|
2136
|
+
|
|
2137
|
+
afterEach(() => {
|
|
2138
|
+
sinon.restore();
|
|
2139
|
+
})
|
|
2140
|
+
|
|
2141
|
+
it('sends metrics on success', async () => {
|
|
2142
|
+
|
|
2143
|
+
await meeting.uploadLogs();
|
|
2144
|
+
|
|
2145
|
+
await testUtils.flushPromises();
|
|
2146
|
+
|
|
2147
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2148
|
+
callStart: 'last active',
|
|
2149
|
+
correlationId: 'correlation id',
|
|
2150
|
+
feedbackId: 'correlation id',
|
|
2151
|
+
locusId: 'locus id',
|
|
2152
|
+
meetingId: 'meeting id',
|
|
2153
|
+
autoupload: true,
|
|
2154
|
+
locussessionid: 'locus session id',
|
|
2155
|
+
});
|
|
2156
|
+
});
|
|
2157
|
+
|
|
2158
|
+
it('sends metrics on failure', async () => {
|
|
2159
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2160
|
+
|
|
2161
|
+
await meeting.uploadLogs();
|
|
2162
|
+
|
|
2163
|
+
await testUtils.flushPromises();
|
|
2164
|
+
|
|
2165
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_failure', sinon.match({
|
|
2166
|
+
callStart: 'last active',
|
|
2167
|
+
correlationId: 'correlation id',
|
|
2168
|
+
feedbackId: 'correlation id',
|
|
2169
|
+
locusId: 'locus id',
|
|
2170
|
+
meetingId: 'meeting id',
|
|
2171
|
+
reason: 'fake error',
|
|
2172
|
+
autoupload: true,
|
|
2173
|
+
locussessionid: 'locus session id',
|
|
2174
|
+
}));
|
|
2175
|
+
});
|
|
2176
|
+
});
|
|
1189
2177
|
});
|
|
1190
2178
|
});
|