@webex/plugin-meetings 2.60.0 → 2.60.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -8
- package/dist/annotation/annotation.types.d.ts +42 -0
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.d.ts +31 -0
- package/dist/annotation/constants.js +41 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.d.ts +117 -0
- package/dist/annotation/index.js +357 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.d.ts +8 -0
- package/dist/breakouts/breakout.js +215 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.d.ts +5 -0
- package/dist/breakouts/collection.js +22 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/breakouts/edit-lock-error.js +51 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.d.ts +8 -0
- package/dist/breakouts/events.js +44 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.d.ts +5 -0
- package/dist/breakouts/index.js +1047 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/breakouts/request.d.ts +22 -0
- package/dist/breakouts/request.js +77 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.d.ts +15 -0
- package/dist/breakouts/utils.js +64 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/browser-detection.js +2 -3
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +3 -4
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +1 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +1 -2
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +1 -2
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +1 -2
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +1 -2
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/common/errors/no-meeting-info.js +50 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/{reclaim-host-role-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 +217 -97
- package/dist/constants.js +416 -441
- 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 +591 -494
- package/dist/meeting/index.js +4732 -2990
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/meeting/locusMediaRequest.js +291 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.d.ts +93 -25
- package/dist/meeting/muteState.js +224 -133
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.d.ts +82 -47
- package/dist/meeting/request.js +297 -199
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.d.ts +11 -0
- package/dist/meeting/request.type.js +7 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.d.ts +102 -1
- package/dist/meeting/util.js +605 -435
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.d.ts +13 -1
- package/dist/meeting-info/index.js +74 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/meeting-info/meeting-info-v2.js +200 -63
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +2 -3
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +39 -41
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.d.ts +17 -0
- package/dist/meetings/collection.js +42 -4
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.d.ts +93 -21
- package/dist/meetings/index.js +490 -127
- 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 +300 -393
- 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 +282 -231
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +4 -5
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.d.ts +15 -1
- package/dist/recording-controller/index.js +57 -46
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.d.ts +5 -4
- package/dist/recording-controller/util.js +10 -10
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.d.ts +9 -47
- package/dist/roap/index.js +101 -235
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.d.ts +18 -12
- package/dist/roap/request.js +126 -180
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +27 -16
- package/dist/roap/turnDiscovery.js +115 -105
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.d.ts +4 -0
- package/dist/rtcMetrics/constants.js +11 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.d.ts +54 -0
- package/dist/rtcMetrics/index.js +140 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.d.ts +1 -83
- package/dist/statsAnalyzer/global.js +2 -85
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.d.ts +50 -30
- package/dist/statsAnalyzer/index.js +435 -510
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +8 -6
- package/dist/statsAnalyzer/mqaUtil.js +120 -83
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +1 -2
- package/dist/transcription/index.js.map +1 -1
- package/dist/webinar/collection.d.ts +16 -0
- package/dist/webinar/collection.js +43 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +68 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +38 -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 +244 -97
- 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 +449 -61
- package/src/locus-info/infoUtils.ts +14 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +85 -2
- package/src/media/index.ts +153 -370
- package/src/media/properties.ts +106 -136
- package/src/media/util.ts +0 -21
- package/src/mediaQualityMetrics/config.ts +244 -377
- package/src/meeting/in-meeting-actions.ts +176 -0
- package/src/meeting/index.ts +3944 -2489
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +224 -138
- package/src/meeting/request.ts +207 -127
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/util.ts +590 -423
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +163 -13
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +28 -28
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +487 -126
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +116 -5
- package/src/member/index.ts +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 +243 -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 +98 -241
- package/src/roap/request.ts +74 -148
- package/src/roap/turnDiscovery.ts +62 -56
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +124 -0
- package/src/statsAnalyzer/global.ts +1 -84
- package/src/statsAnalyzer/index.ts +477 -643
- package/src/statsAnalyzer/mqaUtil.ts +115 -114
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +320 -264
- package/test/integration/spec/space-meeting.js +77 -4
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +237 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1790 -0
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/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 +1390 -16
- package/test/unit/spec/locus-info/infoUtils.js +54 -16
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/lib/selfConstant.js +48 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfUtils.js +275 -0
- package/test/unit/spec/media/index.ts +290 -0
- package/test/unit/spec/media/properties.ts +75 -84
- package/test/unit/spec/meeting/in-meeting-actions.ts +86 -0
- package/test/unit/spec/meeting/index.js +8187 -2769
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +409 -213
- package/test/unit/spec/meeting/request.js +512 -42
- package/test/unit/spec/meeting/utils.js +741 -24
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +527 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1313 -243
- 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 +531 -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 +162 -24
- package/test/unit/spec/recording-controller/index.js +293 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +200 -76
- package/test/unit/spec/roap/request.ts +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 +261 -167
- 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,8 +15,8 @@ import sinon from 'sinon';
|
|
|
11
15
|
import uuid from 'uuid';
|
|
12
16
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
13
17
|
import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
18
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
14
19
|
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
15
|
-
import MediaUtil from '@webex/plugin-meetings/src/media/util';
|
|
16
20
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
17
21
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
18
22
|
import Meetings from '@webex/plugin-meetings/src/meetings';
|
|
@@ -20,6 +24,7 @@ import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
|
20
24
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
21
25
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
22
26
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
27
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
23
28
|
|
|
24
29
|
import testUtils from '../../../utils/testUtils';
|
|
25
30
|
import {
|
|
@@ -30,6 +35,12 @@ import {
|
|
|
30
35
|
LOCUSINFO,
|
|
31
36
|
EVENT_TRIGGERS,
|
|
32
37
|
} from '../../../../src/constants';
|
|
38
|
+
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
|
|
39
|
+
import {forEach} from 'lodash';
|
|
40
|
+
import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
|
|
41
|
+
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
42
|
+
import {NoiseReductionEffect, VirtualBackgroundEffect} from '@webex/media-helpers';
|
|
43
|
+
import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
|
|
33
44
|
|
|
34
45
|
describe('plugin-meetings', () => {
|
|
35
46
|
const logger = {
|
|
@@ -41,6 +52,8 @@ describe('plugin-meetings', () => {
|
|
|
41
52
|
debug: () => {},
|
|
42
53
|
};
|
|
43
54
|
|
|
55
|
+
let triggerProxyStub;
|
|
56
|
+
|
|
44
57
|
beforeEach(() => {
|
|
45
58
|
StaticConfig.set({
|
|
46
59
|
bandwidth: {
|
|
@@ -52,7 +65,7 @@ describe('plugin-meetings', () => {
|
|
|
52
65
|
verboseEvents: true,
|
|
53
66
|
enable: false,
|
|
54
67
|
});
|
|
55
|
-
|
|
68
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
56
69
|
});
|
|
57
70
|
|
|
58
71
|
let webex;
|
|
@@ -61,15 +74,20 @@ describe('plugin-meetings', () => {
|
|
|
61
74
|
let url1;
|
|
62
75
|
let test1;
|
|
63
76
|
let test2;
|
|
77
|
+
let locusInfo;
|
|
64
78
|
|
|
65
79
|
describe('meetings index', () => {
|
|
66
80
|
beforeEach(() => {
|
|
67
81
|
MeetingsUtil.checkH264Support = sinon.stub();
|
|
68
|
-
|
|
82
|
+
uuid1 = uuid.v4();
|
|
69
83
|
url1 = `https://example.com/${uuid.v4()}`;
|
|
70
84
|
uri1 = `test-${uuid.v4()}@example.com`;
|
|
71
85
|
test1 = `test-${uuid.v4()}`;
|
|
72
86
|
test2 = `test2-${uuid.v4()}`;
|
|
87
|
+
locusInfo = {
|
|
88
|
+
parse: sinon.stub().returns(true),
|
|
89
|
+
updateMainSessionLocusCache: sinon.stub(),
|
|
90
|
+
};
|
|
73
91
|
webex = new MockWebex({
|
|
74
92
|
children: {
|
|
75
93
|
device: Device,
|
|
@@ -108,6 +126,7 @@ describe('plugin-meetings', () => {
|
|
|
108
126
|
});
|
|
109
127
|
|
|
110
128
|
Object.assign(webex.internal, {
|
|
129
|
+
llm: {on: sinon.stub()},
|
|
111
130
|
device: {
|
|
112
131
|
deviceType: 'FAKE_DEVICE',
|
|
113
132
|
register: sinon.stub().returns(Promise.resolve()),
|
|
@@ -151,6 +170,10 @@ describe('plugin-meetings', () => {
|
|
|
151
170
|
webex.emit('ready');
|
|
152
171
|
});
|
|
153
172
|
|
|
173
|
+
afterEach(() => {
|
|
174
|
+
sinon.restore();
|
|
175
|
+
});
|
|
176
|
+
|
|
154
177
|
it('has a webex instance with a meetings property', () => {
|
|
155
178
|
assert.exists(webex, 'webex was initialized with children');
|
|
156
179
|
assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
|
|
@@ -217,34 +240,6 @@ describe('plugin-meetings', () => {
|
|
|
217
240
|
});
|
|
218
241
|
});
|
|
219
242
|
|
|
220
|
-
describe('#_toggleTurnDiscovery', () => {
|
|
221
|
-
it('should have toggleAdhocMeetings', () => {
|
|
222
|
-
assert.equal(typeof webex.meetings._toggleTurnDiscovery, 'function');
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
describe('success', () => {
|
|
226
|
-
it('should update meetings to do TURN discovery', () => {
|
|
227
|
-
webex.meetings._toggleTurnDiscovery(true);
|
|
228
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, true);
|
|
229
|
-
|
|
230
|
-
webex.meetings._toggleTurnDiscovery(false);
|
|
231
|
-
assert.equal(webex.meetings.config.experimental.enableTurnDiscovery, false);
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
describe('failure', () => {
|
|
236
|
-
it('should not accept non boolean input', () => {
|
|
237
|
-
const currentEnableTurnDiscovery = webex.meetings.config.experimental.enableTurnDiscovery;
|
|
238
|
-
|
|
239
|
-
webex.meetings._toggleTurnDiscovery('test');
|
|
240
|
-
assert.equal(
|
|
241
|
-
webex.meetings.config.experimental.enableAdhocMeetings,
|
|
242
|
-
currentEnableTurnDiscovery
|
|
243
|
-
);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
243
|
describe('Public API Contracts', () => {
|
|
249
244
|
describe('#register', () => {
|
|
250
245
|
it('emits an event and resolves when register succeeds', async () => {
|
|
@@ -338,37 +333,110 @@ describe('plugin-meetings', () => {
|
|
|
338
333
|
});
|
|
339
334
|
});
|
|
340
335
|
|
|
336
|
+
describe('virtual background effect', () => {
|
|
337
|
+
beforeEach(() => {
|
|
338
|
+
webex.credentials = {
|
|
339
|
+
supertoken: {
|
|
340
|
+
access_token: 'fake_token',
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('creates background effect', async () => {
|
|
346
|
+
const result = await webex.meetings.createVirtualBackgroundEffect();
|
|
347
|
+
|
|
348
|
+
assert.exists(result);
|
|
349
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
350
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
351
|
+
assert.deepEqual(result.options, {
|
|
352
|
+
mode: 'BLUR',
|
|
353
|
+
blurStrength: 'STRONG',
|
|
354
|
+
generator: 'worker',
|
|
355
|
+
quality: 'LOW',
|
|
356
|
+
authToken: 'fake_token',
|
|
357
|
+
mirror: false,
|
|
358
|
+
});
|
|
359
|
+
assert.exists(result.enable);
|
|
360
|
+
assert.exists(result.disable);
|
|
361
|
+
assert.exists(result.dispose);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('creates background effect with custom options passed', async () => {
|
|
365
|
+
const effectOptions = {
|
|
366
|
+
generator: 'local',
|
|
367
|
+
frameRate: 45,
|
|
368
|
+
mode: 'IMAGE',
|
|
369
|
+
mirror: false,
|
|
370
|
+
quality: 'HIGH',
|
|
371
|
+
blurStrength: 'STRONG',
|
|
372
|
+
bgImageUrl: 'https://test.webex.com/landscape.5a535788.jpg',
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const result = await webex.meetings.createVirtualBackgroundEffect(effectOptions);
|
|
376
|
+
|
|
377
|
+
assert.exists(result);
|
|
378
|
+
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
379
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
380
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
381
|
+
assert.exists(result.enable);
|
|
382
|
+
assert.exists(result.disable);
|
|
383
|
+
assert.exists(result.dispose);
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
describe('noise reduction effect', () => {
|
|
388
|
+
beforeEach(() => {
|
|
389
|
+
webex.credentials = {
|
|
390
|
+
supertoken: {
|
|
391
|
+
access_token: 'fake_token',
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('creates noise reduction effect', async () => {
|
|
397
|
+
const result = await webex.meetings.createNoiseReductionEffect({audioContext: {}});
|
|
398
|
+
|
|
399
|
+
assert.exists(result);
|
|
400
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
401
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
402
|
+
assert.deepEqual(result.options, {
|
|
403
|
+
authToken: 'fake_token',
|
|
404
|
+
audioContext: {},
|
|
405
|
+
});
|
|
406
|
+
assert.exists(result.enable);
|
|
407
|
+
assert.exists(result.disable);
|
|
408
|
+
assert.exists(result.dispose);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('creates noise reduction effect with custom options passed', async () => {
|
|
412
|
+
const effectOptions = {
|
|
413
|
+
audioContext: {},
|
|
414
|
+
mode: 'WORKLET',
|
|
415
|
+
env: 'prod',
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const result = await webex.meetings.createNoiseReductionEffect(effectOptions);
|
|
419
|
+
|
|
420
|
+
assert.exists(result);
|
|
421
|
+
assert.instanceOf(result, NoiseReductionEffect);
|
|
422
|
+
assert.containsAllKeys(result, ['audioContext', 'isEnabled', 'isReady', 'options']);
|
|
423
|
+
assert.deepEqual(result.options, {...effectOptions, authToken: 'fake_token'});
|
|
424
|
+
assert.exists(result.enable);
|
|
425
|
+
assert.exists(result.disable);
|
|
426
|
+
assert.exists(result.dispose);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
341
430
|
describe('gets', () => {
|
|
342
431
|
describe('#getReachability', () => {
|
|
343
432
|
it('should have #getReachability', () => {
|
|
344
433
|
assert.exists(webex.meetings.getReachability);
|
|
345
434
|
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const reachability = webex.meetings.getReachability();
|
|
349
|
-
|
|
350
|
-
assert.notExists(
|
|
351
|
-
reachability,
|
|
352
|
-
'reachability is undefined because #setReachability has not been called'
|
|
353
|
-
);
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
describe('after #setReachability', () => {
|
|
357
|
-
beforeEach(() => {
|
|
358
|
-
webex.meetings.setReachability();
|
|
359
|
-
const reachabilityMocker = webex.meetings.getReachability();
|
|
360
|
-
|
|
361
|
-
sinon.stub(reachabilityMocker, 'gatherReachability').returns(true);
|
|
362
|
-
});
|
|
363
|
-
it('gets the reachability data instance from webex.meetings', () => {
|
|
364
|
-
const reachability = webex.meetings.getReachability();
|
|
435
|
+
it('gets the reachability data instance from webex.meetings', () => {
|
|
436
|
+
const reachability = webex.meetings.getReachability();
|
|
365
437
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
'reachability is defined because #setReachability has been called'
|
|
369
|
-
);
|
|
370
|
-
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
371
|
-
});
|
|
438
|
+
assert.exists(reachability, 'reachability is defined');
|
|
439
|
+
assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
|
|
372
440
|
});
|
|
373
441
|
});
|
|
374
442
|
describe('#getPersonalMeetingRoom', () => {
|
|
@@ -443,21 +511,16 @@ describe('plugin-meetings', () => {
|
|
|
443
511
|
);
|
|
444
512
|
});
|
|
445
513
|
describe('when meeting is returned', () => {
|
|
446
|
-
let parse;
|
|
447
|
-
|
|
448
514
|
beforeEach(() => {
|
|
449
|
-
parse = sinon.stub().returns(true);
|
|
450
515
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
451
|
-
locusInfo
|
|
452
|
-
parse,
|
|
453
|
-
},
|
|
516
|
+
locusInfo,
|
|
454
517
|
});
|
|
455
518
|
});
|
|
456
519
|
it('tests the sync meeting calls for existing meeting', async () => {
|
|
457
520
|
await webex.meetings.syncMeetings();
|
|
458
521
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
459
522
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
460
|
-
assert.calledOnce(parse);
|
|
523
|
+
assert.calledOnce(locusInfo.parse);
|
|
461
524
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
462
525
|
});
|
|
463
526
|
});
|
|
@@ -470,6 +533,7 @@ describe('plugin-meetings', () => {
|
|
|
470
533
|
webex.meetings.create = sinon.stub().returns(
|
|
471
534
|
Promise.resolve({
|
|
472
535
|
locusInfo: {
|
|
536
|
+
...locusInfo,
|
|
473
537
|
initialSetup,
|
|
474
538
|
},
|
|
475
539
|
})
|
|
@@ -478,7 +542,7 @@ describe('plugin-meetings', () => {
|
|
|
478
542
|
it('tests the sync meeting calls for not existing meeting', async () => {
|
|
479
543
|
await webex.meetings.syncMeetings();
|
|
480
544
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
481
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
545
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
482
546
|
assert.calledOnce(initialSetup);
|
|
483
547
|
assert.calledOnce(webex.meetings.create);
|
|
484
548
|
assert.calledWith(webex.meetings.request.getActiveMeetings);
|
|
@@ -495,46 +559,46 @@ describe('plugin-meetings', () => {
|
|
|
495
559
|
});
|
|
496
560
|
});
|
|
497
561
|
});
|
|
498
|
-
describe('
|
|
499
|
-
let initialSetup;
|
|
500
|
-
let parse;
|
|
562
|
+
describe('destroy non active locus meetings', () => {
|
|
501
563
|
let destroySpy;
|
|
502
564
|
|
|
565
|
+
const meetingCollectionMeetings = {
|
|
566
|
+
stillValidLocusMeeting: {
|
|
567
|
+
locusUrl: 'still-valid-locus-url',
|
|
568
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
569
|
+
},
|
|
570
|
+
noLongerValidLocusMeeting: {
|
|
571
|
+
locusUrl: 'no-longer-valid-locus-url',
|
|
572
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
573
|
+
},
|
|
574
|
+
otherNonLocusMeeting1: {
|
|
575
|
+
locusUrl: null,
|
|
576
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
577
|
+
},
|
|
578
|
+
otherNonLocusMeeting2: {
|
|
579
|
+
locusUrl: undefined,
|
|
580
|
+
sendCallAnalyzerMetrics: sinon.stub(),
|
|
581
|
+
},
|
|
582
|
+
};
|
|
583
|
+
|
|
503
584
|
beforeEach(() => {
|
|
504
585
|
destroySpy = sinon.spy(webex.meetings, 'destroy');
|
|
505
|
-
|
|
506
|
-
initialSetup = sinon.stub().returns(true);
|
|
507
|
-
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
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
|
-
);
|
|
586
|
+
webex.meetings.meetingCollection.getAll = sinon.stub().returns(meetingCollectionMeetings);
|
|
527
587
|
webex.meetings.request.getActiveMeetings = sinon.stub().returns(
|
|
528
588
|
Promise.resolve({
|
|
529
|
-
loci: [
|
|
589
|
+
loci: [
|
|
590
|
+
{url: 'still-valid-locus-url'}
|
|
591
|
+
],
|
|
530
592
|
})
|
|
531
593
|
);
|
|
532
594
|
MeetingUtil.cleanUp = sinon.stub().returns(Promise.resolve());
|
|
533
595
|
});
|
|
534
|
-
it('destroy non active meetings', async () => {
|
|
596
|
+
it('destroy only non active locus meetings and keep active locus meetings and any other non-locus meeting', async () => {
|
|
535
597
|
await webex.meetings.syncMeetings();
|
|
536
598
|
assert.calledOnce(webex.meetings.request.getActiveMeetings);
|
|
537
|
-
assert.calledOnce(
|
|
599
|
+
assert.calledOnce(webex.meetings.meetingCollection.getAll);
|
|
600
|
+
assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
|
|
601
|
+
assert.callCount(destroySpy, 1);
|
|
538
602
|
|
|
539
603
|
assert.calledOnce(MeetingUtil.cleanUp);
|
|
540
604
|
});
|
|
@@ -574,14 +638,104 @@ describe('plugin-meetings', () => {
|
|
|
574
638
|
});
|
|
575
639
|
});
|
|
576
640
|
|
|
641
|
+
const FAKE_USE_RANDOM_DELAY = true;
|
|
642
|
+
const correlationId = 'my-correlationId';
|
|
643
|
+
const callStateForMetrics = {
|
|
644
|
+
correlationId: 'my-correlationId2',
|
|
645
|
+
joinTrigger: 'my-join-trigger',
|
|
646
|
+
loginType: 'my-login-type',
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
it('should call setCallStateForMetrics on any pre-existing meeting', async () => {
|
|
650
|
+
const fakeMeeting = {setCallStateForMetrics: sinon.mock()};
|
|
651
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(fakeMeeting);
|
|
652
|
+
await webex.meetings.create(
|
|
653
|
+
test1,
|
|
654
|
+
test2,
|
|
655
|
+
FAKE_USE_RANDOM_DELAY,
|
|
656
|
+
{},
|
|
657
|
+
correlationId,
|
|
658
|
+
true,
|
|
659
|
+
callStateForMetrics
|
|
660
|
+
);
|
|
661
|
+
assert.calledOnceWithExactly(fakeMeeting.setCallStateForMetrics, {
|
|
662
|
+
...callStateForMetrics,
|
|
663
|
+
correlationId,
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
668
|
+
const create = webex.meetings.create(...createParameters);
|
|
669
|
+
|
|
670
|
+
assert.exists(create.then);
|
|
671
|
+
await create;
|
|
672
|
+
assert.calledOnce(webex.meetings.createMeeting);
|
|
673
|
+
assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
|
|
674
|
+
};
|
|
675
|
+
|
|
577
676
|
it('calls createMeeting and returns its promise', async () => {
|
|
578
|
-
|
|
579
|
-
|
|
677
|
+
await checkCallCreateMeeting(
|
|
678
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true],
|
|
679
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true]
|
|
680
|
+
);
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
684
|
+
await checkCallCreateMeeting(
|
|
685
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
|
|
686
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
687
|
+
);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
691
|
+
await checkCallCreateMeeting(
|
|
692
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false],
|
|
693
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
694
|
+
);
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
it('calls createMeeting with callStateForMetrics and returns its promise', async () => {
|
|
698
|
+
await checkCallCreateMeeting(
|
|
699
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, undefined, true, callStateForMetrics],
|
|
700
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, callStateForMetrics, true]
|
|
701
|
+
);
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it('calls createMeeting with callStateForMetrics overwritten with correlationId and returns its promise', async () => {
|
|
705
|
+
await checkCallCreateMeeting(
|
|
706
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, callStateForMetrics],
|
|
707
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {...callStateForMetrics, correlationId}, true]
|
|
708
|
+
);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
it('calls createMeeting with extra info params and returns its promise', async () => {
|
|
712
|
+
const FAKE_USE_RANDOM_DELAY = false;
|
|
713
|
+
const correlationId = 'my-correlationId';
|
|
714
|
+
|
|
715
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
716
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
717
|
+
joinTXId: 'TSmrX61wNF',
|
|
718
|
+
};
|
|
719
|
+
const create = webex.meetings.create(
|
|
720
|
+
test1,
|
|
721
|
+
test2,
|
|
722
|
+
FAKE_USE_RANDOM_DELAY,
|
|
723
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
724
|
+
correlationId
|
|
725
|
+
);
|
|
580
726
|
|
|
581
727
|
assert.exists(create.then);
|
|
582
728
|
await create;
|
|
583
729
|
assert.calledOnce(webex.meetings.createMeeting);
|
|
584
|
-
assert.calledWith(
|
|
730
|
+
assert.calledWith(
|
|
731
|
+
webex.meetings.createMeeting,
|
|
732
|
+
test1,
|
|
733
|
+
test2,
|
|
734
|
+
FAKE_USE_RANDOM_DELAY,
|
|
735
|
+
FAKE_INFO_EXTRA_PARAMS,
|
|
736
|
+
{correlationId},
|
|
737
|
+
false
|
|
738
|
+
);
|
|
585
739
|
});
|
|
586
740
|
|
|
587
741
|
it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
|
|
@@ -677,45 +831,51 @@ describe('plugin-meetings', () => {
|
|
|
677
831
|
});
|
|
678
832
|
describe('#handleLocusEvent', () => {
|
|
679
833
|
describe('there was a meeting', () => {
|
|
680
|
-
let parse;
|
|
681
|
-
|
|
682
834
|
beforeEach(() => {
|
|
683
|
-
parse = sinon.stub().returns(true);
|
|
684
835
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
|
|
685
|
-
locusInfo
|
|
686
|
-
parse,
|
|
687
|
-
},
|
|
836
|
+
locusInfo,
|
|
688
837
|
});
|
|
689
838
|
});
|
|
690
|
-
it('should parse the meeting info', () => {
|
|
839
|
+
it('should parse the meeting info and update main session locus cache', () => {
|
|
840
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
|
|
691
841
|
webex.meetings.handleLocusEvent({
|
|
692
842
|
locusUrl: url1,
|
|
693
843
|
});
|
|
694
844
|
assert.calledOnce(webex.meetings.meetingCollection.getByKey);
|
|
695
845
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
696
|
-
assert.calledOnce(parse);
|
|
846
|
+
assert.calledOnce(locusInfo.parse);
|
|
847
|
+
assert.calledOnce(locusInfo.updateMainSessionLocusCache);
|
|
697
848
|
assert.calledWith(
|
|
698
|
-
parse,
|
|
849
|
+
locusInfo.parse,
|
|
699
850
|
{
|
|
700
|
-
locusInfo
|
|
701
|
-
parse,
|
|
702
|
-
},
|
|
851
|
+
locusInfo,
|
|
703
852
|
},
|
|
704
853
|
{
|
|
705
854
|
locusUrl: url1,
|
|
706
855
|
}
|
|
707
856
|
);
|
|
708
857
|
});
|
|
858
|
+
|
|
859
|
+
it('should not update main session locus cache', () => {
|
|
860
|
+
sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
|
|
861
|
+
webex.meetings.handleLocusEvent({
|
|
862
|
+
locusUrl: url1,
|
|
863
|
+
});
|
|
864
|
+
assert.notCalled(locusInfo.updateMainSessionLocusCache);
|
|
865
|
+
});
|
|
709
866
|
});
|
|
710
867
|
describe('there was not a meeting', () => {
|
|
711
868
|
let initialSetup;
|
|
869
|
+
const webExMeetingId = '123456';
|
|
712
870
|
|
|
713
871
|
beforeEach(() => {
|
|
714
872
|
initialSetup = sinon.stub().returns(true);
|
|
715
873
|
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
716
874
|
webex.meetings.create = sinon.stub().returns(
|
|
717
875
|
Promise.resolve({
|
|
876
|
+
id: 'meeting-id',
|
|
718
877
|
locusInfo: {
|
|
878
|
+
...locusInfo,
|
|
719
879
|
initialSetup,
|
|
720
880
|
},
|
|
721
881
|
})
|
|
@@ -735,12 +895,20 @@ describe('plugin-meetings', () => {
|
|
|
735
895
|
callbackAddress: uri1,
|
|
736
896
|
},
|
|
737
897
|
},
|
|
898
|
+
info: {
|
|
899
|
+
webExMeetingId,
|
|
900
|
+
},
|
|
738
901
|
},
|
|
739
902
|
eventType: 'locus.difference',
|
|
740
903
|
locusUrl: url1,
|
|
741
904
|
});
|
|
742
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
905
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
|
|
743
906
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
907
|
+
assert.calledWith(
|
|
908
|
+
webex.meetings.meetingCollection.getByKey,
|
|
909
|
+
'meetingNumber',
|
|
910
|
+
webExMeetingId
|
|
911
|
+
);
|
|
744
912
|
assert.calledOnce(initialSetup);
|
|
745
913
|
assert.calledWith(initialSetup, {
|
|
746
914
|
id: uuid1,
|
|
@@ -754,6 +922,9 @@ describe('plugin-meetings', () => {
|
|
|
754
922
|
callbackAddress: uri1,
|
|
755
923
|
},
|
|
756
924
|
},
|
|
925
|
+
info: {
|
|
926
|
+
webExMeetingId,
|
|
927
|
+
},
|
|
757
928
|
});
|
|
758
929
|
});
|
|
759
930
|
it('should setup the meeting by difference event without replaces', async () => {
|
|
@@ -765,12 +936,20 @@ describe('plugin-meetings', () => {
|
|
|
765
936
|
callbackAddress: uri1,
|
|
766
937
|
},
|
|
767
938
|
},
|
|
939
|
+
info: {
|
|
940
|
+
webExMeetingId,
|
|
941
|
+
},
|
|
768
942
|
},
|
|
769
943
|
eventType: 'locus.difference',
|
|
770
944
|
locusUrl: url1,
|
|
771
945
|
});
|
|
772
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
946
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
773
947
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
948
|
+
assert.calledWith(
|
|
949
|
+
webex.meetings.meetingCollection.getByKey,
|
|
950
|
+
'meetingNumber',
|
|
951
|
+
webExMeetingId
|
|
952
|
+
);
|
|
774
953
|
assert.calledOnce(initialSetup);
|
|
775
954
|
assert.calledWith(initialSetup, {
|
|
776
955
|
id: uuid1,
|
|
@@ -779,8 +958,44 @@ describe('plugin-meetings', () => {
|
|
|
779
958
|
callbackAddress: uri1,
|
|
780
959
|
},
|
|
781
960
|
},
|
|
961
|
+
info: {
|
|
962
|
+
webExMeetingId,
|
|
963
|
+
},
|
|
964
|
+
});
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
it('sends client event correctly on finally', async () => {
|
|
968
|
+
webex.meetings.getMeetingByType = sinon.stub().returns(true);
|
|
969
|
+
|
|
970
|
+
await webex.meetings.handleLocusEvent({
|
|
971
|
+
locus: {
|
|
972
|
+
id: uuid1,
|
|
973
|
+
self: {
|
|
974
|
+
callBackInfo: {
|
|
975
|
+
callbackAddress: uri1,
|
|
976
|
+
},
|
|
977
|
+
},
|
|
978
|
+
info: {
|
|
979
|
+
webExMeetingId,
|
|
980
|
+
},
|
|
981
|
+
},
|
|
982
|
+
eventType: 'locus.difference',
|
|
983
|
+
locusUrl: url1,
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
await testUtils.flushPromises();
|
|
987
|
+
|
|
988
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
989
|
+
name: 'client.call.remote-started',
|
|
990
|
+
payload: {
|
|
991
|
+
trigger: 'mercury-event',
|
|
992
|
+
},
|
|
993
|
+
options: {
|
|
994
|
+
meetingId: 'meeting-id',
|
|
995
|
+
},
|
|
782
996
|
});
|
|
783
997
|
});
|
|
998
|
+
|
|
784
999
|
it('should setup the meeting by a not difference event', async () => {
|
|
785
1000
|
await webex.meetings.handleLocusEvent({
|
|
786
1001
|
locus: {
|
|
@@ -790,12 +1005,20 @@ describe('plugin-meetings', () => {
|
|
|
790
1005
|
callbackAddress: uri1,
|
|
791
1006
|
},
|
|
792
1007
|
},
|
|
1008
|
+
info: {
|
|
1009
|
+
webExMeetingId,
|
|
1010
|
+
},
|
|
793
1011
|
},
|
|
794
1012
|
eventType: test1,
|
|
795
1013
|
locusUrl: url1,
|
|
796
1014
|
});
|
|
797
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1015
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
798
1016
|
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
1017
|
+
assert.calledWith(
|
|
1018
|
+
webex.meetings.meetingCollection.getByKey,
|
|
1019
|
+
'meetingNumber',
|
|
1020
|
+
webExMeetingId
|
|
1021
|
+
);
|
|
799
1022
|
assert.calledOnce(initialSetup);
|
|
800
1023
|
assert.calledWith(initialSetup, {
|
|
801
1024
|
id: uuid1,
|
|
@@ -804,6 +1027,9 @@ describe('plugin-meetings', () => {
|
|
|
804
1027
|
callbackAddress: uri1,
|
|
805
1028
|
},
|
|
806
1029
|
},
|
|
1030
|
+
info: {
|
|
1031
|
+
webExMeetingId,
|
|
1032
|
+
},
|
|
807
1033
|
});
|
|
808
1034
|
});
|
|
809
1035
|
|
|
@@ -826,7 +1052,7 @@ describe('plugin-meetings', () => {
|
|
|
826
1052
|
|
|
827
1053
|
it('should not try to match USM meetings by conversation url', async () => {
|
|
828
1054
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
|
|
829
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1055
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
830
1056
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
831
1057
|
'locusUrl',
|
|
832
1058
|
url1,
|
|
@@ -843,7 +1069,7 @@ describe('plugin-meetings', () => {
|
|
|
843
1069
|
});
|
|
844
1070
|
it('should try to match non-USM meetings by conversation url', async () => {
|
|
845
1071
|
await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
|
|
846
|
-
assert.callCount(webex.meetings.meetingCollection.getByKey,
|
|
1072
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
847
1073
|
assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
|
|
848
1074
|
'locusUrl',
|
|
849
1075
|
url1,
|
|
@@ -866,7 +1092,6 @@ describe('plugin-meetings', () => {
|
|
|
866
1092
|
});
|
|
867
1093
|
describe('#createMeeting', () => {
|
|
868
1094
|
beforeEach(() => {
|
|
869
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
870
1095
|
webex.internal.device.userId = uuid1;
|
|
871
1096
|
webex.internal.device.url = url1;
|
|
872
1097
|
MeetingCollection.set = sinon.stub().returns(true);
|
|
@@ -875,6 +1100,10 @@ describe('plugin-meetings', () => {
|
|
|
875
1100
|
});
|
|
876
1101
|
describe('successful MeetingInfo.#fetchMeetingInfo', () => {
|
|
877
1102
|
let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
|
|
1103
|
+
const FAKE_INFO_EXTRA_PARAMS = {
|
|
1104
|
+
mtid: 'm9fe0afd8c435e892afcce9ea25b97046',
|
|
1105
|
+
joinTXId: 'TSmrX61wNF',
|
|
1106
|
+
};
|
|
878
1107
|
|
|
879
1108
|
beforeEach(() => {
|
|
880
1109
|
clock = sinon.useFakeTimers();
|
|
@@ -904,13 +1133,25 @@ describe('plugin-meetings', () => {
|
|
|
904
1133
|
meeting,
|
|
905
1134
|
destination,
|
|
906
1135
|
type,
|
|
907
|
-
|
|
1136
|
+
extraParams = {},
|
|
1137
|
+
expectedMeetingData = {},
|
|
1138
|
+
sendCAevents = false
|
|
908
1139
|
) => {
|
|
909
1140
|
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
910
1141
|
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
911
1142
|
assert.notCalled(setTimeoutSpy);
|
|
912
|
-
assert.
|
|
913
|
-
assert.calledWith(
|
|
1143
|
+
assert.callCount(TriggerProxy.trigger, 5);
|
|
1144
|
+
assert.calledWith(
|
|
1145
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1146
|
+
destination,
|
|
1147
|
+
type,
|
|
1148
|
+
null,
|
|
1149
|
+
null,
|
|
1150
|
+
undefined,
|
|
1151
|
+
undefined,
|
|
1152
|
+
extraParams,
|
|
1153
|
+
{meetingId: meeting.id, sendCAevents}
|
|
1154
|
+
);
|
|
914
1155
|
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
915
1156
|
|
|
916
1157
|
if (expectedMeetingData.permissionToken) {
|
|
@@ -919,6 +1160,15 @@ describe('plugin-meetings', () => {
|
|
|
919
1160
|
if (expectedMeetingData.meetingJoinUrl) {
|
|
920
1161
|
assert.equal(meeting.meetingJoinUrl, expectedMeetingData.meetingJoinUrl);
|
|
921
1162
|
}
|
|
1163
|
+
if (expectedMeetingData.correlationId) {
|
|
1164
|
+
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1165
|
+
}
|
|
1166
|
+
if (expectedMeetingData.callStateForMetrics) {
|
|
1167
|
+
assert.deepEqual(
|
|
1168
|
+
meeting.callStateForMetrics,
|
|
1169
|
+
expectedMeetingData.callStateForMetrics
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
922
1172
|
assert.equal(meeting.destination, destination);
|
|
923
1173
|
assert.equal(meeting.destinationType, type);
|
|
924
1174
|
assert.calledWith(
|
|
@@ -948,27 +1198,142 @@ describe('plugin-meetings', () => {
|
|
|
948
1198
|
const expectedMeetingData = {
|
|
949
1199
|
permissionToken: 'PT',
|
|
950
1200
|
meetingJoinUrl: 'meetingJoinUrl',
|
|
1201
|
+
correlationId: meeting.id,
|
|
951
1202
|
};
|
|
952
1203
|
|
|
953
|
-
checkCreateWithoutDelay(
|
|
1204
|
+
checkCreateWithoutDelay(
|
|
1205
|
+
meeting,
|
|
1206
|
+
'test destination',
|
|
1207
|
+
'test type',
|
|
1208
|
+
{},
|
|
1209
|
+
expectedMeetingData
|
|
1210
|
+
);
|
|
954
1211
|
});
|
|
955
1212
|
|
|
956
|
-
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
}
|
|
1213
|
+
[undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
|
|
1214
|
+
const infoExtraParamsProvided = infoExtraParams !== undefined;
|
|
1215
|
+
|
|
1216
|
+
it(`creates the meeting from a successful meeting info fetch meeting resolve testing${
|
|
1217
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1218
|
+
}`, async () => {
|
|
1219
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1220
|
+
'test destination',
|
|
1221
|
+
'test type',
|
|
1222
|
+
false,
|
|
1223
|
+
infoExtraParams
|
|
1224
|
+
);
|
|
1225
|
+
const expectedMeetingData = {
|
|
1226
|
+
permissionToken: 'PT',
|
|
1227
|
+
meetingJoinUrl: 'meetingJoinUrl',
|
|
1228
|
+
};
|
|
1229
|
+
|
|
1230
|
+
assert.instanceOf(
|
|
1231
|
+
meeting,
|
|
1232
|
+
Meeting,
|
|
1233
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1234
|
+
);
|
|
1235
|
+
checkCreateWithoutDelay(
|
|
1236
|
+
meeting,
|
|
1237
|
+
'test destination',
|
|
1238
|
+
'test type',
|
|
1239
|
+
infoExtraParamsProvided ? infoExtraParams : {},
|
|
1240
|
+
expectedMeetingData
|
|
1241
|
+
);
|
|
1242
|
+
});
|
|
962
1243
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1244
|
+
it(`creates the meeting from a successful meeting info fetch with random delay${
|
|
1245
|
+
infoExtraParamsProvided ? ' with infoExtraParams' : ''
|
|
1246
|
+
}`, async () => {
|
|
1247
|
+
const FAKE_LOCUS_MEETING = {
|
|
1248
|
+
conversationUrl: 'locusConvURL',
|
|
1249
|
+
url: 'locusUrl',
|
|
1250
|
+
info: {
|
|
1251
|
+
webExMeetingId: 'locusMeetingId',
|
|
1252
|
+
sipUri: 'locusSipUri',
|
|
1253
|
+
owner: 'locusOwner',
|
|
1254
|
+
},
|
|
1255
|
+
meeting: {
|
|
1256
|
+
startTime: fakeMeetingStartTimeString,
|
|
1257
|
+
},
|
|
1258
|
+
fullState: {
|
|
1259
|
+
active: false,
|
|
1260
|
+
},
|
|
1261
|
+
};
|
|
1262
|
+
|
|
1263
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1264
|
+
FAKE_LOCUS_MEETING,
|
|
1265
|
+
'test type',
|
|
1266
|
+
true,
|
|
1267
|
+
infoExtraParams
|
|
1268
|
+
);
|
|
1269
|
+
|
|
1270
|
+
assert.instanceOf(
|
|
1271
|
+
meeting,
|
|
1272
|
+
Meeting,
|
|
1273
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1274
|
+
);
|
|
1275
|
+
assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1276
|
+
assert.calledOnce(setTimeoutSpy);
|
|
1277
|
+
|
|
1278
|
+
// Parse meeting info with locus object
|
|
1279
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1280
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1281
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1282
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1283
|
+
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1284
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1285
|
+
assert.isUndefined(meeting.permissionToken);
|
|
1286
|
+
|
|
1287
|
+
// Add meeting and send trigger
|
|
1288
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1289
|
+
assert.calledTwice(TriggerProxy.trigger);
|
|
1290
|
+
assert.calledWith(
|
|
1291
|
+
TriggerProxy.trigger,
|
|
1292
|
+
sinon.match.instanceOf(Meetings),
|
|
1293
|
+
{
|
|
1294
|
+
file: 'meetings',
|
|
1295
|
+
function: 'createMeeting',
|
|
1296
|
+
},
|
|
1297
|
+
'meeting:added',
|
|
1298
|
+
{
|
|
1299
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1300
|
+
type: 'test meeting added type',
|
|
1301
|
+
}
|
|
1302
|
+
);
|
|
1303
|
+
|
|
1304
|
+
// When timer expires
|
|
1305
|
+
clock.tick(FAKE_TIME_TO_START);
|
|
1306
|
+
assert.calledWith(
|
|
1307
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1308
|
+
FAKE_LOCUS_MEETING,
|
|
1309
|
+
'test type',
|
|
1310
|
+
null,
|
|
1311
|
+
null,
|
|
1312
|
+
undefined,
|
|
1313
|
+
undefined,
|
|
1314
|
+
infoExtraParamsProvided ? infoExtraParams : {}
|
|
1315
|
+
);
|
|
1316
|
+
|
|
1317
|
+
// Parse meeting info is called again with new meeting info
|
|
1318
|
+
await testUtils.flushPromises();
|
|
1319
|
+
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1320
|
+
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1321
|
+
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1322
|
+
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1323
|
+
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1324
|
+
assert.equal(meeting.owner, 'locusOwner');
|
|
1325
|
+
assert.equal(meeting.permissionToken, 'PT');
|
|
1326
|
+
|
|
1327
|
+
assert.calledWith(
|
|
1328
|
+
TriggerProxy.trigger,
|
|
1329
|
+
meeting,
|
|
1330
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1331
|
+
'meeting:meetingInfoAvailable'
|
|
1332
|
+
);
|
|
1333
|
+
});
|
|
969
1334
|
});
|
|
970
1335
|
|
|
971
|
-
it('creates the meeting from a successful meeting info fetch
|
|
1336
|
+
it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
|
|
972
1337
|
const FAKE_LOCUS_MEETING = {
|
|
973
1338
|
conversationUrl: 'locusConvURL',
|
|
974
1339
|
url: 'locusUrl',
|
|
@@ -981,7 +1346,7 @@ describe('plugin-meetings', () => {
|
|
|
981
1346
|
startTime: fakeMeetingStartTimeString,
|
|
982
1347
|
},
|
|
983
1348
|
fullState: {
|
|
984
|
-
active:
|
|
1349
|
+
active: true,
|
|
985
1350
|
},
|
|
986
1351
|
};
|
|
987
1352
|
|
|
@@ -996,62 +1361,10 @@ describe('plugin-meetings', () => {
|
|
|
996
1361
|
Meeting,
|
|
997
1362
|
'createMeeting should eventually resolve to a Meeting Object'
|
|
998
1363
|
);
|
|
999
|
-
|
|
1000
|
-
assert.calledOnce(setTimeoutSpy);
|
|
1001
|
-
|
|
1002
|
-
// Parse meeting info with locus object
|
|
1003
|
-
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1004
|
-
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1005
|
-
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1006
|
-
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1007
|
-
assert.isUndefined(meeting.meetingJoinUrl);
|
|
1008
|
-
assert.equal(meeting.owner, 'locusOwner');
|
|
1009
|
-
assert.isUndefined(meeting.permissionToken);
|
|
1010
|
-
|
|
1011
|
-
// Add meeting and send trigger
|
|
1012
|
-
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1013
|
-
assert.calledTwice(TriggerProxy.trigger);
|
|
1014
|
-
assert.calledWith(
|
|
1015
|
-
TriggerProxy.trigger,
|
|
1016
|
-
sinon.match.instanceOf(Meetings),
|
|
1017
|
-
{
|
|
1018
|
-
file: 'meetings',
|
|
1019
|
-
function: 'createMeeting',
|
|
1020
|
-
},
|
|
1021
|
-
'meeting:added',
|
|
1022
|
-
{
|
|
1023
|
-
meeting: sinon.match.instanceOf(Meeting),
|
|
1024
|
-
type: 'test meeting added type',
|
|
1025
|
-
}
|
|
1026
|
-
);
|
|
1027
|
-
|
|
1028
|
-
// When timer expires
|
|
1029
|
-
clock.tick(FAKE_TIME_TO_START);
|
|
1030
|
-
assert.calledWith(
|
|
1031
|
-
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1032
|
-
FAKE_LOCUS_MEETING,
|
|
1033
|
-
'test type'
|
|
1034
|
-
);
|
|
1035
|
-
|
|
1036
|
-
// Parse meeting info is called again with new meeting info
|
|
1037
|
-
await testUtils.flushPromises();
|
|
1038
|
-
assert.equal(meeting.conversationUrl, 'locusConvURL');
|
|
1039
|
-
assert.equal(meeting.locusUrl, 'locusUrl');
|
|
1040
|
-
assert.equal(meeting.sipUri, 'locusSipUri');
|
|
1041
|
-
assert.equal(meeting.meetingNumber, 'locusMeetingId');
|
|
1042
|
-
assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
|
|
1043
|
-
assert.equal(meeting.owner, 'locusOwner');
|
|
1044
|
-
assert.equal(meeting.permissionToken, 'PT');
|
|
1045
|
-
|
|
1046
|
-
assert.calledWith(
|
|
1047
|
-
TriggerProxy.trigger,
|
|
1048
|
-
meeting,
|
|
1049
|
-
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
1050
|
-
'meeting:meetingInfoAvailable'
|
|
1051
|
-
);
|
|
1364
|
+
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1052
1365
|
});
|
|
1053
1366
|
|
|
1054
|
-
it('creates the meeting from a successful meeting info fetch that has no random delay because
|
|
1367
|
+
it('creates the meeting from a successful meeting info fetch that has no random delay because meeting start time is in the past', async () => {
|
|
1055
1368
|
const FAKE_LOCUS_MEETING = {
|
|
1056
1369
|
conversationUrl: 'locusConvURL',
|
|
1057
1370
|
url: 'locusUrl',
|
|
@@ -1061,10 +1374,10 @@ describe('plugin-meetings', () => {
|
|
|
1061
1374
|
owner: 'locusOwner',
|
|
1062
1375
|
},
|
|
1063
1376
|
meeting: {
|
|
1064
|
-
startTime: fakeMeetingStartTimeString,
|
|
1377
|
+
startTime: fakeMeetingStartTimeString - 1 * 60 * 60 * 1000,
|
|
1065
1378
|
},
|
|
1066
1379
|
fullState: {
|
|
1067
|
-
active:
|
|
1380
|
+
active: false,
|
|
1068
1381
|
},
|
|
1069
1382
|
};
|
|
1070
1383
|
|
|
@@ -1082,7 +1395,12 @@ describe('plugin-meetings', () => {
|
|
|
1082
1395
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1083
1396
|
});
|
|
1084
1397
|
|
|
1085
|
-
it('creates the meeting from a successful meeting info fetch that has no random delay because
|
|
1398
|
+
it('creates the meeting from a successful meeting info fetch that has no random delay because enableUnifiedMeetings is disabled', async () => {
|
|
1399
|
+
Object.assign(webex.meetings.config, {
|
|
1400
|
+
experimental: {
|
|
1401
|
+
enableUnifiedMeetings: false,
|
|
1402
|
+
},
|
|
1403
|
+
});
|
|
1086
1404
|
const FAKE_LOCUS_MEETING = {
|
|
1087
1405
|
conversationUrl: 'locusConvURL',
|
|
1088
1406
|
url: 'locusUrl',
|
|
@@ -1092,7 +1410,7 @@ describe('plugin-meetings', () => {
|
|
|
1092
1410
|
owner: 'locusOwner',
|
|
1093
1411
|
},
|
|
1094
1412
|
meeting: {
|
|
1095
|
-
startTime: fakeMeetingStartTimeString
|
|
1413
|
+
startTime: fakeMeetingStartTimeString,
|
|
1096
1414
|
},
|
|
1097
1415
|
fullState: {
|
|
1098
1416
|
active: false,
|
|
@@ -1113,40 +1431,59 @@ describe('plugin-meetings', () => {
|
|
|
1113
1431
|
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1114
1432
|
});
|
|
1115
1433
|
|
|
1116
|
-
it('creates
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
sipUri: 'locusSipUri',
|
|
1128
|
-
owner: 'locusOwner',
|
|
1129
|
-
},
|
|
1130
|
-
meeting: {
|
|
1131
|
-
startTime: fakeMeetingStartTimeString,
|
|
1132
|
-
},
|
|
1133
|
-
fullState: {
|
|
1134
|
-
active: false,
|
|
1135
|
-
},
|
|
1434
|
+
it('creates meeting with the correlationId provided', async () => {
|
|
1435
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1436
|
+
'test destination',
|
|
1437
|
+
'test type',
|
|
1438
|
+
false,
|
|
1439
|
+
{},
|
|
1440
|
+
{correlationId: 'my-correlationId'}
|
|
1441
|
+
);
|
|
1442
|
+
|
|
1443
|
+
const expectedMeetingData = {
|
|
1444
|
+
correlationId: 'my-correlationId',
|
|
1136
1445
|
};
|
|
1137
1446
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1447
|
+
checkCreateWithoutDelay(
|
|
1448
|
+
meeting,
|
|
1449
|
+
'test destination',
|
|
1140
1450
|
'test type',
|
|
1451
|
+
{},
|
|
1452
|
+
expectedMeetingData,
|
|
1141
1453
|
true
|
|
1142
1454
|
);
|
|
1455
|
+
});
|
|
1143
1456
|
|
|
1144
|
-
|
|
1457
|
+
it('creates meeting with the callStateForMetrics provided', async () => {
|
|
1458
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1459
|
+
'test destination',
|
|
1460
|
+
'test type',
|
|
1461
|
+
false,
|
|
1462
|
+
{},
|
|
1463
|
+
{
|
|
1464
|
+
correlationId: 'my-correlationId',
|
|
1465
|
+
joinTrigger: 'my-join-trigger',
|
|
1466
|
+
loginType: 'my-login-type',
|
|
1467
|
+
}
|
|
1468
|
+
);
|
|
1469
|
+
|
|
1470
|
+
const expectedMeetingData = {
|
|
1471
|
+
correlationId: 'my-correlationId',
|
|
1472
|
+
callStateForMetrics: {
|
|
1473
|
+
correlationId: 'my-correlationId',
|
|
1474
|
+
joinTrigger: 'my-join-trigger',
|
|
1475
|
+
loginType: 'my-login-type',
|
|
1476
|
+
},
|
|
1477
|
+
};
|
|
1478
|
+
|
|
1479
|
+
checkCreateWithoutDelay(
|
|
1145
1480
|
meeting,
|
|
1146
|
-
|
|
1147
|
-
'
|
|
1481
|
+
'test destination',
|
|
1482
|
+
'test type',
|
|
1483
|
+
{},
|
|
1484
|
+
expectedMeetingData,
|
|
1485
|
+
true
|
|
1148
1486
|
);
|
|
1149
|
-
checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
|
|
1150
1487
|
});
|
|
1151
1488
|
});
|
|
1152
1489
|
|
|
@@ -1157,45 +1494,136 @@ describe('plugin-meetings', () => {
|
|
|
1157
1494
|
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1158
1495
|
.stub()
|
|
1159
1496
|
.returns(Promise.reject(new Error('test')));
|
|
1497
|
+
webex.meetings.destroy = sinon.stub().returns(Promise.resolve());
|
|
1498
|
+
webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
|
|
1160
1499
|
});
|
|
1500
|
+
|
|
1501
|
+
const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
|
|
1502
|
+
try {
|
|
1503
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1504
|
+
'test destination',
|
|
1505
|
+
'test type',
|
|
1506
|
+
undefined,
|
|
1507
|
+
undefined,
|
|
1508
|
+
undefined,
|
|
1509
|
+
failOnMissingMeetingInfo
|
|
1510
|
+
);
|
|
1511
|
+
|
|
1512
|
+
assert.instanceOf(
|
|
1513
|
+
meeting,
|
|
1514
|
+
Meeting,
|
|
1515
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1516
|
+
);
|
|
1517
|
+
assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
|
|
1518
|
+
assert.calledOnce(MeetingsUtil.getMeetingAddedType);
|
|
1519
|
+
assert.calledThrice(TriggerProxy.trigger);
|
|
1520
|
+
assert.calledWith(
|
|
1521
|
+
webex.meetings.meetingInfo.fetchMeetingInfo,
|
|
1522
|
+
'test destination',
|
|
1523
|
+
'test type'
|
|
1524
|
+
);
|
|
1525
|
+
|
|
1526
|
+
if (destroy) {
|
|
1527
|
+
assert.calledWith(
|
|
1528
|
+
webex.meetings.destroy,
|
|
1529
|
+
sinon.match.instanceOf(Meeting),
|
|
1530
|
+
'MISSING_MEETING_INFO'
|
|
1531
|
+
);
|
|
1532
|
+
assert.notCalled(MeetingsUtil.getMeetingAddedType);
|
|
1533
|
+
assert.notCalled(TriggerProxy.trigger);
|
|
1534
|
+
assert.throw(webex.meetings.createMeeting, 'meeting information not found');
|
|
1535
|
+
} else {
|
|
1536
|
+
assert.notCalled(webex.meetings.destroy);
|
|
1537
|
+
assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
|
|
1538
|
+
assert.calledWith(
|
|
1539
|
+
TriggerProxy.trigger,
|
|
1540
|
+
sinon.match.instanceOf(Meetings),
|
|
1541
|
+
{
|
|
1542
|
+
file: 'meetings',
|
|
1543
|
+
function: 'createMeeting',
|
|
1544
|
+
},
|
|
1545
|
+
'meeting:added',
|
|
1546
|
+
{
|
|
1547
|
+
meeting: sinon.match.instanceOf(Meeting),
|
|
1548
|
+
type: 'test meeting added type',
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
} catch (err) {
|
|
1553
|
+
assert.instanceOf(err, NoMeetingInfoError);
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
|
|
1161
1557
|
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1162
|
-
|
|
1558
|
+
checkCreateMeetingWithNoMeetingInfo(false, false);
|
|
1559
|
+
});
|
|
1163
1560
|
|
|
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),
|
|
1561
|
+
it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
|
|
1562
|
+
checkCreateMeetingWithNoMeetingInfo(true, true);
|
|
1563
|
+
});
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1566
|
+
describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
|
|
1567
|
+
forEach(
|
|
1568
|
+
[
|
|
1181
1569
|
{
|
|
1182
|
-
|
|
1183
|
-
|
|
1570
|
+
error: new CaptchaError(),
|
|
1571
|
+
debugLogMessage:
|
|
1572
|
+
'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
|
|
1184
1573
|
},
|
|
1185
|
-
'meeting:added',
|
|
1186
1574
|
{
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1575
|
+
error: new PasswordError(),
|
|
1576
|
+
debugLogMessage:
|
|
1577
|
+
'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
|
|
1578
|
+
},
|
|
1579
|
+
{
|
|
1580
|
+
error: new PermissionError(),
|
|
1581
|
+
debugLogMessage:
|
|
1582
|
+
'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.',
|
|
1583
|
+
},
|
|
1584
|
+
{
|
|
1585
|
+
error: new Error(),
|
|
1586
|
+
infoLogMessage: true,
|
|
1587
|
+
debugLogMessage:
|
|
1588
|
+
'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
|
|
1589
|
+
},
|
|
1590
|
+
],
|
|
1591
|
+
({error, debugLogMessage, infoLogMessage}) => {
|
|
1592
|
+
it('creates the meeting from a rejected meeting info fetch', async () => {
|
|
1593
|
+
webex.meetings.meetingInfo.fetchMeetingInfo = sinon
|
|
1594
|
+
.stub()
|
|
1595
|
+
.returns(Promise.reject(error));
|
|
1596
|
+
|
|
1597
|
+
LoggerProxy.logger.debug = sinon.stub();
|
|
1598
|
+
LoggerProxy.logger.info = sinon.stub();
|
|
1599
|
+
|
|
1600
|
+
const meeting = await webex.meetings.createMeeting('test destination', 'test type');
|
|
1601
|
+
|
|
1602
|
+
assert.instanceOf(
|
|
1603
|
+
meeting,
|
|
1604
|
+
Meeting,
|
|
1605
|
+
'createMeeting should eventually resolve to a Meeting Object'
|
|
1606
|
+
);
|
|
1607
|
+
|
|
1608
|
+
assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
|
|
1609
|
+
|
|
1610
|
+
if (infoLogMessage) {
|
|
1611
|
+
assert.calledWith(
|
|
1612
|
+
LoggerProxy.logger.info,
|
|
1613
|
+
'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
|
|
1614
|
+
);
|
|
1615
|
+
} else {
|
|
1616
|
+
assert.notCalled(LoggerProxy.logger.info);
|
|
1617
|
+
}
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
);
|
|
1192
1621
|
});
|
|
1193
1622
|
});
|
|
1194
1623
|
});
|
|
1195
1624
|
describe('Public Event Triggers', () => {
|
|
1196
1625
|
describe('#destroy', () => {
|
|
1197
1626
|
beforeEach(() => {
|
|
1198
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
1199
1627
|
MeetingUtil.cleanUp = sinon.stub();
|
|
1200
1628
|
});
|
|
1201
1629
|
it('should have #destroy', () => {
|
|
@@ -1269,6 +1697,8 @@ describe('plugin-meetings', () => {
|
|
|
1269
1697
|
});
|
|
1270
1698
|
|
|
1271
1699
|
describe('#fetchUserPreferredWebexSite', () => {
|
|
1700
|
+
let loggerProxySpy;
|
|
1701
|
+
|
|
1272
1702
|
it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
|
|
1273
1703
|
assert.isDefined(webex.meetings.preferredWebexSite);
|
|
1274
1704
|
await webex.meetings.fetchUserPreferredWebexSite();
|
|
@@ -1276,7 +1706,22 @@ describe('plugin-meetings', () => {
|
|
|
1276
1706
|
assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
|
|
1277
1707
|
});
|
|
1278
1708
|
|
|
1709
|
+
const setup = ({user} = {}) => {
|
|
1710
|
+
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
|
|
1711
|
+
|
|
1712
|
+
Object.assign(webex.internal, {
|
|
1713
|
+
services: {
|
|
1714
|
+
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
1715
|
+
},
|
|
1716
|
+
user: {
|
|
1717
|
+
get: sinon.stub().returns(Promise.resolve(user)),
|
|
1718
|
+
},
|
|
1719
|
+
});
|
|
1720
|
+
};
|
|
1721
|
+
|
|
1279
1722
|
it('should not fail if UserPreferred info is not fetched ', async () => {
|
|
1723
|
+
setup();
|
|
1724
|
+
|
|
1280
1725
|
Object.assign(webex.internal, {
|
|
1281
1726
|
services: {
|
|
1282
1727
|
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
|
|
@@ -1286,7 +1731,115 @@ describe('plugin-meetings', () => {
|
|
|
1286
1731
|
await webex.meetings.fetchUserPreferredWebexSite().then(() => {
|
|
1287
1732
|
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1288
1733
|
});
|
|
1734
|
+
assert.calledOnceWithExactly(
|
|
1735
|
+
loggerProxySpy,
|
|
1736
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1737
|
+
);
|
|
1738
|
+
});
|
|
1739
|
+
|
|
1740
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1741
|
+
setup({
|
|
1742
|
+
user: {
|
|
1743
|
+
userPreferences: {
|
|
1744
|
+
userPreferencesItems: {
|
|
1745
|
+
preferredWebExSite: 'site.webex.com',
|
|
1746
|
+
},
|
|
1747
|
+
},
|
|
1748
|
+
},
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1752
|
+
|
|
1753
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1754
|
+
assert.notCalled(loggerProxySpy);
|
|
1755
|
+
});
|
|
1756
|
+
|
|
1757
|
+
forEach(
|
|
1758
|
+
[
|
|
1759
|
+
{user: undefined},
|
|
1760
|
+
{user: {userPreferences: {}}},
|
|
1761
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1762
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1763
|
+
],
|
|
1764
|
+
({user}) => {
|
|
1765
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1766
|
+
setup({user});
|
|
1767
|
+
|
|
1768
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1769
|
+
|
|
1770
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1771
|
+
assert.calledOnceWithExactly(
|
|
1772
|
+
loggerProxySpy,
|
|
1773
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1774
|
+
);
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
);
|
|
1778
|
+
|
|
1779
|
+
it('should handle a get user failure', async () => {
|
|
1780
|
+
setup();
|
|
1781
|
+
|
|
1782
|
+
webex.internal.user.get.rejects(new Error());
|
|
1783
|
+
|
|
1784
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1785
|
+
|
|
1786
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1787
|
+
assert.calledOnceWithExactly(
|
|
1788
|
+
loggerProxySpy,
|
|
1789
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1790
|
+
);
|
|
1791
|
+
});
|
|
1792
|
+
|
|
1793
|
+
it('should fall back to fetching the site from the user', async () => {
|
|
1794
|
+
setup({
|
|
1795
|
+
user: {
|
|
1796
|
+
userPreferences: {
|
|
1797
|
+
userPreferencesItems: {
|
|
1798
|
+
preferredWebExSite: 'site.webex.com',
|
|
1799
|
+
},
|
|
1800
|
+
},
|
|
1801
|
+
},
|
|
1802
|
+
});
|
|
1803
|
+
|
|
1804
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1805
|
+
|
|
1806
|
+
assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
|
|
1807
|
+
assert.notCalled(loggerProxySpy);
|
|
1289
1808
|
});
|
|
1809
|
+
|
|
1810
|
+
forEach([
|
|
1811
|
+
{user: undefined},
|
|
1812
|
+
{user: {userPreferences: {}}},
|
|
1813
|
+
{user: {userPreferences: {userPreferencesItems: {}}}},
|
|
1814
|
+
{user: {userPreferences: {userPreferencesItems: {preferredWebExSite: undefined}}}},
|
|
1815
|
+
], ({user}) => {
|
|
1816
|
+
it(`should handle invalid user data ${user}`, async () => {
|
|
1817
|
+
setup({user});
|
|
1818
|
+
|
|
1819
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1820
|
+
|
|
1821
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1822
|
+
assert.calledOnceWithExactly(
|
|
1823
|
+
loggerProxySpy,
|
|
1824
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1825
|
+
);
|
|
1826
|
+
});
|
|
1827
|
+
});
|
|
1828
|
+
|
|
1829
|
+
it('should handle a get user failure', async () => {
|
|
1830
|
+
setup();
|
|
1831
|
+
|
|
1832
|
+
webex.internal.user.get.rejects(new Error());
|
|
1833
|
+
|
|
1834
|
+
await webex.meetings.fetchUserPreferredWebexSite();
|
|
1835
|
+
|
|
1836
|
+
assert.equal(webex.meetings.preferredWebexSite, '');
|
|
1837
|
+
assert.calledOnceWithExactly(
|
|
1838
|
+
loggerProxySpy,
|
|
1839
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1840
|
+
);
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1290
1843
|
});
|
|
1291
1844
|
});
|
|
1292
1845
|
|
|
@@ -1294,7 +1847,6 @@ describe('plugin-meetings', () => {
|
|
|
1294
1847
|
let meeting;
|
|
1295
1848
|
|
|
1296
1849
|
beforeEach(async () => {
|
|
1297
|
-
MediaUtil.createPeerConnection = sinon.stub().returns(true);
|
|
1298
1850
|
webex.internal.device.userId = uuid1;
|
|
1299
1851
|
webex.internal.device.url = url1;
|
|
1300
1852
|
MeetingCollection.set = sinon.stub().returns(true);
|
|
@@ -1371,5 +1923,523 @@ describe('plugin-meetings', () => {
|
|
|
1371
1923
|
);
|
|
1372
1924
|
});
|
|
1373
1925
|
});
|
|
1926
|
+
|
|
1927
|
+
describe('#isNeedHandleMainLocus', () => {
|
|
1928
|
+
let meeting;
|
|
1929
|
+
let newLocus;
|
|
1930
|
+
beforeEach(() => {
|
|
1931
|
+
meeting = {
|
|
1932
|
+
controls: {},
|
|
1933
|
+
self: {},
|
|
1934
|
+
};
|
|
1935
|
+
newLocus = {
|
|
1936
|
+
controls: {},
|
|
1937
|
+
self: {},
|
|
1938
|
+
};
|
|
1939
|
+
});
|
|
1940
|
+
afterEach(() => {
|
|
1941
|
+
sinon.restore();
|
|
1942
|
+
});
|
|
1943
|
+
it('check normal case will return true', () => {
|
|
1944
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1945
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1946
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1947
|
+
assert.equal(result, true);
|
|
1948
|
+
assert.calledWith(
|
|
1949
|
+
LoggerProxy.logger.log,
|
|
1950
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
1951
|
+
);
|
|
1952
|
+
});
|
|
1953
|
+
|
|
1954
|
+
it('check self joined and joined on this device, return true', () => {
|
|
1955
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
|
|
1956
|
+
newLocus.self.state = 'JOINED';
|
|
1957
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1958
|
+
|
|
1959
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1960
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1961
|
+
assert.equal(result, true);
|
|
1962
|
+
assert.calledWith(
|
|
1963
|
+
LoggerProxy.logger.log,
|
|
1964
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
1965
|
+
);
|
|
1966
|
+
});
|
|
1967
|
+
|
|
1968
|
+
it('if newLocus replaceAt time is expired, then return false', () => {
|
|
1969
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1970
|
+
joinedWith: {
|
|
1971
|
+
replaces: [
|
|
1972
|
+
{
|
|
1973
|
+
replaceAt: '2023-03-27T02:17:02.506Z',
|
|
1974
|
+
},
|
|
1975
|
+
],
|
|
1976
|
+
},
|
|
1977
|
+
});
|
|
1978
|
+
newLocus.self.state = 'JOINED';
|
|
1979
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
|
|
1980
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
1981
|
+
replaces: [
|
|
1982
|
+
{
|
|
1983
|
+
replaceAt: '2023-03-27T02:17:01.506Z',
|
|
1984
|
+
},
|
|
1985
|
+
],
|
|
1986
|
+
});
|
|
1987
|
+
|
|
1988
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
1989
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
1990
|
+
assert.equal(result, false);
|
|
1991
|
+
assert.calledWith(
|
|
1992
|
+
LoggerProxy.logger.log,
|
|
1993
|
+
`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`
|
|
1994
|
+
);
|
|
1995
|
+
});
|
|
1996
|
+
|
|
1997
|
+
it('check current is in breakout join with this device, return false', () => {
|
|
1998
|
+
sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
|
|
1999
|
+
joinedWith: {
|
|
2000
|
+
correlationId: '111',
|
|
2001
|
+
},
|
|
2002
|
+
});
|
|
2003
|
+
newLocus.controls.breakout = {url: 'url'};
|
|
2004
|
+
meeting.correlationId = '111';
|
|
2005
|
+
|
|
2006
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2007
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2008
|
+
assert.equal(result, false);
|
|
2009
|
+
assert.calledWith(
|
|
2010
|
+
LoggerProxy.logger.log,
|
|
2011
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
|
|
2012
|
+
);
|
|
2013
|
+
});
|
|
2014
|
+
|
|
2015
|
+
it('check self is moved and removed, return false', () => {
|
|
2016
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2017
|
+
newLocus.self.state = 'LEFT';
|
|
2018
|
+
newLocus.self.reason = 'MOVED';
|
|
2019
|
+
newLocus.self.removed = true;
|
|
2020
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2021
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2022
|
+
assert.equal(result, false);
|
|
2023
|
+
assert.calledWith(
|
|
2024
|
+
LoggerProxy.logger.log,
|
|
2025
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2026
|
+
);
|
|
2027
|
+
});
|
|
2028
|
+
|
|
2029
|
+
it('check self is moved and device resource removed, return false', () => {
|
|
2030
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2031
|
+
newLocus.self.state = 'LEFT';
|
|
2032
|
+
newLocus.self.reason = 'MOVED';
|
|
2033
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2034
|
+
state: 'LEFT',
|
|
2035
|
+
reason: 'MOVED',
|
|
2036
|
+
});
|
|
2037
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2038
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2039
|
+
assert.equal(result, false);
|
|
2040
|
+
assert.calledWith(
|
|
2041
|
+
LoggerProxy.logger.log,
|
|
2042
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
2043
|
+
);
|
|
2044
|
+
});
|
|
2045
|
+
|
|
2046
|
+
it('check self is joined but device resource removed, return false', () => {
|
|
2047
|
+
webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
|
|
2048
|
+
sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(false);
|
|
2049
|
+
newLocus.self.state = 'JOINED';
|
|
2050
|
+
sinon.stub(MeetingsUtil, 'getThisDevice').returns({
|
|
2051
|
+
state: 'LEFT',
|
|
2052
|
+
reason: 'MOVED',
|
|
2053
|
+
});
|
|
2054
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2055
|
+
const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
|
|
2056
|
+
assert.equal(result, false);
|
|
2057
|
+
assert.calledWith(
|
|
2058
|
+
LoggerProxy.logger.log,
|
|
2059
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
2060
|
+
);
|
|
2061
|
+
});
|
|
2062
|
+
});
|
|
2063
|
+
|
|
2064
|
+
describe('#isNeedHandleLocusDTO', () => {
|
|
2065
|
+
let meeting;
|
|
2066
|
+
let newLocus;
|
|
2067
|
+
beforeEach(() => {
|
|
2068
|
+
meeting = {
|
|
2069
|
+
controls: {},
|
|
2070
|
+
self: {},
|
|
2071
|
+
};
|
|
2072
|
+
newLocus = {
|
|
2073
|
+
controls: {},
|
|
2074
|
+
self: {},
|
|
2075
|
+
};
|
|
2076
|
+
});
|
|
2077
|
+
afterEach(() => {
|
|
2078
|
+
sinon.restore();
|
|
2079
|
+
});
|
|
2080
|
+
it('initial DTO , joined breakout session, return true', () => {
|
|
2081
|
+
newLocus.controls.breakout = {
|
|
2082
|
+
sessionType: 'BREAKOUT',
|
|
2083
|
+
};
|
|
2084
|
+
newLocus.self.state = 'JOINED';
|
|
2085
|
+
newLocus.fullState = {
|
|
2086
|
+
active: true,
|
|
2087
|
+
};
|
|
2088
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2089
|
+
const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
|
|
2090
|
+
assert.equal(result, true);
|
|
2091
|
+
assert.calledWith(
|
|
2092
|
+
LoggerProxy.logger.log,
|
|
2093
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
|
|
2094
|
+
);
|
|
2095
|
+
});
|
|
2096
|
+
it('others go to check isNeedHandleMainLocus', () => {
|
|
2097
|
+
newLocus.controls.breakout = {
|
|
2098
|
+
sessionType: 'MAIN',
|
|
2099
|
+
};
|
|
2100
|
+
newLocus.self.state = 'JOINED';
|
|
2101
|
+
|
|
2102
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2103
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2104
|
+
assert.equal(result, true);
|
|
2105
|
+
assert.calledWith(
|
|
2106
|
+
LoggerProxy.logger.log,
|
|
2107
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
2108
|
+
);
|
|
2109
|
+
});
|
|
2110
|
+
it('joined breakout session, self status is moved, return false', () => {
|
|
2111
|
+
newLocus.controls.breakout = {
|
|
2112
|
+
sessionType: 'BREAKOUT',
|
|
2113
|
+
};
|
|
2114
|
+
newLocus.self.state = 'LEFT';
|
|
2115
|
+
newLocus.self.reason = 'MOVED';
|
|
2116
|
+
|
|
2117
|
+
LoggerProxy.logger.log = sinon.stub();
|
|
2118
|
+
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
|
|
2119
|
+
assert.equal(result, false);
|
|
2120
|
+
});
|
|
2121
|
+
});
|
|
2122
|
+
|
|
2123
|
+
describe('#getCorrespondingMeetingByLocus', () => {
|
|
2124
|
+
let locus;
|
|
2125
|
+
let mockReturnMeeting = {meeting: 'meeting1'};
|
|
2126
|
+
const mockGetByKey = (keyWillReturnMeeting) => {
|
|
2127
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
|
|
2128
|
+
if (key === keyWillReturnMeeting) {
|
|
2129
|
+
return mockReturnMeeting;
|
|
2130
|
+
}
|
|
2131
|
+
return null;
|
|
2132
|
+
});
|
|
2133
|
+
};
|
|
2134
|
+
|
|
2135
|
+
beforeEach(() => {
|
|
2136
|
+
locus = {
|
|
2137
|
+
controls: {},
|
|
2138
|
+
self: {
|
|
2139
|
+
callbackInfo: {
|
|
2140
|
+
callbackAddress: 'address1',
|
|
2141
|
+
},
|
|
2142
|
+
},
|
|
2143
|
+
info: {
|
|
2144
|
+
webExMeetingId: '123456',
|
|
2145
|
+
isUnifiedSpaceMeeting: false,
|
|
2146
|
+
},
|
|
2147
|
+
conversationUrl: 'conversationUrl1',
|
|
2148
|
+
};
|
|
2149
|
+
|
|
2150
|
+
sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
|
|
2151
|
+
});
|
|
2152
|
+
afterEach(() => {
|
|
2153
|
+
sinon.restore();
|
|
2154
|
+
});
|
|
2155
|
+
it('check the calls when no meeting found in meetingCollection', () => {
|
|
2156
|
+
mockGetByKey();
|
|
2157
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2158
|
+
assert.isNull(result);
|
|
2159
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2160
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2161
|
+
assert.calledWith(
|
|
2162
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2163
|
+
'correlationId',
|
|
2164
|
+
'correlationId1'
|
|
2165
|
+
);
|
|
2166
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2167
|
+
assert.calledWith(
|
|
2168
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2169
|
+
'conversationUrl',
|
|
2170
|
+
'conversationUrl1'
|
|
2171
|
+
);
|
|
2172
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2173
|
+
});
|
|
2174
|
+
|
|
2175
|
+
it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
|
|
2176
|
+
mockGetByKey();
|
|
2177
|
+
locus.info.isUnifiedSpaceMeeting = true;
|
|
2178
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2179
|
+
assert.isNull(result);
|
|
2180
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2181
|
+
});
|
|
2182
|
+
|
|
2183
|
+
it('check the calls when meeting found by key: locusUrl', () => {
|
|
2184
|
+
mockGetByKey('locusUrl');
|
|
2185
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2186
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2187
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
|
|
2188
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2189
|
+
});
|
|
2190
|
+
|
|
2191
|
+
it('check the calls when meeting found by key: correlationId', () => {
|
|
2192
|
+
mockGetByKey('correlationId');
|
|
2193
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2194
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2195
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
|
|
2196
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2197
|
+
assert.calledWith(
|
|
2198
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2199
|
+
'correlationId',
|
|
2200
|
+
'correlationId1'
|
|
2201
|
+
);
|
|
2202
|
+
});
|
|
2203
|
+
|
|
2204
|
+
it('check the calls when meeting found by key: sipUri', () => {
|
|
2205
|
+
mockGetByKey('sipUri');
|
|
2206
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2207
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2208
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
|
|
2209
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2210
|
+
assert.calledWith(
|
|
2211
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2212
|
+
'correlationId',
|
|
2213
|
+
'correlationId1'
|
|
2214
|
+
);
|
|
2215
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2216
|
+
});
|
|
2217
|
+
|
|
2218
|
+
it('check the calls when meeting found by key: conversationUrl', () => {
|
|
2219
|
+
mockGetByKey('conversationUrl');
|
|
2220
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2221
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2222
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
|
|
2223
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2224
|
+
assert.calledWith(
|
|
2225
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2226
|
+
'correlationId',
|
|
2227
|
+
'correlationId1'
|
|
2228
|
+
);
|
|
2229
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2230
|
+
assert.calledWith(
|
|
2231
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2232
|
+
'conversationUrl',
|
|
2233
|
+
'conversationUrl1'
|
|
2234
|
+
);
|
|
2235
|
+
});
|
|
2236
|
+
|
|
2237
|
+
it('check the calls when meeting found by key: meetingNumber', () => {
|
|
2238
|
+
mockGetByKey('meetingNumber');
|
|
2239
|
+
const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
|
|
2240
|
+
assert.deepEqual(result, mockReturnMeeting);
|
|
2241
|
+
assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
|
|
2242
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
|
|
2243
|
+
assert.calledWith(
|
|
2244
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2245
|
+
'correlationId',
|
|
2246
|
+
'correlationId1'
|
|
2247
|
+
);
|
|
2248
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
|
|
2249
|
+
assert.calledWith(
|
|
2250
|
+
webex.meetings.meetingCollection.getByKey,
|
|
2251
|
+
'conversationUrl',
|
|
2252
|
+
'conversationUrl1'
|
|
2253
|
+
);
|
|
2254
|
+
assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
|
|
2255
|
+
});
|
|
2256
|
+
});
|
|
2257
|
+
|
|
2258
|
+
describe('#sortLocusArrayToUpdate', () => {
|
|
2259
|
+
let lociArray;
|
|
2260
|
+
let mainLocus;
|
|
2261
|
+
let breakoutLocus;
|
|
2262
|
+
beforeEach(() => {
|
|
2263
|
+
mainLocus = {
|
|
2264
|
+
url: 'mainUrl1',
|
|
2265
|
+
controls: {
|
|
2266
|
+
breakout: {
|
|
2267
|
+
sessionType: 'MAIN',
|
|
2268
|
+
url: 'breakoutUnifiedUrl1',
|
|
2269
|
+
},
|
|
2270
|
+
},
|
|
2271
|
+
};
|
|
2272
|
+
breakoutLocus = {
|
|
2273
|
+
url: 'breakoutUrl1',
|
|
2274
|
+
controls: {
|
|
2275
|
+
breakout: {
|
|
2276
|
+
sessionType: 'BREAKOUT',
|
|
2277
|
+
url: 'breakoutUnifiedUrl1',
|
|
2278
|
+
},
|
|
2279
|
+
},
|
|
2280
|
+
};
|
|
2281
|
+
lociArray = [mainLocus, breakoutLocus];
|
|
2282
|
+
|
|
2283
|
+
sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
|
|
2284
|
+
return locus.url === 'breakoutUrl1';
|
|
2285
|
+
});
|
|
2286
|
+
});
|
|
2287
|
+
afterEach(() => {
|
|
2288
|
+
sinon.restore();
|
|
2289
|
+
});
|
|
2290
|
+
|
|
2291
|
+
it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
|
|
2292
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
|
|
2293
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2294
|
+
assert.deepEqual(result, [mainLocus]);
|
|
2295
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
|
|
2296
|
+
});
|
|
2297
|
+
|
|
2298
|
+
it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
|
|
2299
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2300
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2301
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2302
|
+
assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
|
|
2303
|
+
});
|
|
2304
|
+
|
|
2305
|
+
it('if the breakout locus has no associated main locus, return all', () => {
|
|
2306
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
|
|
2307
|
+
breakoutLocus.controls.breakout.url = 'testUrl';
|
|
2308
|
+
const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
|
|
2309
|
+
assert.deepEqual(result, [mainLocus, breakoutLocus]);
|
|
2310
|
+
});
|
|
2311
|
+
});
|
|
2312
|
+
|
|
2313
|
+
describe('#checkHandleBreakoutLocus', () => {
|
|
2314
|
+
let breakoutLocus;
|
|
2315
|
+
beforeEach(() => {
|
|
2316
|
+
breakoutLocus = {
|
|
2317
|
+
url: 'breakoutUrl1',
|
|
2318
|
+
controls: {
|
|
2319
|
+
breakout: {
|
|
2320
|
+
sessionType: 'BREAKOUT',
|
|
2321
|
+
url: 'breakoutUnifiedUrl1',
|
|
2322
|
+
},
|
|
2323
|
+
},
|
|
2324
|
+
};
|
|
2325
|
+
|
|
2326
|
+
webex.meetings.handleLocusEvent = sinon.stub();
|
|
2327
|
+
});
|
|
2328
|
+
afterEach(() => {
|
|
2329
|
+
sinon.restore();
|
|
2330
|
+
});
|
|
2331
|
+
it('do nothing if new created locus is null/no cached breakouts for updating', () => {
|
|
2332
|
+
webex.meetings.checkHandleBreakoutLocus(null);
|
|
2333
|
+
webex.meetings.breakoutLocusForHandleLater = null;
|
|
2334
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2335
|
+
webex.meetings.breakoutLocusForHandleLater = [];
|
|
2336
|
+
webex.meetings.checkHandleBreakoutLocus({});
|
|
2337
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2338
|
+
});
|
|
2339
|
+
|
|
2340
|
+
it('do nothing if new created locus is breakout locus', () => {
|
|
2341
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2342
|
+
webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
|
|
2343
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2344
|
+
});
|
|
2345
|
+
|
|
2346
|
+
it('do nothing if no cached locus is associated with the new created locus', () => {
|
|
2347
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2348
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2349
|
+
controls: {
|
|
2350
|
+
breakout: {
|
|
2351
|
+
sessionType: 'MAIN',
|
|
2352
|
+
url: 'breakoutUnifiedUrl2',
|
|
2353
|
+
},
|
|
2354
|
+
},
|
|
2355
|
+
});
|
|
2356
|
+
assert.notCalled(webex.meetings.handleLocusEvent);
|
|
2357
|
+
});
|
|
2358
|
+
|
|
2359
|
+
it('update the cached breakout locus which associate the new created locus', () => {
|
|
2360
|
+
webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
|
|
2361
|
+
webex.meetings.checkHandleBreakoutLocus({
|
|
2362
|
+
controls: {
|
|
2363
|
+
breakout: {
|
|
2364
|
+
sessionType: 'MAIN',
|
|
2365
|
+
url: 'breakoutUnifiedUrl1',
|
|
2366
|
+
},
|
|
2367
|
+
},
|
|
2368
|
+
});
|
|
2369
|
+
assert.calledWith(webex.meetings.handleLocusEvent, {
|
|
2370
|
+
locus: breakoutLocus,
|
|
2371
|
+
locusUrl: breakoutLocus.url,
|
|
2372
|
+
});
|
|
2373
|
+
});
|
|
2374
|
+
});
|
|
2375
|
+
|
|
2376
|
+
describe('uploading of logs', () => {
|
|
2377
|
+
let metricsSpy;
|
|
2378
|
+
let meeting;
|
|
2379
|
+
|
|
2380
|
+
beforeEach(async () => {
|
|
2381
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2382
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2383
|
+
|
|
2384
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2385
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2386
|
+
|
|
2387
|
+
triggerProxyStub.restore();
|
|
2388
|
+
|
|
2389
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2390
|
+
|
|
2391
|
+
meeting = await webex.meetings.create('test');
|
|
2392
|
+
|
|
2393
|
+
meeting.locusId = 'locus id';
|
|
2394
|
+
meeting.correlationId = 'correlation id';
|
|
2395
|
+
meeting.locusInfo = {
|
|
2396
|
+
fullState: {lastActive: 'last active', sessionId: 'locus session id'},
|
|
2397
|
+
info: {webExMeetingId: 'meeting id'},
|
|
2398
|
+
};
|
|
2399
|
+
});
|
|
2400
|
+
|
|
2401
|
+
afterEach(() => {
|
|
2402
|
+
sinon.restore();
|
|
2403
|
+
});
|
|
2404
|
+
|
|
2405
|
+
it('sends metrics on success', async () => {
|
|
2406
|
+
await meeting.uploadLogs();
|
|
2407
|
+
|
|
2408
|
+
await testUtils.flushPromises();
|
|
2409
|
+
|
|
2410
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2411
|
+
callStart: 'last active',
|
|
2412
|
+
correlationId: 'correlation id',
|
|
2413
|
+
feedbackId: 'correlation id',
|
|
2414
|
+
locusId: 'locus id',
|
|
2415
|
+
meetingId: 'meeting id',
|
|
2416
|
+
autoupload: true,
|
|
2417
|
+
locussessionid: 'locus session id',
|
|
2418
|
+
});
|
|
2419
|
+
});
|
|
2420
|
+
|
|
2421
|
+
it('sends metrics on failure', async () => {
|
|
2422
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2423
|
+
|
|
2424
|
+
await meeting.uploadLogs();
|
|
2425
|
+
|
|
2426
|
+
await testUtils.flushPromises();
|
|
2427
|
+
|
|
2428
|
+
assert.calledOnceWithExactly(
|
|
2429
|
+
metricsSpy,
|
|
2430
|
+
'js_sdk_upload_logs_failure',
|
|
2431
|
+
sinon.match({
|
|
2432
|
+
callStart: 'last active',
|
|
2433
|
+
correlationId: 'correlation id',
|
|
2434
|
+
feedbackId: 'correlation id',
|
|
2435
|
+
locusId: 'locus id',
|
|
2436
|
+
meetingId: 'meeting id',
|
|
2437
|
+
reason: 'fake error',
|
|
2438
|
+
autoupload: true,
|
|
2439
|
+
locussessionid: 'locus session id',
|
|
2440
|
+
})
|
|
2441
|
+
);
|
|
2442
|
+
});
|
|
2443
|
+
});
|
|
1374
2444
|
});
|
|
1375
2445
|
});
|