@webex/plugin-meetings 2.60.0 → 2.60.1-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -8
- package/dist/annotation/annotation.types.d.ts +42 -0
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.d.ts +31 -0
- package/dist/annotation/constants.js +41 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.d.ts +117 -0
- package/dist/annotation/index.js +357 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.d.ts +8 -0
- package/dist/breakouts/breakout.js +215 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.d.ts +5 -0
- package/dist/breakouts/collection.js +22 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/breakouts/edit-lock-error.js +51 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.d.ts +8 -0
- package/dist/breakouts/events.js +44 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.d.ts +5 -0
- package/dist/breakouts/index.js +1047 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/breakouts/request.d.ts +22 -0
- package/dist/breakouts/request.js +77 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.d.ts +15 -0
- package/dist/breakouts/utils.js +64 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/browser-detection.js +2 -3
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +3 -4
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +1 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +1 -2
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +1 -2
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +1 -2
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +1 -2
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/common/errors/no-meeting-info.js +50 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/{reclaim-host-role-error.js → reclaim-host-role-errors.js} +7 -11
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/reconnection-in-progress.js +1 -2
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +1 -2
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +1 -2
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.d.ts +20 -8
- package/dist/common/errors/webex-errors.js +48 -28
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +1 -2
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +1 -2
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +1 -2
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +1 -2
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +1 -2
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +1 -2
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +2 -3
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.d.ts +3 -1
- package/dist/common/logs/request.js +8 -5
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.d.ts +9 -7
- package/dist/common/queue.js +22 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.d.ts +6 -7
- package/dist/config.js +8 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +234 -100
- package/dist/constants.js +433 -444
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +3 -6
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.d.ts +11 -1
- package/dist/controls-options-manager/enums.js +15 -6
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.d.ts +17 -1
- package/dist/controls-options-manager/index.js +127 -38
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.d.ts +43 -0
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.d.ts +1 -7
- package/dist/controls-options-manager/util.js +309 -19
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +121 -5
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.d.ts +2 -0
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.d.ts +27 -0
- package/dist/interceptors/locusRetry.js +94 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.d.ts +5 -0
- package/dist/interpretation/collection.js +22 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.d.ts +5 -0
- package/dist/interpretation/index.js +365 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.d.ts +5 -0
- package/dist/interpretation/siLanguage.js +24 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +100 -11
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -4
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +1 -2
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +1 -2
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.d.ts +57 -4
- package/dist/locus-info/index.js +425 -84
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +13 -5
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +58 -3
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.d.ts +66 -6
- package/dist/locus-info/parser.js +253 -80
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +97 -13
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.d.ts +2 -0
- package/dist/media/index.js +107 -319
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.d.ts +38 -53
- package/dist/media/properties.js +96 -153
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -22
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.d.ts +234 -230
- package/dist/mediaQualityMetrics/config.js +302 -498
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.d.ts +88 -0
- package/dist/meeting/in-meeting-actions.js +94 -3
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.d.ts +705 -520
- package/dist/meeting/index.js +5047 -3089
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/meeting/locusMediaRequest.js +291 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.d.ts +93 -25
- package/dist/meeting/muteState.js +224 -133
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.d.ts +82 -47
- package/dist/meeting/request.js +304 -199
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.d.ts +11 -0
- package/dist/meeting/request.type.js +7 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.d.ts +118 -1
- package/dist/meeting/util.js +676 -435
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.d.ts +20 -0
- package/dist/meeting/voicea-meeting.js +201 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.d.ts +13 -1
- package/dist/meeting-info/index.js +74 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/meeting-info/meeting-info-v2.js +200 -63
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +2 -3
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +39 -41
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.d.ts +17 -0
- package/dist/meetings/collection.js +42 -4
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.d.ts +114 -20
- package/dist/meetings/index.js +540 -126
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.d.ts +4 -0
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +4 -3
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +107 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.d.ts +13 -1
- package/dist/member/index.js +45 -2
- package/dist/member/index.js.map +1 -1
- package/dist/member/member.types.js +3 -4
- package/dist/member/member.types.js.map +1 -1
- package/dist/member/types.d.ts +32 -0
- package/dist/member/types.js +23 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +120 -29
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.d.ts +5 -0
- package/dist/members/collection.js +11 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.d.ts +56 -11
- package/dist/members/index.js +174 -47
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.d.ts +67 -11
- package/dist/members/request.js +102 -54
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +3 -4
- package/dist/members/types.js.map +1 -1
- package/dist/members/util.d.ts +214 -1
- package/dist/members/util.js +327 -284
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.d.ts +15 -6
- package/dist/metrics/constants.js +17 -9
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.d.ts +4 -111
- package/dist/metrics/index.js +4 -452
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.d.ts +118 -0
- package/dist/multistream/mediaRequestManager.js +344 -0
- package/dist/multistream/mediaRequestManager.js.map +1 -0
- package/dist/multistream/receiveSlot.d.ts +68 -0
- package/dist/multistream/receiveSlot.js +200 -0
- package/dist/multistream/receiveSlot.js.map +1 -0
- package/dist/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/multistream/receiveSlotManager.js +174 -0
- package/dist/multistream/receiveSlotManager.js.map +1 -0
- package/dist/multistream/remoteMedia.d.ts +72 -0
- package/dist/multistream/remoteMedia.js +268 -0
- package/dist/multistream/remoteMedia.js.map +1 -0
- package/dist/multistream/remoteMediaGroup.d.ts +47 -0
- package/dist/multistream/remoteMediaGroup.js +267 -0
- package/dist/multistream/remoteMediaGroup.js.map +1 -0
- package/dist/multistream/remoteMediaManager.d.ts +285 -0
- package/dist/multistream/remoteMediaManager.js +1211 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -0
- package/dist/multistream/sendSlotManager.d.ts +61 -0
- package/dist/multistream/sendSlotManager.js +236 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/networkQualityMonitor/index.js +5 -4
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +2 -3
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -3
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +1 -2
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/clusterReachability.d.ts +109 -0
- package/dist/reachability/clusterReachability.js +357 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.d.ts +61 -95
- package/dist/reachability/index.js +304 -392
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.d.ts +7 -3
- package/dist/reachability/request.js +18 -10
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.d.ts +8 -0
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reactions/constants.d.ts +3 -0
- package/dist/reactions/constants.js +12 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.d.ts +2 -2
- package/dist/reactions/reactions.js +4 -6
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.d.ts +23 -3
- package/dist/reactions/reactions.type.js +21 -23
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.d.ts +32 -8
- package/dist/reconnection-manager/index.js +285 -232
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +4 -5
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.d.ts +15 -1
- package/dist/recording-controller/index.js +57 -46
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.d.ts +5 -4
- package/dist/recording-controller/util.js +10 -10
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.d.ts +9 -47
- package/dist/roap/index.js +100 -238
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.d.ts +18 -12
- package/dist/roap/request.js +126 -180
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +27 -16
- package/dist/roap/turnDiscovery.js +115 -105
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.d.ts +4 -0
- package/dist/rtcMetrics/constants.js +11 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.d.ts +54 -0
- package/dist/rtcMetrics/index.js +140 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.d.ts +1 -83
- package/dist/statsAnalyzer/global.js +2 -85
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.d.ts +50 -30
- package/dist/statsAnalyzer/index.js +436 -511
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +8 -6
- package/dist/statsAnalyzer/mqaUtil.js +130 -90
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +1 -2
- package/dist/transcription/index.js.map +1 -1
- package/dist/webinar/collection.d.ts +16 -0
- package/dist/webinar/collection.js +43 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +68 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +39 -26
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +220 -0
- package/src/breakouts/breakout.ts +188 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +925 -0
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/webex-errors.ts +36 -12
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +6 -7
- package/src/constants.ts +265 -100
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +44 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +110 -0
- package/src/locus-info/index.ts +450 -61
- package/src/locus-info/infoUtils.ts +14 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +85 -2
- package/src/media/index.ts +153 -370
- package/src/media/properties.ts +106 -136
- package/src/media/util.ts +0 -21
- package/src/mediaQualityMetrics/config.ts +244 -377
- package/src/meeting/in-meeting-actions.ts +176 -0
- package/src/meeting/index.ts +4306 -2581
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +224 -138
- package/src/meeting/request.ts +214 -127
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/util.ts +687 -423
- package/src/meeting/voicea-meeting.ts +161 -0
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +163 -13
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +28 -28
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +529 -127
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +116 -5
- package/src/member/index.ts +43 -1
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +125 -28
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +187 -52
- package/src/members/request.ts +87 -27
- package/src/members/util.ts +332 -291
- package/src/metrics/constants.ts +15 -6
- package/src/metrics/index.ts +1 -471
- package/src/multistream/mediaRequestManager.ts +440 -0
- package/src/multistream/receiveSlot.ts +184 -0
- package/src/multistream/receiveSlotManager.ts +166 -0
- package/src/multistream/remoteMedia.ts +254 -0
- package/src/multistream/remoteMediaGroup.ts +284 -0
- package/src/multistream/remoteMediaManager.ts +1145 -0
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/networkQualityMonitor/index.ts +6 -6
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +246 -347
- package/src/reachability/request.ts +17 -8
- package/src/reachability/util.ts +24 -0
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.ts +4 -4
- package/src/reactions/reactions.type.ts +30 -4
- package/src/reconnection-manager/index.ts +168 -156
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +96 -241
- package/src/roap/request.ts +74 -148
- package/src/roap/turnDiscovery.ts +62 -56
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +124 -0
- package/src/statsAnalyzer/global.ts +1 -84
- package/src/statsAnalyzer/index.ts +479 -645
- package/src/statsAnalyzer/mqaUtil.ts +128 -126
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +320 -264
- package/test/integration/spec/space-meeting.js +77 -4
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +237 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1790 -0
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +323 -30
- package/test/unit/spec/locus-info/index.js +1438 -16
- package/test/unit/spec/locus-info/infoUtils.js +54 -16
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/lib/selfConstant.js +48 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfUtils.js +275 -0
- package/test/unit/spec/media/index.ts +290 -0
- package/test/unit/spec/media/properties.ts +75 -84
- package/test/unit/spec/meeting/in-meeting-actions.ts +86 -0
- package/test/unit/spec/meeting/index.js +8886 -2815
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +409 -213
- package/test/unit/spec/meeting/request.js +523 -43
- package/test/unit/spec/meeting/utils.js +834 -24
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +527 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1446 -217
- package/test/unit/spec/meetings/utils.js +202 -2
- package/test/unit/spec/member/index.js +32 -9
- package/test/unit/spec/member/util.js +499 -61
- package/test/unit/spec/members/index.js +394 -5
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +173 -38
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +1418 -0
- package/test/unit/spec/multistream/receiveSlot.ts +163 -0
- package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
- package/test/unit/spec/multistream/remoteMedia.ts +255 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +662 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +1924 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/networkQualityMonitor/index.js +4 -4
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +532 -24
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +163 -24
- package/test/unit/spec/recording-controller/index.js +293 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +187 -77
- package/test/unit/spec/roap/request.ts +255 -0
- package/test/unit/spec/roap/turnDiscovery.ts +86 -48
- package/test/unit/spec/rtcMetrics/index.ts +93 -0
- package/test/unit/spec/stats-analyzer/index.js +644 -165
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/constants.js +9 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -45
- package/test/utils/webex-config.js +4 -0
- package/test/utils/webex-test-users.js +7 -3
- package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
- package/dist/meeting/effectsState.d.ts +0 -42
- package/dist/meeting/effectsState.js +0 -260
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.d.ts +0 -169
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/peer-connection-manager/index.d.ts +0 -6
- package/dist/peer-connection-manager/index.js +0 -671
- package/dist/peer-connection-manager/index.js.map +0 -1
- package/dist/peer-connection-manager/util.d.ts +0 -6
- package/dist/peer-connection-manager/util.js +0 -110
- package/dist/peer-connection-manager/util.js.map +0 -1
- package/dist/roap/collection.d.ts +0 -10
- package/dist/roap/collection.js +0 -63
- package/dist/roap/collection.js.map +0 -1
- package/dist/roap/handler.d.ts +0 -47
- package/dist/roap/handler.js +0 -279
- package/dist/roap/handler.js.map +0 -1
- package/dist/roap/state.d.ts +0 -9
- package/dist/roap/state.js +0 -127
- package/dist/roap/state.js.map +0 -1
- package/dist/roap/util.d.ts +0 -2
- package/dist/roap/util.js +0 -76
- package/dist/roap/util.js.map +0 -1
- package/src/index.js +0 -15
- package/src/meeting/effectsState.ts +0 -209
- package/src/metrics/config.ts +0 -485
- package/src/peer-connection-manager/index.ts +0 -847
- package/src/peer-connection-manager/util.ts +0 -119
- package/src/roap/collection.ts +0 -62
- package/src/roap/handler.ts +0 -294
- package/src/roap/state.ts +0 -156
- package/src/roap/util.ts +0 -100
- package/test/unit/spec/meeting/effectsState.js +0 -281
- package/test/unit/spec/peerconnection-manager/index.js +0 -218
- package/test/unit/spec/peerconnection-manager/utils.js +0 -49
- package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -388
- package/test/unit/spec/roap/util.js +0 -30
- /package/dist/common/errors/{reclaim-host-role-error.d.ts → reclaim-host-role-errors.d.ts} +0 -0
- /package/src/common/errors/{reclaim-host-role-error.ts → reclaim-host-role-errors.ts} +0 -0
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import 'jsdom-global/register';
|
|
5
5
|
|
|
6
|
+
// Polyfill for crypto: https://github.com/jsdom/jsdom/issues/1612#issuecomment-663210638
|
|
7
|
+
import {Crypto} from '@peculiar/webcrypto';
|
|
8
|
+
global.crypto = new Crypto();
|
|
9
|
+
|
|
6
10
|
import Device from '@webex/internal-plugin-device';
|
|
7
11
|
import Mercury from '@webex/internal-plugin-mercury';
|
|
8
12
|
import {assert} from '@webex/test-helper-chai';
|
|
@@ -11,15 +15,16 @@ import sinon from 'sinon';
|
|
|
11
15
|
import uuid from 'uuid';
|
|
12
16
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
13
17
|
import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
18
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
14
19
|
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
15
|
-
import
|
|
16
|
-
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
20
|
+
import Meeting, {CallStateForMetrics} from '@webex/plugin-meetings/src/meeting';
|
|
17
21
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
18
22
|
import Meetings from '@webex/plugin-meetings/src/meetings';
|
|
19
23
|
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
20
24
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
21
25
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
22
26
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
27
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
23
28
|
|
|
24
29
|
import testUtils from '../../../utils/testUtils';
|
|
25
30
|
import {
|
|
@@ -30,6 +35,12 @@ import {
|
|
|
30
35
|
LOCUSINFO,
|
|
31
36
|
EVENT_TRIGGERS,
|
|
32
37
|
} from '../../../../src/constants';
|
|
38
|
+
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
|
|
39
|
+
import {forEach} from 'lodash';
|
|
40
|
+
import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
|
|
41
|
+
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
42
|
+
import {NoiseReductionEffect, VirtualBackgroundEffect} from '@webex/media-helpers';
|
|
43
|
+
import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
|
|
33
44
|
|
|
34
45
|
describe('plugin-meetings', () => {
|
|
35
46
|
const logger = {
|
|
@@ -41,6 +52,8 @@ describe('plugin-meetings', () => {
|
|
|
41
52
|
debug: () => {},
|
|
42
53
|
};
|
|
43
54
|
|
|
55
|
+
let triggerProxyStub;
|
|
56
|
+
|
|
44
57
|
beforeEach(() => {
|
|
45
58
|
StaticConfig.set({
|
|
46
59
|
bandwidth: {
|
|
@@ -52,7 +65,7 @@ describe('plugin-meetings', () => {
|
|
|
52
65
|
verboseEvents: true,
|
|
53
66
|
enable: false,
|
|
54
67
|
});
|
|
55
|
-
|
|
68
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
56
69
|
});
|
|
57
70
|
|
|
58
71
|
let webex;
|
|
@@ -61,15 +74,20 @@ describe('plugin-meetings', () => {
|
|
|
61
74
|
let url1;
|
|
62
75
|
let test1;
|
|
63
76
|
let test2;
|
|
77
|
+
let locusInfo;
|
|
64
78
|
|
|
65
79
|
describe('meetings index', () => {
|
|
66
80
|
beforeEach(() => {
|
|
67
81
|
MeetingsUtil.checkH264Support = sinon.stub();
|
|
68
|
-
|
|
82
|
+
uuid1 = uuid.v4();
|
|
69
83
|
url1 = `https://example.com/${uuid.v4()}`;
|
|
70
84
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
71
85
|
test1 = `test-${uuid.v4()}`;
|
|
72
86
|
test2 = `test2-${uuid.v4()}`;
|
|
87
|
+
locusInfo = {
|
|
88
|
+
parse: sinon.stub().returns(true),
|
|
89
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
90
|
+
};
|
|
73
91
|
webex = new MockWebex({
|
|
74
92
|
children: {
|
|
75
93
|
device: Device,
|
|
@@ -108,6 +126,7 @@ describe('plugin-meetings', () => {
|
|
|
108
126
|
});
|
|
109
127
|
|
|
110
128
|
Object.assign(webex.internal, {
|
|
129
|
+
llm: {on: sinon.stub()},
|
|
111
130
|
device: {
|
|
112
131
|
deviceType: 'FAKE_DEVICE',
|
|
113
132
|
register: sinon.stub().returns(Promise.resolve()),
|
|
@@ -151,6 +170,10 @@ describe('plugin-meetings', () => {
|
|
|
151
170
|
webex.emit('ready');
|
|
152
171
|
});
|
|
153
172
|
|
|
173
|
+
afterEach(() => {
|
|
174
|
+
sinon.restore();
|
|
175
|
+
});
|
|
176
|
+
|
|
154
177
|
it('has a webex instance with a meetings property', () => {
|
|
155
178
|
assert.exists(webex, 'webex was initialized with children');
|
|
156
179
|
assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
|
|
@@ -217,30 +240,15 @@ describe('plugin-meetings', () => {
|
|
|
217
240
|
});
|
|
218
241
|
});
|
|
219
242
|
|
|
220
|
-
describe('#
|
|
221
|
-
it('should have
|
|
222
|
-
assert.equal(typeof webex.meetings.
|
|
243
|
+
describe('#_toggleTcpReachability', () => {
|
|
244
|
+
it('should have _toggleTcpReachability', () => {
|
|
245
|
+
assert.equal(typeof webex.meetings._toggleTcpReachability, 'function');
|
|
223
246
|
});
|
|
224
247
|
|
|
225
248
|
describe('success', () => {
|
|
226
|
-
it('should update meetings to do
|
|
227
|
-
webex.meetings.
|
|
228
|
-
assert.equal(webex.meetings.config.experimental.
|
|
229
|
-
|
|
230
|
-
webex.meetings._toggleTurnDiscovery(false);
|
|
231
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, false);
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
describe('failure', () => {
|
|
236
|
-
it('should not accept non boolean input', () => {
|
|
237
|
-
const currentEnableTurnDiscovery = webex.meetings.config.experimental.enableTurnDiscovery;
|
|
238
|
-
|
|
239
|
-
webex.meetings._toggleTurnDiscovery('test');
|
|
240
|
-
assert.equal(
|
|
241
|
-
webex.meetings.config.experimental.enableAdhocMeetings,
|
|
242
|
-
currentEnableTurnDiscovery
|
|
243
|
-
);
|
|
249
|
+
it('should update meetings to do TCP reachability', () => {
|
|
250
|
+
webex.meetings._toggleTcpReachability(true);
|
|
251
|
+
assert.equal(webex.meetings.config.experimental.enableTcpReachability, true);
|
|
244
252
|
});
|
|
245
253
|
});
|
|
246
254
|
});
|
|
@@ -338,37 +346,110 @@ describe('plugin-meetings', () => {
|
|
|
338
346
|
});
|
|
339
347
|
});
|
|
340
348
|
|
|
349
|
+
describe('virtual background effect', () => {
|
|
350
|
+
beforeEach(() => {
|
|
351
|
+
webex.credentials = {
|
|
352
|
+
supertoken: {
|
|
353
|
+
access_token: 'fake_token',
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('creates background effect', async () => {
|
|
359
|
+
const result = await webex.meetings.createVirtualBackgroundEffect();
|
|
360
|
+
|
|
361
|
+
assert.exists(result);
|
|
362
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
363
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
364
|
+
assert.deepEqual(result.options, {
|
|
365
|
+
mode: 'BLUR',
|
|
366
|
+
blurStrength: 'STRONG',
|
|
367
|
+
generator: 'worker',
|
|
368
|
+
quality: 'LOW',
|
|
369
|
+
authToken: 'fake_token',
|
|
370
|
+
mirror: false,
|
|
371
|
+
});
|
|
372
|
+
assert.exists(result.enable);
|
|
373
|
+
assert.exists(result.disable);
|
|
374
|
+
assert.exists(result.dispose);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('creates background effect with custom options passed', async () => {
|
|
378
|
+
const effectOptions = {
|
|
379
|
+
generator: 'local',
|
|
380
|
+
frameRate: 45,
|
|
381
|
+
mode: 'IMAGE',
|
|
382
|
+
mirror: false,
|
|
383
|
+
quality: 'HIGH',
|
|
384
|
+
blurStrength: 'STRONG',
|
|
385
|
+
bgImageUrl: 'https://test.webex.com/landscape.5a535788.jpg',
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const result = await webex.meetings.createVirtualBackgroundEffect(effectOptions);
|
|
389
|
+
|
|
390
|
+
assert.exists(result);
|
|
391
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
392
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
393
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
394
|
+
assert.exists(result.enable);
|
|
395
|
+
assert.exists(result.disable);
|
|
396
|
+
assert.exists(result.dispose);
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
describe('noise reduction effect', () => {
|
|
401
|
+
beforeEach(() => {
|
|
402
|
+
webex.credentials = {
|
|
403
|
+
supertoken: {
|
|
404
|
+
access_token: 'fake_token',
|
|
405
|
+
},
|
|
406
|
+
};
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('creates noise reduction effect', async () => {
|
|
410
|
+
const result = await webex.meetings.createNoiseReductionEffect({audioContext: {}});
|
|
411
|
+
|
|
412
|
+
assert.exists(result);
|
|
413
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
414
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
415
|
+
assert.deepEqual(result.options, {
|
|
416
|
+
authToken: 'fake_token',
|
|
417
|
+
audioContext: {},
|
|
418
|
+
});
|
|
419
|
+
assert.exists(result.enable);
|
|
420
|
+
assert.exists(result.disable);
|
|
421
|
+
assert.exists(result.dispose);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it('creates noise reduction effect with custom options passed', async () => {
|
|
425
|
+
const effectOptions = {
|
|
426
|
+
audioContext: {},
|
|
427
|
+
mode: 'WORKLET',
|
|
428
|
+
env: 'prod',
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const result = await webex.meetings.createNoiseReductionEffect(effectOptions);
|
|
432
|
+
|
|
433
|
+
assert.exists(result);
|
|
434
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
435
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
436
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
437
|
+
assert.exists(result.enable);
|
|
438
|
+
assert.exists(result.disable);
|
|
439
|
+
assert.exists(result.dispose);
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
|
|
341
443
|
describe('gets', () => {
|
|
342
444
|
describe('#getReachability', () => {
|
|
343
445
|
it('should have #getReachability', () => {
|
|
344
446
|
assert.exists(webex.meetings.getReachability);
|
|
345
447
|
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const reachability = webex.meetings.getReachability();
|
|
349
|
-
|
|
350
|
-
assert.notExists(
|
|
351
|
-
reachability,
|
|
352
|
-
'reachability is undefined because #setReachability has not been called'
|
|
353
|
-
);
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
describe('after #setReachability', () => {
|
|
357
|
-
beforeEach(() => {
|
|
358
|
-
webex.meetings.setReachability();
|
|
359
|
-
const reachabilityMocker = webex.meetings.getReachability();
|
|
360
|
-
|
|
361
|
-
sinon.stub(reachabilityMocker, 'gatherReachability').returns(true);
|
|
362
|
-
});
|
|
363
|
-
it('gets the reachability data instance from webex.meetings', () => {
|
|
364
|
-
const reachability = webex.meetings.getReachability();
|
|
448
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
449
|
+
const reachability = webex.meetings.getReachability();
|
|
365
450
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
'reachability is defined because #setReachability has been called'
|
|
369
|
-
);
|
|
370
|
-
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
371
|
-
});
|
|
451
|
+
assert.exists(reachability, 'reachability is defined');
|
|
452
|
+
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
372
453
|
});
|
|
373
454
|
});
|
|
374
455
|
describe('#getPersonalMeetingRoom', () => {
|
|
@@ -443,21 +524,16 @@ describe('plugin-meetings', () => {
|
|
|
443
524
|
);
|
|
444
525
|
});
|
|
445
526
|
describe('when meeting is returned', () => {
|
|
446
|
-
let parse;
|
|
447
|
-
|
|
448
527
|
beforeEach(() => {
|
|
449
|
-
parse = sinon.stub().returns(true);
|
|
450
528
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
451
|
-
locusInfo
|
|
452
|
-
parse,
|
|
453
|
-
},
|
|
529
|
+
locusInfo,
|
|
454
530
|
});
|
|
455
531
|
});
|
|
456
532
|
it('tests the sync meeting calls for existing meeting', async () => {
|
|
457
533
|
await webex.meetings.syncMeetings();
|
|
458
534
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
459
535
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
460
|
-
assert.calledOnce(parse);
|
|
536
|
+
assert.calledOnce(locusInfo.parse);
|
|
461
537
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
462
538
|
});
|
|
463
539
|
});
|
|
@@ -470,6 +546,7 @@ describe('plugin-meetings', () => {
|
|
|
470
546
|
webex.meetings.create = sinon.stub().returns(
|
|
471
547
|
Promise.resolve({
|
|
472
548
|
locusInfo: {
|
|
549
|
+
...locusInfo,
|
|
473
550
|
initialSetup,
|
|
474
551
|
},
|
|
475
552
|
})
|
|
@@ -478,7 +555,7 @@ describe('plugin-meetings', () => {
|
|
|
478
555
|
it('tests the sync meeting calls for not existing meeting', async () => {
|
|
479
556
|
await webex.meetings.syncMeetings();
|
|
480
557
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
481
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
558
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
482
559
|
assert.calledOnce(initialSetup);
|
|
483
560
|
assert.calledOnce(webex.meetings.create);
|
|
484
561
|
assert.calledWith(webex.meetings.request.getActiveMeetings);
|
|
@@ -495,46 +572,71 @@ describe('plugin-meetings', () => {
|
|
|
495
572
|
});
|
|
496
573
|
});
|
|
497
574
|
});
|
|
498
|
-
describe('
|
|
499
|
-
let initialSetup;
|
|
500
|
-
let parse;
|
|
575
|
+
describe('when destroying meeting is needed', () => {
|
|
501
576
|
let destroySpy;
|
|
502
577
|
|
|
578
|
+
const meetingCollectionMeetings = {
|
|
579
|
+
stillValidLocusMeeting: {
|
|
580
|
+
locusUrl: 'still-valid-locus-url',
|
|
581
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
582
|
+
},
|
|
583
|
+
noLongerValidLocusMeeting: {
|
|
584
|
+
locusUrl: 'no-longer-valid-locus-url',
|
|
585
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
586
|
+
},
|
|
587
|
+
otherNonLocusMeeting1: {
|
|
588
|
+
locusUrl: null,
|
|
589
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
590
|
+
},
|
|
591
|
+
otherNonLocusMeeting2: {
|
|
592
|
+
locusUrl: undefined,
|
|
593
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
|
|
503
597
|
beforeEach(() => {
|
|
504
598
|
destroySpy = sinon.spy(webex.meetings, 'destroy');
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
locusInfo: {
|
|
509
|
-
parse,
|
|
510
|
-
},
|
|
511
|
-
sendCallAnalyzerMetrics: sinon.stub(),
|
|
512
|
-
});
|
|
513
|
-
webex.meetings.meetingCollection.getAll = sinon.stub().returns({
|
|
514
|
-
meetingutk: {
|
|
515
|
-
locusUrl: 'fdfdjfdhj',
|
|
516
|
-
sendCallAnalyzerMetrics: sinon.stub(),
|
|
517
|
-
},
|
|
518
|
-
});
|
|
519
|
-
webex.meetings.create = sinon.stub().returns(
|
|
520
|
-
Promise.resolve({
|
|
521
|
-
locusInfo: {
|
|
522
|
-
initialSetup,
|
|
523
|
-
},
|
|
524
|
-
sendCallAnalyzerMetrics: sinon.stub(),
|
|
525
|
-
})
|
|
526
|
-
);
|
|
599
|
+
webex.meetings.meetingCollection.getAll = sinon
|
|
600
|
+
.stub()
|
|
601
|
+
.returns(meetingCollectionMeetings);
|
|
527
602
|
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
528
603
|
Promise.resolve({
|
|
529
|
-
loci: [],
|
|
604
|
+
loci: [{url: 'still-valid-locus-url'}],
|
|
530
605
|
})
|
|
531
606
|
);
|
|
532
607
|
MeetingUtil.cleanUp = sinon.stub().returns(Promise.resolve());
|
|
533
608
|
});
|
|
534
|
-
|
|
609
|
+
|
|
610
|
+
it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings is not defined', async () => {
|
|
535
611
|
await webex.meetings.syncMeetings();
|
|
536
612
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
537
|
-
assert.calledOnce(
|
|
613
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
614
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
615
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
|
|
616
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
|
|
617
|
+
assert.callCount(destroySpy, 3);
|
|
618
|
+
|
|
619
|
+
assert.callCount(MeetingUtil.cleanUp, 3);
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings === true', async () => {
|
|
623
|
+
await webex.meetings.syncMeetings({keepOnlyLocusMeetings: true});
|
|
624
|
+
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
625
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
626
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
627
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
|
|
628
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
|
|
629
|
+
assert.callCount(destroySpy, 3);
|
|
630
|
+
|
|
631
|
+
assert.callCount(MeetingUtil.cleanUp, 3);
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
it('destroy any LOCUS meetings that have no active locus url if keepOnlyLocusMeetings === false', async () => {
|
|
635
|
+
await webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
|
|
636
|
+
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
637
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
638
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
639
|
+
assert.callCount(destroySpy, 1);
|
|
538
640
|
|
|
539
641
|
assert.calledOnce(MeetingUtil.cleanUp);
|
|
540
642
|
});
|
|
@@ -574,14 +676,139 @@ describe('plugin-meetings', () => {
|
|
|
574
676
|
});
|
|
575
677
|
});
|
|
576
678
|
|
|
679
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
680
|
+
const correlationId = 'my-correlationId';
|
|
681
|
+
const callStateForMetrics = {
|
|
682
|
+
correlationId: 'my-correlationId2',
|
|
683
|
+
joinTrigger: 'my-join-trigger',
|
|
684
|
+
loginType: 'my-login-type',
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
it('should call setCallStateForMetrics on any pre-existing meeting', async () => {
|
|
688
|
+
const fakeMeeting = {setCallStateForMetrics: sinon.mock()};
|
|
689
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(fakeMeeting);
|
|
690
|
+
await webex.meetings.create(
|
|
691
|
+
test1,
|
|
692
|
+
test2,
|
|
693
|
+
FAKE_USE_RANDOM_DELAY,
|
|
694
|
+
{},
|
|
695
|
+
correlationId,
|
|
696
|
+
true,
|
|
697
|
+
callStateForMetrics
|
|
698
|
+
);
|
|
699
|
+
assert.calledOnceWithExactly(fakeMeeting.setCallStateForMetrics, {
|
|
700
|
+
...callStateForMetrics,
|
|
701
|
+
correlationId,
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
706
|
+
const create = webex.meetings.create(...createParameters);
|
|
707
|
+
|
|
708
|
+
assert.exists(create.then);
|
|
709
|
+
await create;
|
|
710
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
711
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
712
|
+
};
|
|
713
|
+
|
|
577
714
|
it('calls createMeeting and returns its promise', async () => {
|
|
578
|
-
|
|
579
|
-
|
|
715
|
+
await checkCallCreateMeeting(
|
|
716
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true],
|
|
717
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true]
|
|
718
|
+
);
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it('calls createMeeting, pass the meeting info param and returns its promise', async () => {
|
|
722
|
+
const meetingInfo = {};
|
|
723
|
+
await checkCallCreateMeeting(
|
|
724
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, undefined, meetingInfo],
|
|
725
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true, meetingInfo]
|
|
726
|
+
);
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
it('calls createMeeting, pass the meeting info and meetingLookupURL param and returns its promise', async () => {
|
|
730
|
+
const meetingInfo = {};
|
|
731
|
+
await checkCallCreateMeeting(
|
|
732
|
+
[
|
|
733
|
+
test1,
|
|
734
|
+
test2,
|
|
735
|
+
FAKE_USE_RANDOM_DELAY,
|
|
736
|
+
{},
|
|
737
|
+
correlationId,
|
|
738
|
+
true,
|
|
739
|
+
undefined,
|
|
740
|
+
meetingInfo,
|
|
741
|
+
'meetingLookupURL',
|
|
742
|
+
],
|
|
743
|
+
[
|
|
744
|
+
test1,
|
|
745
|
+
test2,
|
|
746
|
+
FAKE_USE_RANDOM_DELAY,
|
|
747
|
+
{},
|
|
748
|
+
{correlationId},
|
|
749
|
+
true,
|
|
750
|
+
meetingInfo,
|
|
751
|
+
'meetingLookupURL',
|
|
752
|
+
]
|
|
753
|
+
);
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
757
|
+
await checkCallCreateMeeting(
|
|
758
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
|
|
759
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
760
|
+
);
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
764
|
+
await checkCallCreateMeeting(
|
|
765
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false],
|
|
766
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
767
|
+
);
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
it('calls createMeeting with callStateForMetrics and returns its promise', async () => {
|
|
771
|
+
await checkCallCreateMeeting(
|
|
772
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, undefined, true, callStateForMetrics],
|
|
773
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, callStateForMetrics, true]
|
|
774
|
+
);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
it('calls createMeeting with callStateForMetrics overwritten with correlationId and returns its promise', async () => {
|
|
778
|
+
await checkCallCreateMeeting(
|
|
779
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, callStateForMetrics],
|
|
780
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {...callStateForMetrics, correlationId}, true]
|
|
781
|
+
);
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
785
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
786
|
+
const correlationId = 'my-correlationId';
|
|
787
|
+
|
|
788
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
789
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
790
|
+
joinTXId: 'TSmrX61wNF',
|
|
791
|
+
};
|
|
792
|
+
const create = webex.meetings.create(
|
|
793
|
+
test1,
|
|
794
|
+
test2,
|
|
795
|
+
FAKE_USE_RANDOM_DELAY,
|
|
796
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
797
|
+
correlationId
|
|
798
|
+
);
|
|
580
799
|
|
|
581
800
|
assert.exists(create.then);
|
|
582
801
|
await create;
|
|
583
802
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
584
|
-
assert.calledWith(
|
|
803
|
+
assert.calledWith(
|
|
804
|
+
webex.meetings.createMeeting,
|
|
805
|
+
test1,
|
|
806
|
+
test2,
|
|
807
|
+
FAKE_USE_RANDOM_DELAY,
|
|
808
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
809
|
+
{correlationId},
|
|
810
|
+
false
|
|
811
|
+
);
|
|
585
812
|
});
|
|
586
813
|
|
|
587
814
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -677,45 +904,51 @@ describe('plugin-meetings', () => {
|
|
|
677
904
|
});
|
|
678
905
|
describe('#handleLocusEvent', () => {
|
|
679
906
|
describe('there was a meeting', () => {
|
|
680
|
-
let parse;
|
|
681
|
-
|
|
682
907
|
beforeEach(() => {
|
|
683
|
-
parse = sinon.stub().returns(true);
|
|
684
908
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
685
|
-
locusInfo
|
|
686
|
-
parse,
|
|
687
|
-
},
|
|
909
|
+
locusInfo,
|
|
688
910
|
});
|
|
689
911
|
});
|
|
690
|
-
it('should parse the meeting info', () => {
|
|
912
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
913
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
691
914
|
webex.meetings.handleLocusEvent({
|
|
692
915
|
locusUrl: url1,
|
|
693
916
|
});
|
|
694
917
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
695
918
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
696
|
-
assert.calledOnce(parse);
|
|
919
|
+
assert.calledOnce(locusInfo.parse);
|
|
920
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
697
921
|
assert.calledWith(
|
|
698
|
-
parse,
|
|
922
|
+
locusInfo.parse,
|
|
699
923
|
{
|
|
700
|
-
locusInfo
|
|
701
|
-
parse,
|
|
702
|
-
},
|
|
924
|
+
locusInfo,
|
|
703
925
|
},
|
|
704
926
|
{
|
|
705
927
|
locusUrl: url1,
|
|
706
928
|
}
|
|
707
929
|
);
|
|
708
930
|
});
|
|
931
|
+
|
|
932
|
+
it('should not update main session locus cache', () => {
|
|
933
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
934
|
+
webex.meetings.handleLocusEvent({
|
|
935
|
+
locusUrl: url1,
|
|
936
|
+
});
|
|
937
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
938
|
+
});
|
|
709
939
|
});
|
|
710
940
|
describe('there was not a meeting', () => {
|
|
711
941
|
let initialSetup;
|
|
942
|
+
const webExMeetingId = '123456';
|
|
712
943
|
|
|
713
944
|
beforeEach(() => {
|
|
714
945
|
initialSetup = sinon.stub().returns(true);
|
|
715
946
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
716
947
|
webex.meetings.create = sinon.stub().returns(
|
|
717
948
|
Promise.resolve({
|
|
949
|
+
id: 'meeting-id',
|
|
718
950
|
locusInfo: {
|
|
951
|
+
...locusInfo,
|
|
719
952
|
initialSetup,
|
|
720
953
|
},
|
|
721
954
|
})
|
|
@@ -735,12 +968,20 @@ describe('plugin-meetings', () => {
|
|
|
735
968
|
callbackAddress: uri1,
|
|
736
969
|
},
|
|
737
970
|
},
|
|
971
|
+
info: {
|
|
972
|
+
webExMeetingId,
|
|
973
|
+
},
|
|
738
974
|
},
|
|
739
975
|
eventType: 'locus.difference',
|
|
740
976
|
locusUrl: url1,
|
|
741
977
|
});
|
|
742
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
978
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
743
979
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
980
|
+
assert.calledWith(
|
|
981
|
+
webex.meetings.meetingCollection.getByKey,
|
|
982
|
+
'meetingNumber',
|
|
983
|
+
webExMeetingId
|
|
984
|
+
);
|
|
744
985
|
assert.calledOnce(initialSetup);
|
|
745
986
|
assert.calledWith(initialSetup, {
|
|
746
987
|
id: uuid1,
|
|
@@ -754,6 +995,9 @@ describe('plugin-meetings', () => {
|
|
|
754
995
|
callbackAddress: uri1,
|
|
755
996
|
},
|
|
756
997
|
},
|
|
998
|
+
info: {
|
|
999
|
+
webExMeetingId,
|
|
1000
|
+
},
|
|
757
1001
|
});
|
|
758
1002
|
});
|
|
759
1003
|
it('should setup the meeting by difference event without replaces', async () => {
|
|
@@ -765,12 +1009,20 @@ describe('plugin-meetings', () => {
|
|
|
765
1009
|
callbackAddress: uri1,
|
|
766
1010
|
},
|
|
767
1011
|
},
|
|
1012
|
+
info: {
|
|
1013
|
+
webExMeetingId,
|
|
1014
|
+
},
|
|
768
1015
|
},
|
|
769
1016
|
eventType: 'locus.difference',
|
|
770
1017
|
locusUrl: url1,
|
|
771
1018
|
});
|
|
772
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1019
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
773
1020
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1021
|
+
assert.calledWith(
|
|
1022
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1023
|
+
'meetingNumber',
|
|
1024
|
+
webExMeetingId
|
|
1025
|
+
);
|
|
774
1026
|
assert.calledOnce(initialSetup);
|
|
775
1027
|
assert.calledWith(initialSetup, {
|
|
776
1028
|
id: uuid1,
|
|
@@ -779,8 +1031,44 @@ describe('plugin-meetings', () => {
|
|
|
779
1031
|
callbackAddress: uri1,
|
|
780
1032
|
},
|
|
781
1033
|
},
|
|
1034
|
+
info: {
|
|
1035
|
+
webExMeetingId,
|
|
1036
|
+
},
|
|
1037
|
+
});
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
it('sends client event correctly on finally', async () => {
|
|
1041
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
1042
|
+
|
|
1043
|
+
await webex.meetings.handleLocusEvent({
|
|
1044
|
+
locus: {
|
|
1045
|
+
id: uuid1,
|
|
1046
|
+
self: {
|
|
1047
|
+
callBackInfo: {
|
|
1048
|
+
callbackAddress: uri1,
|
|
1049
|
+
},
|
|
1050
|
+
},
|
|
1051
|
+
info: {
|
|
1052
|
+
webExMeetingId,
|
|
1053
|
+
},
|
|
1054
|
+
},
|
|
1055
|
+
eventType: 'locus.difference',
|
|
1056
|
+
locusUrl: url1,
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
await testUtils.flushPromises();
|
|
1060
|
+
|
|
1061
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
1062
|
+
name: 'client.call.remote-started',
|
|
1063
|
+
payload: {
|
|
1064
|
+
trigger: 'mercury-event',
|
|
1065
|
+
},
|
|
1066
|
+
options: {
|
|
1067
|
+
meetingId: 'meeting-id',
|
|
1068
|
+
},
|
|
782
1069
|
});
|
|
783
1070
|
});
|
|
1071
|
+
|
|
784
1072
|
it('should setup the meeting by a not difference event', async () => {
|
|
785
1073
|
await webex.meetings.handleLocusEvent({
|
|
786
1074
|
locus: {
|
|
@@ -790,12 +1078,20 @@ describe('plugin-meetings', () => {
|
|
|
790
1078
|
callbackAddress: uri1,
|
|
791
1079
|
},
|
|
792
1080
|
},
|
|
1081
|
+
info: {
|
|
1082
|
+
webExMeetingId,
|
|
1083
|
+
},
|
|
793
1084
|
},
|
|
794
1085
|
eventType: test1,
|
|
795
1086
|
locusUrl: url1,
|
|
796
1087
|
});
|
|
797
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1088
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
798
1089
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1090
|
+
assert.calledWith(
|
|
1091
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1092
|
+
'meetingNumber',
|
|
1093
|
+
webExMeetingId
|
|
1094
|
+
);
|
|
799
1095
|
assert.calledOnce(initialSetup);
|
|
800
1096
|
assert.calledWith(initialSetup, {
|
|
801
1097
|
id: uuid1,
|
|
@@ -804,6 +1100,9 @@ describe('plugin-meetings', () => {
|
|
|
804
1100
|
callbackAddress: uri1,
|
|
805
1101
|
},
|
|
806
1102
|
},
|
|
1103
|
+
info: {
|
|
1104
|
+
webExMeetingId,
|
|
1105
|
+
},
|
|
807
1106
|
});
|
|
808
1107
|
});
|
|
809
1108
|
|
|
@@ -826,7 +1125,7 @@ describe('plugin-meetings', () => {
|
|
|
826
1125
|
|
|
827
1126
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
828
1127
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
|
|
829
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1128
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
830
1129
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
831
1130
|
'locusUrl',
|
|
832
1131
|
url1,
|
|
@@ -843,7 +1142,7 @@ describe('plugin-meetings', () => {
|
|
|
843
1142
|
});
|
|
844
1143
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
845
1144
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
|
|
846
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1145
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
847
1146
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
848
1147
|
'locusUrl',
|
|
849
1148
|
url1,
|
|
@@ -866,7 +1165,6 @@ describe('plugin-meetings', () => {
|
|
|
866
1165
|
});
|
|
867
1166
|
describe('#createMeeting', () => {
|
|
868
1167
|
beforeEach(() => {
|
|
869
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
870
1168
|
webex.internal.device.userId = uuid1;
|
|
871
1169
|
webex.internal.device.url = url1;
|
|
872
1170
|
MeetingCollection.set = sinon.stub().returns(true);
|
|
@@ -875,6 +1173,10 @@ describe('plugin-meetings', () => {
|
|
|
875
1173
|
});
|
|
876
1174
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
877
1175
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1176
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
1177
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
1178
|
+
joinTXId: 'TSmrX61wNF',
|
|
1179
|
+
};
|
|
878
1180
|
|
|
879
1181
|
beforeEach(() => {
|
|
880
1182
|
clock = sinon.useFakeTimers();
|
|
@@ -904,13 +1206,37 @@ describe('plugin-meetings', () => {
|
|
|
904
1206
|
meeting,
|
|
905
1207
|
destination,
|
|
906
1208
|
type,
|
|
907
|
-
|
|
1209
|
+
extraParams = {},
|
|
1210
|
+
expectedMeetingData = {},
|
|
1211
|
+
sendCAevents = false,
|
|
1212
|
+
injectMeetingInfo = false
|
|
908
1213
|
) => {
|
|
909
|
-
|
|
1214
|
+
if (injectMeetingInfo) {
|
|
1215
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1216
|
+
} else {
|
|
1217
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
910
1220
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
911
1221
|
assert.notCalled(setTimeoutSpy);
|
|
912
|
-
assert.
|
|
913
|
-
|
|
1222
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1223
|
+
|
|
1224
|
+
if (injectMeetingInfo) {
|
|
1225
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1226
|
+
} else {
|
|
1227
|
+
assert.calledWith(
|
|
1228
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1229
|
+
destination,
|
|
1230
|
+
type,
|
|
1231
|
+
null,
|
|
1232
|
+
null,
|
|
1233
|
+
undefined,
|
|
1234
|
+
undefined,
|
|
1235
|
+
extraParams,
|
|
1236
|
+
{meetingId: meeting.id, sendCAevents}
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
914
1240
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
915
1241
|
|
|
916
1242
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -919,6 +1245,21 @@ describe('plugin-meetings', () => {
|
|
|
919
1245
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
920
1246
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
921
1247
|
}
|
|
1248
|
+
if (expectedMeetingData.correlationId) {
|
|
1249
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1250
|
+
}
|
|
1251
|
+
if (expectedMeetingData.callStateForMetrics) {
|
|
1252
|
+
assert.deepEqual(
|
|
1253
|
+
meeting.callStateForMetrics,
|
|
1254
|
+
expectedMeetingData.callStateForMetrics
|
|
1255
|
+
);
|
|
1256
|
+
}
|
|
1257
|
+
if (expectedMeetingData.meetingLookupUrl) {
|
|
1258
|
+
assert.equal(
|
|
1259
|
+
meeting.meetingInfo.meetingLookupUrl,
|
|
1260
|
+
expectedMeetingData.meetingLookupUrl
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
922
1263
|
assert.equal(meeting.destination, destination);
|
|
923
1264
|
assert.equal(meeting.destinationType, type);
|
|
924
1265
|
assert.calledWith(
|
|
@@ -948,107 +1289,207 @@ describe('plugin-meetings', () => {
|
|
|
948
1289
|
const expectedMeetingData = {
|
|
949
1290
|
permissionToken: 'PT',
|
|
950
1291
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
1292
|
+
correlationId: meeting.id,
|
|
951
1293
|
};
|
|
952
1294
|
|
|
953
|
-
checkCreateWithoutDelay(
|
|
1295
|
+
checkCreateWithoutDelay(
|
|
1296
|
+
meeting,
|
|
1297
|
+
'test destination',
|
|
1298
|
+
'test type',
|
|
1299
|
+
{},
|
|
1300
|
+
expectedMeetingData
|
|
1301
|
+
);
|
|
954
1302
|
});
|
|
955
1303
|
|
|
956
|
-
it('
|
|
957
|
-
const
|
|
958
|
-
const expectedMeetingData = {
|
|
1304
|
+
it('accepts injected meeting info', async () => {
|
|
1305
|
+
const meetingInfo = {
|
|
959
1306
|
permissionToken: 'PT',
|
|
960
1307
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
961
1308
|
};
|
|
962
1309
|
|
|
963
|
-
|
|
1310
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1311
|
+
'test destination',
|
|
1312
|
+
'test type',
|
|
1313
|
+
false,
|
|
1314
|
+
{},
|
|
1315
|
+
undefined,
|
|
1316
|
+
false,
|
|
1317
|
+
meetingInfo
|
|
1318
|
+
);
|
|
1319
|
+
|
|
1320
|
+
const expectedMeetingData = {
|
|
1321
|
+
...meetingInfo,
|
|
1322
|
+
correlationId: meeting.id,
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
checkCreateWithoutDelay(
|
|
964
1326
|
meeting,
|
|
965
|
-
|
|
966
|
-
'
|
|
1327
|
+
'test destination',
|
|
1328
|
+
'test type',
|
|
1329
|
+
{},
|
|
1330
|
+
expectedMeetingData,
|
|
1331
|
+
false,
|
|
1332
|
+
true
|
|
967
1333
|
);
|
|
968
|
-
checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
|
|
969
1334
|
});
|
|
970
1335
|
|
|
971
|
-
it('
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
info: {
|
|
976
|
-
webExMeetingId: 'locusMeetingId',
|
|
977
|
-
sipUri: 'locusSipUri',
|
|
978
|
-
owner: 'locusOwner',
|
|
979
|
-
},
|
|
980
|
-
meeting: {
|
|
981
|
-
startTime: fakeMeetingStartTimeString,
|
|
982
|
-
},
|
|
983
|
-
fullState: {
|
|
984
|
-
active: false,
|
|
985
|
-
},
|
|
1336
|
+
it('accepts injected meeting info with meeting lookup url', async () => {
|
|
1337
|
+
const meetingInfo = {
|
|
1338
|
+
permissionToken: 'PT',
|
|
1339
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
986
1340
|
};
|
|
987
1341
|
|
|
988
1342
|
const meeting = await webex.meetings.createMeeting(
|
|
989
|
-
|
|
1343
|
+
'test destination',
|
|
990
1344
|
'test type',
|
|
991
|
-
|
|
1345
|
+
false,
|
|
1346
|
+
{},
|
|
1347
|
+
undefined,
|
|
1348
|
+
false,
|
|
1349
|
+
meetingInfo,
|
|
1350
|
+
'meetingLookupUrl'
|
|
992
1351
|
);
|
|
993
1352
|
|
|
994
|
-
|
|
1353
|
+
const expectedMeetingData = {
|
|
1354
|
+
...meetingInfo,
|
|
1355
|
+
meetingLookupUrl: 'meetingLookupUrl',
|
|
1356
|
+
correlationId: meeting.id,
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
checkCreateWithoutDelay(
|
|
995
1360
|
meeting,
|
|
996
|
-
|
|
997
|
-
'
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
// Parse meeting info with locus object
|
|
1003
|
-
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1004
|
-
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1005
|
-
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1006
|
-
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1007
|
-
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1008
|
-
assert.equal(meeting.owner, 'locusOwner');
|
|
1009
|
-
assert.isUndefined(meeting.permissionToken);
|
|
1010
|
-
|
|
1011
|
-
// Add meeting and send trigger
|
|
1012
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1013
|
-
assert.calledTwice(TriggerProxy.trigger);
|
|
1014
|
-
assert.calledWith(
|
|
1015
|
-
TriggerProxy.trigger,
|
|
1016
|
-
sinon.match.instanceOf(Meetings),
|
|
1017
|
-
{
|
|
1018
|
-
file: 'meetings',
|
|
1019
|
-
function: 'createMeeting',
|
|
1020
|
-
},
|
|
1021
|
-
'meeting:added',
|
|
1022
|
-
{
|
|
1023
|
-
meeting: sinon.match.instanceOf(Meeting),
|
|
1024
|
-
type: 'test meeting added type',
|
|
1025
|
-
}
|
|
1361
|
+
'test destination',
|
|
1362
|
+
'test type',
|
|
1363
|
+
{},
|
|
1364
|
+
expectedMeetingData,
|
|
1365
|
+
false,
|
|
1366
|
+
true
|
|
1026
1367
|
);
|
|
1368
|
+
});
|
|
1027
1369
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1370
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1371
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
1372
|
+
|
|
1373
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${
|
|
1374
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1375
|
+
}`, async () => {
|
|
1376
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1377
|
+
'test destination',
|
|
1378
|
+
'test type',
|
|
1379
|
+
false,
|
|
1380
|
+
infoExtraParams
|
|
1381
|
+
);
|
|
1382
|
+
const expectedMeetingData = {
|
|
1383
|
+
permissionToken: 'PT',
|
|
1384
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1385
|
+
};
|
|
1386
|
+
|
|
1387
|
+
assert.instanceOf(
|
|
1388
|
+
meeting,
|
|
1389
|
+
Meeting,
|
|
1390
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1391
|
+
);
|
|
1392
|
+
checkCreateWithoutDelay(
|
|
1393
|
+
meeting,
|
|
1394
|
+
'test destination',
|
|
1395
|
+
'test type',
|
|
1396
|
+
infoExtraParamsProvided ? infoExtraParams : {},
|
|
1397
|
+
expectedMeetingData
|
|
1398
|
+
);
|
|
1399
|
+
});
|
|
1035
1400
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1401
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${
|
|
1402
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1403
|
+
}`, async () => {
|
|
1404
|
+
const FAKE_LOCUS_MEETING = {
|
|
1405
|
+
conversationUrl: 'locusConvURL',
|
|
1406
|
+
url: 'locusUrl',
|
|
1407
|
+
info: {
|
|
1408
|
+
webExMeetingId: 'locusMeetingId',
|
|
1409
|
+
sipUri: 'locusSipUri',
|
|
1410
|
+
owner: 'locusOwner',
|
|
1411
|
+
},
|
|
1412
|
+
meeting: {
|
|
1413
|
+
startTime: fakeMeetingStartTimeString,
|
|
1414
|
+
},
|
|
1415
|
+
fullState: {
|
|
1416
|
+
active: false,
|
|
1417
|
+
},
|
|
1418
|
+
};
|
|
1045
1419
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1420
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1421
|
+
FAKE_LOCUS_MEETING,
|
|
1422
|
+
'test type',
|
|
1423
|
+
true,
|
|
1424
|
+
infoExtraParams
|
|
1425
|
+
);
|
|
1426
|
+
|
|
1427
|
+
assert.instanceOf(
|
|
1428
|
+
meeting,
|
|
1429
|
+
Meeting,
|
|
1430
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1431
|
+
);
|
|
1432
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1433
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1434
|
+
|
|
1435
|
+
// Parse meeting info with locus object
|
|
1436
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1437
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1438
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1439
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1440
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1441
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1442
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1443
|
+
|
|
1444
|
+
// Add meeting and send trigger
|
|
1445
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1446
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1447
|
+
assert.calledWith(
|
|
1448
|
+
TriggerProxy.trigger,
|
|
1449
|
+
sinon.match.instanceOf(Meetings),
|
|
1450
|
+
{
|
|
1451
|
+
file: 'meetings',
|
|
1452
|
+
function: 'createMeeting',
|
|
1453
|
+
},
|
|
1454
|
+
'meeting:added',
|
|
1455
|
+
{
|
|
1456
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1457
|
+
type: 'test meeting added type',
|
|
1458
|
+
}
|
|
1459
|
+
);
|
|
1460
|
+
|
|
1461
|
+
// When timer expires
|
|
1462
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1463
|
+
await testUtils.flushPromises();
|
|
1464
|
+
|
|
1465
|
+
assert.calledWith(
|
|
1466
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1467
|
+
FAKE_LOCUS_MEETING,
|
|
1468
|
+
'test type',
|
|
1469
|
+
null,
|
|
1470
|
+
null,
|
|
1471
|
+
undefined,
|
|
1472
|
+
undefined,
|
|
1473
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1474
|
+
);
|
|
1475
|
+
|
|
1476
|
+
// Parse meeting info is called again with new meeting info
|
|
1477
|
+
await testUtils.flushPromises();
|
|
1478
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1479
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1480
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1481
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1482
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1483
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1484
|
+
assert.equal(meeting.permissionToken, 'PT');
|
|
1485
|
+
|
|
1486
|
+
assert.calledWith(
|
|
1487
|
+
TriggerProxy.trigger,
|
|
1488
|
+
meeting,
|
|
1489
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1490
|
+
'meeting:meetingInfoAvailable'
|
|
1491
|
+
);
|
|
1492
|
+
});
|
|
1052
1493
|
});
|
|
1053
1494
|
|
|
1054
1495
|
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
@@ -1148,6 +1589,61 @@ describe('plugin-meetings', () => {
|
|
|
1148
1589
|
);
|
|
1149
1590
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1150
1591
|
});
|
|
1592
|
+
|
|
1593
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1594
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1595
|
+
'test destination',
|
|
1596
|
+
'test type',
|
|
1597
|
+
false,
|
|
1598
|
+
{},
|
|
1599
|
+
{correlationId: 'my-correlationId'}
|
|
1600
|
+
);
|
|
1601
|
+
|
|
1602
|
+
const expectedMeetingData = {
|
|
1603
|
+
correlationId: 'my-correlationId',
|
|
1604
|
+
};
|
|
1605
|
+
|
|
1606
|
+
checkCreateWithoutDelay(
|
|
1607
|
+
meeting,
|
|
1608
|
+
'test destination',
|
|
1609
|
+
'test type',
|
|
1610
|
+
{},
|
|
1611
|
+
expectedMeetingData,
|
|
1612
|
+
true
|
|
1613
|
+
);
|
|
1614
|
+
});
|
|
1615
|
+
|
|
1616
|
+
it('creates meeting with the callStateForMetrics provided', async () => {
|
|
1617
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1618
|
+
'test destination',
|
|
1619
|
+
'test type',
|
|
1620
|
+
false,
|
|
1621
|
+
{},
|
|
1622
|
+
{
|
|
1623
|
+
correlationId: 'my-correlationId',
|
|
1624
|
+
joinTrigger: 'my-join-trigger',
|
|
1625
|
+
loginType: 'my-login-type',
|
|
1626
|
+
}
|
|
1627
|
+
);
|
|
1628
|
+
|
|
1629
|
+
const expectedMeetingData = {
|
|
1630
|
+
correlationId: 'my-correlationId',
|
|
1631
|
+
callStateForMetrics: {
|
|
1632
|
+
correlationId: 'my-correlationId',
|
|
1633
|
+
joinTrigger: 'my-join-trigger',
|
|
1634
|
+
loginType: 'my-login-type',
|
|
1635
|
+
},
|
|
1636
|
+
};
|
|
1637
|
+
|
|
1638
|
+
checkCreateWithoutDelay(
|
|
1639
|
+
meeting,
|
|
1640
|
+
'test destination',
|
|
1641
|
+
'test type',
|
|
1642
|
+
{},
|
|
1643
|
+
expectedMeetingData,
|
|
1644
|
+
true
|
|
1645
|
+
);
|
|
1646
|
+
});
|
|
1151
1647
|
});
|
|
1152
1648
|
|
|
1153
1649
|
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|
|
@@ -1157,45 +1653,136 @@ describe('plugin-meetings', () => {
|
|
|
1157
1653
|
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1158
1654
|
.stub()
|
|
1159
1655
|
.returns(Promise.reject(new Error('test')));
|
|
1656
|
+
webex.meetings.destroy = sinon.stub().returns(Promise.resolve());
|
|
1657
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1160
1658
|
});
|
|
1659
|
+
|
|
1660
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1661
|
+
try {
|
|
1662
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1663
|
+
'test destination',
|
|
1664
|
+
'test type',
|
|
1665
|
+
undefined,
|
|
1666
|
+
undefined,
|
|
1667
|
+
undefined,
|
|
1668
|
+
failOnMissingMeetingInfo
|
|
1669
|
+
);
|
|
1670
|
+
|
|
1671
|
+
assert.instanceOf(
|
|
1672
|
+
meeting,
|
|
1673
|
+
Meeting,
|
|
1674
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1675
|
+
);
|
|
1676
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1677
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1678
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1679
|
+
assert.calledWith(
|
|
1680
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1681
|
+
'test destination',
|
|
1682
|
+
'test type'
|
|
1683
|
+
);
|
|
1684
|
+
|
|
1685
|
+
if (destroy) {
|
|
1686
|
+
assert.calledWith(
|
|
1687
|
+
webex.meetings.destroy,
|
|
1688
|
+
sinon.match.instanceOf(Meeting),
|
|
1689
|
+
'MISSING_MEETING_INFO'
|
|
1690
|
+
);
|
|
1691
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1692
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1693
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1694
|
+
} else {
|
|
1695
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1696
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1697
|
+
assert.calledWith(
|
|
1698
|
+
TriggerProxy.trigger,
|
|
1699
|
+
sinon.match.instanceOf(Meetings),
|
|
1700
|
+
{
|
|
1701
|
+
file: 'meetings',
|
|
1702
|
+
function: 'createMeeting',
|
|
1703
|
+
},
|
|
1704
|
+
'meeting:added',
|
|
1705
|
+
{
|
|
1706
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1707
|
+
type: 'test meeting added type',
|
|
1708
|
+
}
|
|
1709
|
+
);
|
|
1710
|
+
}
|
|
1711
|
+
} catch (err) {
|
|
1712
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1713
|
+
}
|
|
1714
|
+
};
|
|
1715
|
+
|
|
1161
1716
|
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1162
|
-
|
|
1717
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1718
|
+
});
|
|
1163
1719
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
assert.calledWith(
|
|
1173
|
-
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1174
|
-
'test destination',
|
|
1175
|
-
'test type'
|
|
1176
|
-
);
|
|
1177
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1178
|
-
assert.calledWith(
|
|
1179
|
-
TriggerProxy.trigger,
|
|
1180
|
-
sinon.match.instanceOf(Meetings),
|
|
1720
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1721
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1722
|
+
});
|
|
1723
|
+
});
|
|
1724
|
+
|
|
1725
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1726
|
+
forEach(
|
|
1727
|
+
[
|
|
1181
1728
|
{
|
|
1182
|
-
|
|
1183
|
-
|
|
1729
|
+
error: new CaptchaError(),
|
|
1730
|
+
debugLogMessage:
|
|
1731
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1184
1732
|
},
|
|
1185
|
-
'meeting:added',
|
|
1186
1733
|
{
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1734
|
+
error: new PasswordError(),
|
|
1735
|
+
debugLogMessage:
|
|
1736
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1737
|
+
},
|
|
1738
|
+
{
|
|
1739
|
+
error: new PermissionError(),
|
|
1740
|
+
debugLogMessage:
|
|
1741
|
+
'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.',
|
|
1742
|
+
},
|
|
1743
|
+
{
|
|
1744
|
+
error: new Error(),
|
|
1745
|
+
infoLogMessage: true,
|
|
1746
|
+
debugLogMessage:
|
|
1747
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1748
|
+
},
|
|
1749
|
+
],
|
|
1750
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1751
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1752
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1753
|
+
.stub()
|
|
1754
|
+
.returns(Promise.reject(error));
|
|
1755
|
+
|
|
1756
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1757
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1758
|
+
|
|
1759
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1760
|
+
|
|
1761
|
+
assert.instanceOf(
|
|
1762
|
+
meeting,
|
|
1763
|
+
Meeting,
|
|
1764
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1765
|
+
);
|
|
1766
|
+
|
|
1767
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1768
|
+
|
|
1769
|
+
if (infoLogMessage) {
|
|
1770
|
+
assert.calledWith(
|
|
1771
|
+
LoggerProxy.logger.info,
|
|
1772
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1773
|
+
);
|
|
1774
|
+
} else {
|
|
1775
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1779
|
+
);
|
|
1192
1780
|
});
|
|
1193
1781
|
});
|
|
1194
1782
|
});
|
|
1195
1783
|
describe('Public Event Triggers', () => {
|
|
1196
1784
|
describe('#destroy', () => {
|
|
1197
1785
|
beforeEach(() => {
|
|
1198
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
1199
1786
|
MeetingUtil.cleanUp = sinon.stub();
|
|
1200
1787
|
});
|
|
1201
1788
|
it('should have #destroy', () => {
|
|
@@ -1269,6 +1856,8 @@ describe('plugin-meetings', () => {
|
|
|
1269
1856
|
});
|
|
1270
1857
|
|
|
1271
1858
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1859
|
+
let loggerProxySpy;
|
|
1860
|
+
|
|
1272
1861
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1273
1862
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1274
1863
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1276,7 +1865,22 @@ describe('plugin-meetings', () => {
|
|
|
1276
1865
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1277
1866
|
});
|
|
1278
1867
|
|
|
1868
|
+
const setup = ({user} = {}) => {
|
|
1869
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1870
|
+
|
|
1871
|
+
Object.assign(webex.internal, {
|
|
1872
|
+
services: {
|
|
1873
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1874
|
+
},
|
|
1875
|
+
user: {
|
|
1876
|
+
get: sinon.stub().returns(Promise.resolve(user)),
|
|
1877
|
+
},
|
|
1878
|
+
});
|
|
1879
|
+
};
|
|
1880
|
+
|
|
1279
1881
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1882
|
+
setup();
|
|
1883
|
+
|
|
1280
1884
|
Object.assign(webex.internal, {
|
|
1281
1885
|
services: {
|
|
1282
1886
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
@@ -1286,7 +1890,115 @@ describe('plugin-meetings', () => {
|
|
|
1286
1890
|
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1287
1891
|
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1288
1892
|
});
|
|
1893
|
+
assert.calledOnceWithExactly(
|
|
1894
|
+
loggerProxySpy,
|
|
1895
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1896
|
+
);
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1899
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1900
|
+
setup({
|
|
1901
|
+
user: {
|
|
1902
|
+
userPreferences: {
|
|
1903
|
+
userPreferencesItems: {
|
|
1904
|
+
preferredWebExSite: 'site.webex.com',
|
|
1905
|
+
},
|
|
1906
|
+
},
|
|
1907
|
+
},
|
|
1908
|
+
});
|
|
1909
|
+
|
|
1910
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1911
|
+
|
|
1912
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1913
|
+
assert.notCalled(loggerProxySpy);
|
|
1914
|
+
});
|
|
1915
|
+
|
|
1916
|
+
forEach(
|
|
1917
|
+
[
|
|
1918
|
+
{user: undefined},
|
|
1919
|
+
{user: {userPreferences: {}}},
|
|
1920
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1921
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1922
|
+
],
|
|
1923
|
+
({user}) => {
|
|
1924
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1925
|
+
setup({user});
|
|
1926
|
+
|
|
1927
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1928
|
+
|
|
1929
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1930
|
+
assert.calledOnceWithExactly(
|
|
1931
|
+
loggerProxySpy,
|
|
1932
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1933
|
+
);
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
);
|
|
1937
|
+
|
|
1938
|
+
it('should handle a get user failure', async () => {
|
|
1939
|
+
setup();
|
|
1940
|
+
|
|
1941
|
+
webex.internal.user.get.rejects(new Error());
|
|
1942
|
+
|
|
1943
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1944
|
+
|
|
1945
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1946
|
+
assert.calledOnceWithExactly(
|
|
1947
|
+
loggerProxySpy,
|
|
1948
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1949
|
+
);
|
|
1950
|
+
});
|
|
1951
|
+
|
|
1952
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1953
|
+
setup({
|
|
1954
|
+
user: {
|
|
1955
|
+
userPreferences: {
|
|
1956
|
+
userPreferencesItems: {
|
|
1957
|
+
preferredWebExSite: 'site.webex.com',
|
|
1958
|
+
},
|
|
1959
|
+
},
|
|
1960
|
+
},
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1964
|
+
|
|
1965
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1966
|
+
assert.notCalled(loggerProxySpy);
|
|
1289
1967
|
});
|
|
1968
|
+
|
|
1969
|
+
forEach([
|
|
1970
|
+
{user: undefined},
|
|
1971
|
+
{user: {userPreferences: {}}},
|
|
1972
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1973
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1974
|
+
], ({user}) => {
|
|
1975
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1976
|
+
setup({user});
|
|
1977
|
+
|
|
1978
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1979
|
+
|
|
1980
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1981
|
+
assert.calledOnceWithExactly(
|
|
1982
|
+
loggerProxySpy,
|
|
1983
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1984
|
+
);
|
|
1985
|
+
});
|
|
1986
|
+
});
|
|
1987
|
+
|
|
1988
|
+
it('should handle a get user failure', async () => {
|
|
1989
|
+
setup();
|
|
1990
|
+
|
|
1991
|
+
webex.internal.user.get.rejects(new Error());
|
|
1992
|
+
|
|
1993
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1994
|
+
|
|
1995
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1996
|
+
assert.calledOnceWithExactly(
|
|
1997
|
+
loggerProxySpy,
|
|
1998
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1999
|
+
);
|
|
2000
|
+
});
|
|
2001
|
+
|
|
1290
2002
|
});
|
|
1291
2003
|
});
|
|
1292
2004
|
|
|
@@ -1294,7 +2006,6 @@ describe('plugin-meetings', () => {
|
|
|
1294
2006
|
let meeting;
|
|
1295
2007
|
|
|
1296
2008
|
beforeEach(async () => {
|
|
1297
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
1298
2009
|
webex.internal.device.userId = uuid1;
|
|
1299
2010
|
webex.internal.device.url = url1;
|
|
1300
2011
|
MeetingCollection.set = sinon.stub().returns(true);
|
|
@@ -1371,5 +2082,523 @@ describe('plugin-meetings', () => {
|
|
|
1371
2082
|
);
|
|
1372
2083
|
});
|
|
1373
2084
|
});
|
|
2085
|
+
|
|
2086
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
2087
|
+
let meeting;
|
|
2088
|
+
let newLocus;
|
|
2089
|
+
beforeEach(() => {
|
|
2090
|
+
meeting = {
|
|
2091
|
+
controls: {},
|
|
2092
|
+
self: {},
|
|
2093
|
+
};
|
|
2094
|
+
newLocus = {
|
|
2095
|
+
controls: {},
|
|
2096
|
+
self: {},
|
|
2097
|
+
};
|
|
2098
|
+
});
|
|
2099
|
+
afterEach(() => {
|
|
2100
|
+
sinon.restore();
|
|
2101
|
+
});
|
|
2102
|
+
it('check normal case will return true', () => {
|
|
2103
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
2104
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2105
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2106
|
+
assert.equal(result, true);
|
|
2107
|
+
assert.calledWith(
|
|
2108
|
+
LoggerProxy.logger.log,
|
|
2109
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
2110
|
+
);
|
|
2111
|
+
});
|
|
2112
|
+
|
|
2113
|
+
it('check self joined and joined on this device, return true', () => {
|
|
2114
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
2115
|
+
newLocus.self.state = 'JOINED';
|
|
2116
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
2117
|
+
|
|
2118
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2119
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2120
|
+
assert.equal(result, true);
|
|
2121
|
+
assert.calledWith(
|
|
2122
|
+
LoggerProxy.logger.log,
|
|
2123
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
2124
|
+
);
|
|
2125
|
+
});
|
|
2126
|
+
|
|
2127
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
2128
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
2129
|
+
joinedWith: {
|
|
2130
|
+
replaces: [
|
|
2131
|
+
{
|
|
2132
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
2133
|
+
},
|
|
2134
|
+
],
|
|
2135
|
+
},
|
|
2136
|
+
});
|
|
2137
|
+
newLocus.self.state = 'JOINED';
|
|
2138
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
2139
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2140
|
+
replaces: [
|
|
2141
|
+
{
|
|
2142
|
+
replaceAt: '2023-03-27T02:17:01.506Z',
|
|
2143
|
+
},
|
|
2144
|
+
],
|
|
2145
|
+
});
|
|
2146
|
+
|
|
2147
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2148
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2149
|
+
assert.equal(result, false);
|
|
2150
|
+
assert.calledWith(
|
|
2151
|
+
LoggerProxy.logger.log,
|
|
2152
|
+
`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`
|
|
2153
|
+
);
|
|
2154
|
+
});
|
|
2155
|
+
|
|
2156
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
2157
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
2158
|
+
joinedWith: {
|
|
2159
|
+
correlationId: '111',
|
|
2160
|
+
},
|
|
2161
|
+
});
|
|
2162
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
2163
|
+
meeting.correlationId = '111';
|
|
2164
|
+
|
|
2165
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2166
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2167
|
+
assert.equal(result, false);
|
|
2168
|
+
assert.calledWith(
|
|
2169
|
+
LoggerProxy.logger.log,
|
|
2170
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
2171
|
+
);
|
|
2172
|
+
});
|
|
2173
|
+
|
|
2174
|
+
it('check self is moved and removed, return false', () => {
|
|
2175
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2176
|
+
newLocus.self.state = 'LEFT';
|
|
2177
|
+
newLocus.self.reason = 'MOVED';
|
|
2178
|
+
newLocus.self.removed = true;
|
|
2179
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2180
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2181
|
+
assert.equal(result, false);
|
|
2182
|
+
assert.calledWith(
|
|
2183
|
+
LoggerProxy.logger.log,
|
|
2184
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2185
|
+
);
|
|
2186
|
+
});
|
|
2187
|
+
|
|
2188
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
2189
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2190
|
+
newLocus.self.state = 'LEFT';
|
|
2191
|
+
newLocus.self.reason = 'MOVED';
|
|
2192
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2193
|
+
state: 'LEFT',
|
|
2194
|
+
reason: 'MOVED',
|
|
2195
|
+
});
|
|
2196
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2197
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2198
|
+
assert.equal(result, false);
|
|
2199
|
+
assert.calledWith(
|
|
2200
|
+
LoggerProxy.logger.log,
|
|
2201
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2202
|
+
);
|
|
2203
|
+
});
|
|
2204
|
+
|
|
2205
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
2206
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2207
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
2208
|
+
newLocus.self.state = 'JOINED';
|
|
2209
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2210
|
+
state: 'LEFT',
|
|
2211
|
+
reason: 'MOVED',
|
|
2212
|
+
});
|
|
2213
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2214
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2215
|
+
assert.equal(result, false);
|
|
2216
|
+
assert.calledWith(
|
|
2217
|
+
LoggerProxy.logger.log,
|
|
2218
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
2219
|
+
);
|
|
2220
|
+
});
|
|
2221
|
+
});
|
|
2222
|
+
|
|
2223
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
2224
|
+
let meeting;
|
|
2225
|
+
let newLocus;
|
|
2226
|
+
beforeEach(() => {
|
|
2227
|
+
meeting = {
|
|
2228
|
+
controls: {},
|
|
2229
|
+
self: {},
|
|
2230
|
+
};
|
|
2231
|
+
newLocus = {
|
|
2232
|
+
controls: {},
|
|
2233
|
+
self: {},
|
|
2234
|
+
};
|
|
2235
|
+
});
|
|
2236
|
+
afterEach(() => {
|
|
2237
|
+
sinon.restore();
|
|
2238
|
+
});
|
|
2239
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
2240
|
+
newLocus.controls.breakout = {
|
|
2241
|
+
sessionType: 'BREAKOUT',
|
|
2242
|
+
};
|
|
2243
|
+
newLocus.self.state = 'JOINED';
|
|
2244
|
+
newLocus.fullState = {
|
|
2245
|
+
active: true,
|
|
2246
|
+
};
|
|
2247
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2248
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
2249
|
+
assert.equal(result, true);
|
|
2250
|
+
assert.calledWith(
|
|
2251
|
+
LoggerProxy.logger.log,
|
|
2252
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
2253
|
+
);
|
|
2254
|
+
});
|
|
2255
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
2256
|
+
newLocus.controls.breakout = {
|
|
2257
|
+
sessionType: 'MAIN',
|
|
2258
|
+
};
|
|
2259
|
+
newLocus.self.state = 'JOINED';
|
|
2260
|
+
|
|
2261
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2262
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2263
|
+
assert.equal(result, true);
|
|
2264
|
+
assert.calledWith(
|
|
2265
|
+
LoggerProxy.logger.log,
|
|
2266
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
2267
|
+
);
|
|
2268
|
+
});
|
|
2269
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
2270
|
+
newLocus.controls.breakout = {
|
|
2271
|
+
sessionType: 'BREAKOUT',
|
|
2272
|
+
};
|
|
2273
|
+
newLocus.self.state = 'LEFT';
|
|
2274
|
+
newLocus.self.reason = 'MOVED';
|
|
2275
|
+
|
|
2276
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2277
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2278
|
+
assert.equal(result, false);
|
|
2279
|
+
});
|
|
2280
|
+
});
|
|
2281
|
+
|
|
2282
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
2283
|
+
let locus;
|
|
2284
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
2285
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
2286
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
2287
|
+
if (key === keyWillReturnMeeting) {
|
|
2288
|
+
return mockReturnMeeting;
|
|
2289
|
+
}
|
|
2290
|
+
return null;
|
|
2291
|
+
});
|
|
2292
|
+
};
|
|
2293
|
+
|
|
2294
|
+
beforeEach(() => {
|
|
2295
|
+
locus = {
|
|
2296
|
+
controls: {},
|
|
2297
|
+
self: {
|
|
2298
|
+
callbackInfo: {
|
|
2299
|
+
callbackAddress: 'address1',
|
|
2300
|
+
},
|
|
2301
|
+
},
|
|
2302
|
+
info: {
|
|
2303
|
+
webExMeetingId: '123456',
|
|
2304
|
+
isUnifiedSpaceMeeting: false,
|
|
2305
|
+
},
|
|
2306
|
+
conversationUrl: 'conversationUrl1',
|
|
2307
|
+
};
|
|
2308
|
+
|
|
2309
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
2310
|
+
});
|
|
2311
|
+
afterEach(() => {
|
|
2312
|
+
sinon.restore();
|
|
2313
|
+
});
|
|
2314
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
2315
|
+
mockGetByKey();
|
|
2316
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2317
|
+
assert.isNull(result);
|
|
2318
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2319
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2320
|
+
assert.calledWith(
|
|
2321
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2322
|
+
'correlationId',
|
|
2323
|
+
'correlationId1'
|
|
2324
|
+
);
|
|
2325
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2326
|
+
assert.calledWith(
|
|
2327
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2328
|
+
'conversationUrl',
|
|
2329
|
+
'conversationUrl1'
|
|
2330
|
+
);
|
|
2331
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
2335
|
+
mockGetByKey();
|
|
2336
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
2337
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2338
|
+
assert.isNull(result);
|
|
2339
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2340
|
+
});
|
|
2341
|
+
|
|
2342
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
2343
|
+
mockGetByKey('locusUrl');
|
|
2344
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2345
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2346
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
2347
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2348
|
+
});
|
|
2349
|
+
|
|
2350
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
2351
|
+
mockGetByKey('correlationId');
|
|
2352
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2353
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2354
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
2355
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2356
|
+
assert.calledWith(
|
|
2357
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2358
|
+
'correlationId',
|
|
2359
|
+
'correlationId1'
|
|
2360
|
+
);
|
|
2361
|
+
});
|
|
2362
|
+
|
|
2363
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
2364
|
+
mockGetByKey('sipUri');
|
|
2365
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2366
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2367
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
2368
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2369
|
+
assert.calledWith(
|
|
2370
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2371
|
+
'correlationId',
|
|
2372
|
+
'correlationId1'
|
|
2373
|
+
);
|
|
2374
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2375
|
+
});
|
|
2376
|
+
|
|
2377
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
2378
|
+
mockGetByKey('conversationUrl');
|
|
2379
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2380
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2381
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2382
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2383
|
+
assert.calledWith(
|
|
2384
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2385
|
+
'correlationId',
|
|
2386
|
+
'correlationId1'
|
|
2387
|
+
);
|
|
2388
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2389
|
+
assert.calledWith(
|
|
2390
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2391
|
+
'conversationUrl',
|
|
2392
|
+
'conversationUrl1'
|
|
2393
|
+
);
|
|
2394
|
+
});
|
|
2395
|
+
|
|
2396
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
2397
|
+
mockGetByKey('meetingNumber');
|
|
2398
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2399
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2400
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2401
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2402
|
+
assert.calledWith(
|
|
2403
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2404
|
+
'correlationId',
|
|
2405
|
+
'correlationId1'
|
|
2406
|
+
);
|
|
2407
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2408
|
+
assert.calledWith(
|
|
2409
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2410
|
+
'conversationUrl',
|
|
2411
|
+
'conversationUrl1'
|
|
2412
|
+
);
|
|
2413
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2414
|
+
});
|
|
2415
|
+
});
|
|
2416
|
+
|
|
2417
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
2418
|
+
let lociArray;
|
|
2419
|
+
let mainLocus;
|
|
2420
|
+
let breakoutLocus;
|
|
2421
|
+
beforeEach(() => {
|
|
2422
|
+
mainLocus = {
|
|
2423
|
+
url: 'mainUrl1',
|
|
2424
|
+
controls: {
|
|
2425
|
+
breakout: {
|
|
2426
|
+
sessionType: 'MAIN',
|
|
2427
|
+
url: 'breakoutUnifiedUrl1',
|
|
2428
|
+
},
|
|
2429
|
+
},
|
|
2430
|
+
};
|
|
2431
|
+
breakoutLocus = {
|
|
2432
|
+
url: 'breakoutUrl1',
|
|
2433
|
+
controls: {
|
|
2434
|
+
breakout: {
|
|
2435
|
+
sessionType: 'BREAKOUT',
|
|
2436
|
+
url: 'breakoutUnifiedUrl1',
|
|
2437
|
+
},
|
|
2438
|
+
},
|
|
2439
|
+
};
|
|
2440
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2441
|
+
|
|
2442
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2443
|
+
return locus.url === 'breakoutUrl1';
|
|
2444
|
+
});
|
|
2445
|
+
});
|
|
2446
|
+
afterEach(() => {
|
|
2447
|
+
sinon.restore();
|
|
2448
|
+
});
|
|
2449
|
+
|
|
2450
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2451
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2452
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2453
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2454
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2455
|
+
});
|
|
2456
|
+
|
|
2457
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2458
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2459
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2460
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2461
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2462
|
+
});
|
|
2463
|
+
|
|
2464
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2465
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2466
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2467
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2468
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2469
|
+
});
|
|
2470
|
+
});
|
|
2471
|
+
|
|
2472
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2473
|
+
let breakoutLocus;
|
|
2474
|
+
beforeEach(() => {
|
|
2475
|
+
breakoutLocus = {
|
|
2476
|
+
url: 'breakoutUrl1',
|
|
2477
|
+
controls: {
|
|
2478
|
+
breakout: {
|
|
2479
|
+
sessionType: 'BREAKOUT',
|
|
2480
|
+
url: 'breakoutUnifiedUrl1',
|
|
2481
|
+
},
|
|
2482
|
+
},
|
|
2483
|
+
};
|
|
2484
|
+
|
|
2485
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2486
|
+
});
|
|
2487
|
+
afterEach(() => {
|
|
2488
|
+
sinon.restore();
|
|
2489
|
+
});
|
|
2490
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2491
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2492
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2493
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2494
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2495
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2496
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2497
|
+
});
|
|
2498
|
+
|
|
2499
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2500
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2501
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2502
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2503
|
+
});
|
|
2504
|
+
|
|
2505
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2506
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2507
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2508
|
+
controls: {
|
|
2509
|
+
breakout: {
|
|
2510
|
+
sessionType: 'MAIN',
|
|
2511
|
+
url: 'breakoutUnifiedUrl2',
|
|
2512
|
+
},
|
|
2513
|
+
},
|
|
2514
|
+
});
|
|
2515
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2516
|
+
});
|
|
2517
|
+
|
|
2518
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2519
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2520
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2521
|
+
controls: {
|
|
2522
|
+
breakout: {
|
|
2523
|
+
sessionType: 'MAIN',
|
|
2524
|
+
url: 'breakoutUnifiedUrl1',
|
|
2525
|
+
},
|
|
2526
|
+
},
|
|
2527
|
+
});
|
|
2528
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {
|
|
2529
|
+
locus: breakoutLocus,
|
|
2530
|
+
locusUrl: breakoutLocus.url,
|
|
2531
|
+
});
|
|
2532
|
+
});
|
|
2533
|
+
});
|
|
2534
|
+
|
|
2535
|
+
describe('uploading of logs', () => {
|
|
2536
|
+
let metricsSpy;
|
|
2537
|
+
let meeting;
|
|
2538
|
+
|
|
2539
|
+
beforeEach(async () => {
|
|
2540
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2541
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2542
|
+
|
|
2543
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2544
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2545
|
+
|
|
2546
|
+
triggerProxyStub.restore();
|
|
2547
|
+
|
|
2548
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2549
|
+
|
|
2550
|
+
meeting = await webex.meetings.create('test');
|
|
2551
|
+
|
|
2552
|
+
meeting.locusId = 'locus id';
|
|
2553
|
+
meeting.correlationId = 'correlation id';
|
|
2554
|
+
meeting.locusInfo = {
|
|
2555
|
+
fullState: {lastActive: 'last active', sessionId: 'locus session id'},
|
|
2556
|
+
info: {webExMeetingId: 'meeting id'},
|
|
2557
|
+
};
|
|
2558
|
+
});
|
|
2559
|
+
|
|
2560
|
+
afterEach(() => {
|
|
2561
|
+
sinon.restore();
|
|
2562
|
+
});
|
|
2563
|
+
|
|
2564
|
+
it('sends metrics on success', async () => {
|
|
2565
|
+
await meeting.uploadLogs();
|
|
2566
|
+
|
|
2567
|
+
await testUtils.flushPromises();
|
|
2568
|
+
|
|
2569
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2570
|
+
callStart: 'last active',
|
|
2571
|
+
correlationId: 'correlation id',
|
|
2572
|
+
feedbackId: 'correlation id',
|
|
2573
|
+
locusId: 'locus id',
|
|
2574
|
+
meetingId: 'meeting id',
|
|
2575
|
+
autoupload: true,
|
|
2576
|
+
locussessionid: 'locus session id',
|
|
2577
|
+
});
|
|
2578
|
+
});
|
|
2579
|
+
|
|
2580
|
+
it('sends metrics on failure', async () => {
|
|
2581
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2582
|
+
|
|
2583
|
+
await meeting.uploadLogs();
|
|
2584
|
+
|
|
2585
|
+
await testUtils.flushPromises();
|
|
2586
|
+
|
|
2587
|
+
assert.calledOnceWithExactly(
|
|
2588
|
+
metricsSpy,
|
|
2589
|
+
'js_sdk_upload_logs_failure',
|
|
2590
|
+
sinon.match({
|
|
2591
|
+
callStart: 'last active',
|
|
2592
|
+
correlationId: 'correlation id',
|
|
2593
|
+
feedbackId: 'correlation id',
|
|
2594
|
+
locusId: 'locus id',
|
|
2595
|
+
meetingId: 'meeting id',
|
|
2596
|
+
reason: 'fake error',
|
|
2597
|
+
autoupload: true,
|
|
2598
|
+
locussessionid: 'locus session id',
|
|
2599
|
+
})
|
|
2600
|
+
);
|
|
2601
|
+
});
|
|
2602
|
+
});
|
|
1374
2603
|
});
|
|
1375
2604
|
});
|