@webex/plugin-meetings 3.0.0-test.1 → 3.1.0
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/.eslintrc.js +6 -0
- package/babel.config.js +3 -0
- package/dist/annotation/constants.js +12 -20
- package/dist/annotation/constants.js.map +1 -1
- package/dist/annotation/index.js +25 -10
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +2 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/collection.js +1 -2
- package/dist/breakouts/collection.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +1 -2
- package/dist/breakouts/edit-lock-error.js.map +1 -1
- package/dist/breakouts/events.js +1 -2
- package/dist/breakouts/events.js.map +1 -1
- package/dist/breakouts/index.js +13 -14
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +1 -2
- package/dist/breakouts/request.js.map +1 -1
- package/dist/breakouts/utils.js +3 -6
- package/dist/breakouts/utils.js.map +1 -1
- 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.js +1 -2
- package/dist/common/errors/no-meeting-info.js.map +1 -1
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.js +6 -10
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -1
- 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.js +14 -15
- 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 +1 -2
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/{types/common → common}/logs/request.d.ts +1 -1
- package/dist/common/logs/request.js +3 -4
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +2 -4
- package/dist/common/queue.js.map +1 -1
- package/dist/{types/config.d.ts → config.d.ts} +1 -0
- package/dist/config.js +4 -3
- package/dist/config.js.map +1 -1
- package/dist/{types/constants.d.ts → constants.d.ts} +10 -5
- package/dist/constants.js +207 -380
- 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.js +7 -10
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +27 -32
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/util.js +1 -2
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRetry.js +4 -3
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interpretation/collection.js +1 -2
- package/dist/interpretation/collection.js.map +1 -1
- package/dist/interpretation/index.js +4 -5
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +2 -3
- package/dist/interpretation/siLanguage.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +12 -13
- 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.js +23 -27
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +3 -4
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +16 -3
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +6 -10
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +12 -6
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/media/MediaConnectionAwaiter.js +163 -0
- package/dist/media/MediaConnectionAwaiter.js.map +1 -0
- package/dist/media/index.js +9 -5
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +7 -28
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -2
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +9 -18
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +14 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/{types/meeting → meeting}/index.d.ts +71 -16
- package/dist/meeting/index.js +1411 -1036
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +4 -5
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +2 -4
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/{types/meeting → meeting}/request.d.ts +3 -0
- package/dist/meeting/request.js +45 -36
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/{types/meeting → meeting}/util.d.ts +1 -0
- package/dist/meeting/util.js +13 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.d.ts +16 -0
- package/dist/meeting/voicea-meeting.js +169 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +5 -4
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +27 -29
- 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 +8 -8
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +15 -9
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +5 -6
- package/dist/meetings/collection.js.map +1 -1
- package/dist/{types/meetings → meetings}/index.d.ts +11 -2
- package/dist/meetings/index.js +44 -17
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +2 -3
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +1 -4
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +1 -3
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +6 -8
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +1 -2
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +1 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +8 -7
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +2 -3
- 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/{types/members → members}/util.d.ts +1 -1
- package/dist/members/util.js +3 -4
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -2
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +3 -2
- package/dist/metrics/index.js.map +1 -1
- package/dist/{types/multistream → multistream}/mediaRequestManager.d.ts +1 -2
- package/dist/multistream/mediaRequestManager.js +9 -11
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +3 -5
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +7 -9
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +3 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/{types/multistream → multistream}/remoteMediaGroup.d.ts +1 -1
- package/dist/multistream/remoteMediaGroup.js +7 -6
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/{types/multistream → multistream}/remoteMediaManager.d.ts +1 -2
- package/dist/multistream/remoteMediaManager.js +32 -29
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/{types/multistream → multistream}/sendSlotManager.d.ts +1 -2
- package/dist/multistream/sendSlotManager.js +9 -6
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +1 -2
- 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/{types/reachability → reachability}/clusterReachability.d.ts +1 -0
- package/dist/reachability/clusterReachability.js +35 -20
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/{types/reachability → reachability}/index.d.ts +4 -0
- package/dist/reachability/index.js +41 -12
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +25 -20
- package/dist/reachability/request.js.map +1 -1
- package/dist/{types/reachability → reachability}/util.d.ts +7 -0
- package/dist/reachability/util.js +19 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/reactions/constants.js +1 -2
- package/dist/reactions/constants.js.map +1 -1
- package/dist/reactions/reactions.js +2 -4
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js +6 -8
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +18 -11
- 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.js +43 -51
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +1 -2
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/{types/roap → roap}/index.d.ts +10 -2
- package/dist/roap/index.js +17 -3
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +10 -10
- package/dist/roap/request.js.map +1 -1
- package/dist/{types/roap → roap}/turnDiscovery.d.ts +64 -17
- package/dist/roap/turnDiscovery.js +316 -134
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +1 -2
- package/dist/rtcMetrics/constants.js.map +1 -1
- package/dist/rtcMetrics/index.js +4 -6
- package/dist/rtcMetrics/index.js.map +1 -1
- package/dist/statsAnalyzer/global.js +1 -2
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +123 -96
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +24 -31
- 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.js +1 -2
- package/dist/webinar/collection.js.map +1 -1
- package/dist/webinar/index.js +2 -3
- package/dist/webinar/index.js.map +1 -1
- package/jest.config.js +3 -0
- package/package.json +44 -25
- package/process +1 -0
- package/src/config.ts +3 -4
- package/src/constants.ts +13 -4
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/selfUtils.ts +5 -0
- package/src/media/MediaConnectionAwaiter.ts +174 -0
- package/src/media/index.ts +3 -1
- package/src/media/properties.ts +6 -31
- package/src/meeting/index.ts +526 -227
- package/src/meeting/request.ts +18 -2
- package/src/meeting/util.ts +6 -1
- package/src/meeting/voicea-meeting.ts +122 -0
- package/src/meeting-info/meeting-info-v2.ts +5 -11
- package/src/meeting-info/util.ts +12 -9
- package/src/meeting-info/utilv2.ts +26 -15
- package/src/meetings/index.ts +18 -0
- package/src/member/index.ts +0 -1
- package/src/multistream/mediaRequestManager.ts +1 -1
- package/src/multistream/remoteMediaGroup.ts +1 -1
- package/src/multistream/remoteMediaManager.ts +1 -2
- package/src/multistream/sendSlotManager.ts +1 -2
- package/src/reachability/clusterReachability.ts +20 -5
- package/src/reachability/index.ts +24 -1
- package/src/reachability/request.ts +15 -11
- package/src/reachability/util.ts +21 -0
- package/src/reconnection-manager/index.ts +1 -1
- package/src/roap/index.ts +25 -3
- package/src/roap/request.ts +2 -2
- package/src/roap/turnDiscovery.ts +244 -78
- package/src/statsAnalyzer/index.ts +63 -27
- package/test/integration/spec/journey.js +2 -2
- package/test/unit/spec/breakouts/breakout.ts +2 -1
- package/test/unit/spec/breakouts/index.ts +7 -4
- package/test/unit/spec/interpretation/index.ts +4 -1
- package/test/unit/spec/locus-info/index.js +27 -18
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +9 -0
- package/test/unit/spec/locus-info/selfUtils.js +41 -11
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +344 -0
- package/test/unit/spec/media/index.ts +94 -78
- package/test/unit/spec/media/properties.ts +16 -70
- package/test/unit/spec/meeting/index.js +757 -141
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +58 -11
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +20 -15
- package/test/unit/spec/meeting-info/utilv2.js +6 -0
- package/test/unit/spec/meetings/index.js +101 -13
- package/test/unit/spec/metrics/index.js +1 -2
- package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +0 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +0 -1
- package/test/unit/spec/reachability/clusterReachability.ts +86 -22
- package/test/unit/spec/reachability/index.ts +197 -60
- package/test/unit/spec/reachability/request.js +15 -7
- package/test/unit/spec/reachability/util.ts +32 -2
- package/test/unit/spec/reconnection-manager/index.js +28 -0
- package/test/unit/spec/recording-controller/index.js +0 -1
- package/test/unit/spec/roap/index.ts +61 -6
- package/test/unit/spec/roap/turnDiscovery.ts +299 -17
- package/test/unit/spec/stats-analyzer/index.js +179 -0
- /package/dist/{types/annotation → annotation}/annotation.types.d.ts +0 -0
- /package/dist/{types/annotation → annotation}/constants.d.ts +0 -0
- /package/dist/{types/annotation → annotation}/index.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/breakout.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/collection.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/edit-lock-error.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/events.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/index.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/request.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/utils.d.ts +0 -0
- /package/dist/{types/common → common}/browser-detection.d.ts +0 -0
- /package/dist/{types/common → common}/collection.d.ts +0 -0
- /package/dist/{types/common → common}/config.d.ts +0 -0
- /package/dist/{types/common → common}/errors/captcha-error.d.ts +0 -0
- /package/dist/{types/common → common}/errors/intent-to-join.d.ts +0 -0
- /package/dist/{types/common → common}/errors/join-meeting.d.ts +0 -0
- /package/dist/{types/common → common}/errors/media.d.ts +0 -0
- /package/dist/{types/common → common}/errors/no-meeting-info.d.ts +0 -0
- /package/dist/{types/common → common}/errors/parameter.d.ts +0 -0
- /package/dist/{types/common → common}/errors/password-error.d.ts +0 -0
- /package/dist/{types/common → common}/errors/permission.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reclaim-host-role-errors.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reconnection-in-progress.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reconnection.d.ts +0 -0
- /package/dist/{types/common → common}/errors/stats.d.ts +0 -0
- /package/dist/{types/common → common}/errors/webex-errors.d.ts +0 -0
- /package/dist/{types/common → common}/errors/webex-meetings-error.d.ts +0 -0
- /package/dist/{types/common → common}/events/events-scope.d.ts +0 -0
- /package/dist/{types/common → common}/events/events.d.ts +0 -0
- /package/dist/{types/common → common}/events/trigger-proxy.d.ts +0 -0
- /package/dist/{types/common → common}/events/util.d.ts +0 -0
- /package/dist/{types/common → common}/logs/logger-config.d.ts +0 -0
- /package/dist/{types/common → common}/logs/logger-proxy.d.ts +0 -0
- /package/dist/{types/common → common}/queue.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/constants.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/enums.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/index.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/types.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/util.d.ts +0 -0
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/interceptors → interceptors}/index.d.ts +0 -0
- /package/dist/{types/interceptors → interceptors}/locusRetry.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/collection.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/index.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/siLanguage.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/controlsUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/embeddedAppsUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/fullState.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/hostUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/index.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/infoUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/mediaSharesUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/parser.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/selfUtils.d.ts +0 -0
- /package/dist/{types/media → media}/index.d.ts +0 -0
- /package/dist/{types/media → media}/properties.d.ts +0 -0
- /package/dist/{types/media → media}/util.d.ts +0 -0
- /package/dist/{types/mediaQualityMetrics → mediaQualityMetrics}/config.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/in-meeting-actions.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/locusMediaRequest.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/muteState.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/request.type.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/state.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/collection.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/index.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/meeting-info-v2.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/request.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/util.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/utilv2.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/collection.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/meetings.types.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/request.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/util.d.ts +0 -0
- /package/dist/{types/member → member}/index.d.ts +0 -0
- /package/dist/{types/member → member}/types.d.ts +0 -0
- /package/dist/{types/member → member}/util.d.ts +0 -0
- /package/dist/{types/members → members}/collection.d.ts +0 -0
- /package/dist/{types/members → members}/index.d.ts +0 -0
- /package/dist/{types/members → members}/request.d.ts +0 -0
- /package/dist/{types/members → members}/types.d.ts +0 -0
- /package/dist/{types/metrics → metrics}/constants.d.ts +0 -0
- /package/dist/{types/metrics → metrics}/index.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/receiveSlot.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/receiveSlotManager.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/remoteMedia.d.ts +0 -0
- /package/dist/{types/networkQualityMonitor → networkQualityMonitor}/index.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/index.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/request.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/util.d.ts +0 -0
- /package/dist/{types/reachability → reachability}/request.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/constants.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/reactions.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/reactions.type.d.ts +0 -0
- /package/dist/{types/reconnection-manager → reconnection-manager}/index.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/enums.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/index.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/util.d.ts +0 -0
- /package/dist/{types/roap → roap}/request.d.ts +0 -0
- /package/dist/{types/rtcMetrics → rtcMetrics}/constants.d.ts +0 -0
- /package/dist/{types/rtcMetrics → rtcMetrics}/index.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/global.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/index.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/mqaUtil.d.ts +0 -0
- /package/dist/{types/transcription → transcription}/index.d.ts +0 -0
- /package/dist/{types/webinar → webinar}/collection.d.ts +0 -0
- /package/dist/{types/webinar → webinar}/index.d.ts +0 -0
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
4
|
import 'jsdom-global/register';
|
|
5
|
-
import jwt from 'jsonwebtoken';
|
|
6
5
|
import {cloneDeep, forEach, isEqual, isUndefined} from 'lodash';
|
|
7
6
|
import sinon from 'sinon';
|
|
8
7
|
import * as internalMediaModule from '@webex/internal-media-core';
|
|
@@ -100,7 +99,6 @@ import {
|
|
|
100
99
|
MeetingInfoV2PolicyError,
|
|
101
100
|
} from '../../../../src/meeting-info/meeting-info-v2';
|
|
102
101
|
import {
|
|
103
|
-
CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,
|
|
104
102
|
DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
|
|
105
103
|
ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE,
|
|
106
104
|
ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,
|
|
@@ -111,6 +109,8 @@ import CallDiagnosticMetrics from '@webex/internal-plugin-metrics/src/call-diagn
|
|
|
111
109
|
import {ERROR_DESCRIPTIONS} from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
|
|
112
110
|
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
113
111
|
|
|
112
|
+
import {EVENT_TRIGGERS as VOICEAEVENTS} from '@webex/internal-plugin-voicea';
|
|
113
|
+
|
|
114
114
|
describe('plugin-meetings', () => {
|
|
115
115
|
const logger = {
|
|
116
116
|
info: () => {},
|
|
@@ -610,36 +610,177 @@ describe('plugin-meetings', () => {
|
|
|
610
610
|
assert.exists(meeting.joinWithMedia);
|
|
611
611
|
});
|
|
612
612
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
613
|
+
const fakeRoapMessage = {id: 'fake TURN discovery message'};
|
|
614
|
+
const fakeReachabilityResults = {id: 'fake reachability'};
|
|
615
|
+
const fakeTurnServerInfo = {id: 'fake turn info'};
|
|
616
|
+
const fakeJoinResult = {id: 'join result'};
|
|
617
617
|
|
|
618
|
-
|
|
619
|
-
|
|
618
|
+
const joinOptions = {correlationId: '12345'};
|
|
619
|
+
const mediaOptions = {audioEnabled: true, allowMediaInLobby: true};
|
|
620
620
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
621
|
+
let generateTurnDiscoveryRequestMessageStub;
|
|
622
|
+
let handleTurnDiscoveryHttpResponseStub;
|
|
623
|
+
let abortTurnDiscoveryStub;
|
|
624
|
+
|
|
625
|
+
beforeEach(() => {
|
|
626
|
+
meeting.join = sinon.stub().returns(Promise.resolve(fakeJoinResult));
|
|
627
|
+
meeting.addMedia = sinon.stub().returns(Promise.resolve(test4));
|
|
628
|
+
|
|
629
|
+
webex.meetings.reachability.getReachabilityResults.resolves(fakeReachabilityResults);
|
|
630
|
+
|
|
631
|
+
generateTurnDiscoveryRequestMessageStub = sinon
|
|
632
|
+
.stub(meeting.roap, 'generateTurnDiscoveryRequestMessage')
|
|
633
|
+
.resolves({roapMessage: fakeRoapMessage});
|
|
634
|
+
handleTurnDiscoveryHttpResponseStub = sinon
|
|
635
|
+
.stub(meeting.roap, 'handleTurnDiscoveryHttpResponse')
|
|
636
|
+
.resolves({turnServerInfo: fakeTurnServerInfo, turnDiscoverySkippedReason: undefined});
|
|
637
|
+
abortTurnDiscoveryStub = sinon.stub(meeting.roap, 'abortTurnDiscovery');
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('should work as expected', async () => {
|
|
641
|
+
const result = await meeting.joinWithMedia({
|
|
642
|
+
joinOptions,
|
|
643
|
+
mediaOptions,
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
// check that TURN discovery is done with join and addMedia called
|
|
647
|
+
assert.calledOnceWithExactly(meeting.join, {
|
|
648
|
+
...joinOptions,
|
|
649
|
+
roapMessage: fakeRoapMessage,
|
|
650
|
+
reachability: fakeReachabilityResults,
|
|
651
|
+
});
|
|
652
|
+
assert.calledOnceWithExactly(generateTurnDiscoveryRequestMessageStub, meeting, true);
|
|
653
|
+
assert.calledOnceWithExactly(
|
|
654
|
+
handleTurnDiscoveryHttpResponseStub,
|
|
655
|
+
meeting,
|
|
656
|
+
fakeJoinResult
|
|
657
|
+
);
|
|
658
|
+
assert.calledOnceWithExactly(meeting.addMedia, mediaOptions, fakeTurnServerInfo);
|
|
659
|
+
|
|
660
|
+
assert.deepEqual(result, {join: fakeJoinResult, media: test4});
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it("should not call handleTurnDiscoveryHttpResponse if we don't send a TURN discovery request with join", async () => {
|
|
664
|
+
generateTurnDiscoveryRequestMessageStub.resolves({roapMessage: undefined});
|
|
665
|
+
|
|
666
|
+
const result = await meeting.joinWithMedia({
|
|
667
|
+
joinOptions,
|
|
668
|
+
mediaOptions,
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// check that TURN discovery is done with join and addMedia called
|
|
672
|
+
assert.calledOnceWithExactly(meeting.join, {
|
|
673
|
+
...joinOptions,
|
|
674
|
+
roapMessage: undefined,
|
|
675
|
+
reachability: fakeReachabilityResults,
|
|
628
676
|
});
|
|
677
|
+
assert.calledOnceWithExactly(generateTurnDiscoveryRequestMessageStub, meeting, true);
|
|
678
|
+
assert.notCalled(handleTurnDiscoveryHttpResponseStub);
|
|
679
|
+
assert.notCalled(abortTurnDiscoveryStub);
|
|
680
|
+
assert.calledOnceWithExactly(meeting.addMedia, mediaOptions, undefined);
|
|
681
|
+
|
|
682
|
+
assert.deepEqual(result, {join: fakeJoinResult, media: test4});
|
|
683
|
+
assert.equal(meeting.turnServerUsed, false);
|
|
629
684
|
});
|
|
630
685
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
686
|
+
it('should call abortTurnDiscovery() if we do not get a TURN server info', async () => {
|
|
687
|
+
handleTurnDiscoveryHttpResponseStub.resolves({
|
|
688
|
+
turnServerInfo: undefined,
|
|
689
|
+
turnDiscoverySkippedReason: 'missing http response',
|
|
635
690
|
});
|
|
636
691
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
692
|
+
const result = await meeting.joinWithMedia({
|
|
693
|
+
joinOptions,
|
|
694
|
+
mediaOptions,
|
|
695
|
+
});
|
|
640
696
|
|
|
641
|
-
|
|
697
|
+
// check that TURN discovery is done with join and addMedia called
|
|
698
|
+
assert.calledOnceWithExactly(meeting.join, {
|
|
699
|
+
...joinOptions,
|
|
700
|
+
roapMessage: fakeRoapMessage,
|
|
701
|
+
reachability: fakeReachabilityResults,
|
|
642
702
|
});
|
|
703
|
+
assert.calledOnceWithExactly(generateTurnDiscoveryRequestMessageStub, meeting, true);
|
|
704
|
+
assert.calledOnceWithExactly(
|
|
705
|
+
handleTurnDiscoveryHttpResponseStub,
|
|
706
|
+
meeting,
|
|
707
|
+
fakeJoinResult
|
|
708
|
+
);
|
|
709
|
+
assert.calledOnceWithExactly(abortTurnDiscoveryStub);
|
|
710
|
+
assert.calledOnceWithExactly(meeting.addMedia, mediaOptions, undefined);
|
|
711
|
+
|
|
712
|
+
assert.deepEqual(result, {join: fakeJoinResult, media: test4});
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
it('should reject if join() fails', async () => {
|
|
716
|
+
const error = new Error('fake');
|
|
717
|
+
meeting.join = sinon.stub().returns(Promise.reject(error));
|
|
718
|
+
meeting.locusUrl = null; // when join fails, we end up with null locusUrl
|
|
719
|
+
|
|
720
|
+
await assert.isRejected(meeting.joinWithMedia({mediaOptions: {allowMediaInLobby: true}}));
|
|
721
|
+
|
|
722
|
+
assert.calledOnceWithExactly(abortTurnDiscoveryStub);
|
|
723
|
+
|
|
724
|
+
assert.calledWith(
|
|
725
|
+
Metrics.sendBehavioralMetric,
|
|
726
|
+
BEHAVIORAL_METRICS.JOIN_WITH_MEDIA_FAILURE,
|
|
727
|
+
{
|
|
728
|
+
correlation_id: meeting.correlationId,
|
|
729
|
+
locus_id: undefined,
|
|
730
|
+
reason: error.message,
|
|
731
|
+
stack: error.stack,
|
|
732
|
+
leaveErrorReason: undefined,
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
type: error.name,
|
|
736
|
+
}
|
|
737
|
+
);
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it('should fail if called with allowMediaInLobby:false', async () => {
|
|
741
|
+
meeting.join = sinon.stub().returns(Promise.resolve(test1));
|
|
742
|
+
meeting.addMedia = sinon.stub().returns(Promise.resolve(test4));
|
|
743
|
+
|
|
744
|
+
await assert.isRejected(
|
|
745
|
+
meeting.joinWithMedia({mediaOptions: {allowMediaInLobby: false}})
|
|
746
|
+
);
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
it('should call leave() if addMedia fails and ignore leave() failure', async () => {
|
|
750
|
+
const leaveError = new Error('leave error');
|
|
751
|
+
const addMediaError = new Error('fake addMedia error');
|
|
752
|
+
|
|
753
|
+
const leaveStub = sinon.stub(meeting, 'leave').rejects(leaveError);
|
|
754
|
+
meeting.addMedia = sinon.stub().rejects(addMediaError);
|
|
755
|
+
|
|
756
|
+
await assert.isRejected(
|
|
757
|
+
meeting.joinWithMedia({
|
|
758
|
+
joinOptions: {resourceId: 'some resource'},
|
|
759
|
+
mediaOptions: {allowMediaInLobby: true},
|
|
760
|
+
}),
|
|
761
|
+
addMediaError
|
|
762
|
+
);
|
|
763
|
+
|
|
764
|
+
assert.calledOnce(leaveStub);
|
|
765
|
+
assert.calledOnceWithExactly(leaveStub, {
|
|
766
|
+
resourceId: 'some resource',
|
|
767
|
+
reason: 'joinWithMedia failure',
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
assert.calledWith(
|
|
771
|
+
Metrics.sendBehavioralMetric,
|
|
772
|
+
BEHAVIORAL_METRICS.JOIN_WITH_MEDIA_FAILURE,
|
|
773
|
+
{
|
|
774
|
+
correlation_id: meeting.correlationId,
|
|
775
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
|
776
|
+
reason: addMediaError.message,
|
|
777
|
+
stack: addMediaError.stack,
|
|
778
|
+
leaveErrorReason: leaveError.message,
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
type: addMediaError.name,
|
|
782
|
+
}
|
|
783
|
+
);
|
|
643
784
|
});
|
|
644
785
|
});
|
|
645
786
|
|
|
@@ -655,38 +796,250 @@ describe('plugin-meetings', () => {
|
|
|
655
796
|
assert.equal(meeting.isTranscriptionSupported(), true);
|
|
656
797
|
});
|
|
657
798
|
});
|
|
658
|
-
describe('#receiveTranscription', () => {
|
|
659
|
-
it('should invoke subscribe method to invoke the callback', () => {
|
|
660
|
-
meeting.monitorTranscriptionSocketConnection = sinon.stub();
|
|
661
|
-
meeting.initializeTranscription = sinon.stub();
|
|
662
799
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
800
|
+
describe('#startTranscription', () => {
|
|
801
|
+
beforeEach(() => {
|
|
802
|
+
webex.internal.voicea.on = sinon.stub();
|
|
803
|
+
webex.internal.voicea.off = sinon.stub();
|
|
804
|
+
webex.internal.voicea.listenToEvents = sinon.stub();
|
|
805
|
+
webex.internal.voicea.toggleTranscribing = sinon.stub();
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
it('should subscribe to events for the first time and avoid subscribing for future transcription starts', async () => {
|
|
809
|
+
meeting.joinedWith = {
|
|
810
|
+
state: 'JOINED',
|
|
811
|
+
};
|
|
812
|
+
meeting.areVoiceaEventsSetup = false;
|
|
813
|
+
meeting.roles = ['MODERATOR'];
|
|
814
|
+
|
|
815
|
+
await meeting.startTranscription();
|
|
816
|
+
|
|
817
|
+
assert.equal(webex.internal.voicea.on.callCount, 4);
|
|
818
|
+
assert.equal(meeting.areVoiceaEventsSetup, true);
|
|
819
|
+
assert.equal(webex.internal.voicea.listenToEvents.callCount, 1);
|
|
820
|
+
assert.calledWith(webex.internal.voicea.toggleTranscribing, true);
|
|
821
|
+
|
|
822
|
+
await meeting.startTranscription();
|
|
823
|
+
assert.equal(webex.internal.voicea.on.callCount, 4);
|
|
824
|
+
assert.equal(meeting.areVoiceaEventsSetup, true);
|
|
825
|
+
assert.equal(webex.internal.voicea.listenToEvents.callCount, 1);
|
|
826
|
+
assert.calledTwice(webex.internal.voicea.toggleTranscribing);
|
|
827
|
+
assert.calledWith(webex.internal.voicea.toggleTranscribing, true);
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it('should listen to events and not toggleTranscribing if the user is not a host', async () => {
|
|
831
|
+
meeting.joinedWith = {
|
|
832
|
+
state: 'JOINED',
|
|
833
|
+
};
|
|
834
|
+
meeting.areVoiceaEventsSetup = false;
|
|
835
|
+
meeting.roles = ['COHOST'];
|
|
836
|
+
|
|
837
|
+
await meeting.startTranscription();
|
|
838
|
+
|
|
839
|
+
assert.equal(webex.internal.voicea.on.callCount, 4);
|
|
840
|
+
assert.equal(meeting.areVoiceaEventsSetup, true);
|
|
841
|
+
assert.equal(webex.internal.voicea.listenToEvents.callCount, 1);
|
|
842
|
+
assert.notCalled(webex.internal.voicea.toggleTranscribing);
|
|
668
843
|
});
|
|
669
844
|
|
|
670
845
|
it("should throw error if request doesn't work", async () => {
|
|
671
846
|
meeting.request = sinon.stub().returns(Promise.reject());
|
|
672
847
|
|
|
673
848
|
try {
|
|
674
|
-
await meeting.
|
|
849
|
+
await meeting.startTranscription();
|
|
675
850
|
} catch (err) {
|
|
676
851
|
assert(err, {});
|
|
677
852
|
}
|
|
678
853
|
});
|
|
679
854
|
});
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
855
|
+
|
|
856
|
+
describe('#stopTranscription', () => {
|
|
857
|
+
beforeEach(() => {
|
|
858
|
+
webex.internal.voicea.on = sinon.stub();
|
|
859
|
+
webex.internal.voicea.off = sinon.stub();
|
|
860
|
+
webex.internal.voicea.listenToEvents = sinon.stub();
|
|
861
|
+
webex.internal.voicea.toggleTranscribing = sinon.stub();
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
it('should stop listening to voicea events and also trigger a stop event', () => {
|
|
865
|
+
meeting.stopTranscription();
|
|
866
|
+
assert.equal(webex.internal.voicea.off.callCount, 4);
|
|
867
|
+
assert.equal(meeting.areVoiceaEventsSetup, false);
|
|
868
|
+
assert.calledWith(
|
|
869
|
+
TriggerProxy.trigger,
|
|
870
|
+
sinon.match.instanceOf(Meeting),
|
|
871
|
+
{
|
|
872
|
+
file: 'meeting/index',
|
|
873
|
+
function: 'triggerStopReceivingTranscriptionEvent',
|
|
874
|
+
},
|
|
875
|
+
EVENT_TRIGGERS.MEETING_STOPPED_RECEIVING_TRANSCRIPTION
|
|
876
|
+
);
|
|
877
|
+
});
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
describe('#setCaptionLanguage', () => {
|
|
881
|
+
beforeEach(() => {
|
|
882
|
+
meeting.isTranscriptionSupported = sinon.stub();
|
|
883
|
+
meeting.transcription = {languageOptions: {}};
|
|
884
|
+
webex.internal.voicea.on = sinon.stub();
|
|
885
|
+
webex.internal.voicea.off = sinon.stub();
|
|
886
|
+
webex.internal.voicea.setCaptionLanguage = sinon.stub();
|
|
887
|
+
webex.internal.voicea.requestLanguage = sinon.stub();
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
afterEach(() => {
|
|
891
|
+
// Restore the original methods after each test
|
|
892
|
+
sinon.restore();
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
it('should reject if transcription is not supported', (done) => {
|
|
896
|
+
meeting.isTranscriptionSupported.returns(false);
|
|
897
|
+
|
|
898
|
+
meeting.setCaptionLanguage('fr').catch((error) => {
|
|
899
|
+
assert.equal(error.message, 'Webex Assistant is not enabled/supported');
|
|
900
|
+
done();
|
|
901
|
+
});
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
it('should resolve with the language code on successful language update', (done) => {
|
|
905
|
+
meeting.isTranscriptionSupported.returns(true);
|
|
906
|
+
const languageCode = 'fr';
|
|
907
|
+
|
|
908
|
+
meeting.setCaptionLanguage(languageCode).then((resolvedLanguageCode) => {
|
|
909
|
+
assert.calledWith(webex.internal.voicea.requestLanguage, languageCode);
|
|
910
|
+
assert.equal(resolvedLanguageCode, languageCode);
|
|
911
|
+
assert.equal(
|
|
912
|
+
meeting.transcription.languageOptions.currentCaptionLanguage,
|
|
913
|
+
languageCode
|
|
914
|
+
);
|
|
915
|
+
done();
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
assert.calledOnceWithMatch(
|
|
919
|
+
webex.internal.voicea.on,
|
|
920
|
+
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
// Trigger the event
|
|
924
|
+
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
925
|
+
voiceaListenerLangugeUpdate({statusCode: 200, languageCode});
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
it('should reject if the statusCode in payload is not 200', (done) => {
|
|
929
|
+
meeting.isTranscriptionSupported.returns(true);
|
|
930
|
+
const languageCode = 'fr';
|
|
931
|
+
const rejectPayload = {
|
|
932
|
+
statusCode: 400,
|
|
933
|
+
message: 'some error message',
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
meeting.setCaptionLanguage(languageCode).catch((payload) => {
|
|
937
|
+
assert.equal(payload, rejectPayload);
|
|
938
|
+
done();
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
assert.calledOnceWithMatch(
|
|
942
|
+
webex.internal.voicea.on,
|
|
943
|
+
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
// Trigger the event
|
|
947
|
+
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
948
|
+
voiceaListenerLangugeUpdate(rejectPayload);
|
|
949
|
+
});
|
|
950
|
+
});
|
|
951
|
+
|
|
952
|
+
describe('#setSpokenLanguage', () => {
|
|
953
|
+
beforeEach(() => {
|
|
954
|
+
meeting.isTranscriptionSupported = sinon.stub();
|
|
955
|
+
meeting.transcription = {languageOptions: {}};
|
|
956
|
+
webex.internal.voicea.on = sinon.stub();
|
|
957
|
+
webex.internal.voicea.off = sinon.stub();
|
|
958
|
+
webex.internal.voicea.setSpokenLanguage = sinon.stub();
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
afterEach(() => {
|
|
962
|
+
// Restore the original methods after each test
|
|
963
|
+
sinon.restore();
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
it('should reject if transcription is not supported', (done) => {
|
|
967
|
+
meeting.isTranscriptionSupported.returns(false);
|
|
968
|
+
|
|
969
|
+
meeting.setSpokenLanguage('fr').catch((error) => {
|
|
970
|
+
assert.equal(error.message, 'Webex Assistant is not enabled/supported');
|
|
971
|
+
done();
|
|
972
|
+
});
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
it('should resolve with the language code on successful language update', (done) => {
|
|
976
|
+
meeting.isTranscriptionSupported.returns(true);
|
|
977
|
+
const languageCode = 'fr';
|
|
978
|
+
|
|
979
|
+
meeting.setSpokenLanguage(languageCode).then((resolvedLanguageCode) => {
|
|
980
|
+
assert.calledWith(webex.internal.voicea.setSpokenLanguage, languageCode);
|
|
981
|
+
assert.equal(resolvedLanguageCode, languageCode);
|
|
982
|
+
assert.equal(meeting.transcription.languageOptions.currentSpokenLanguage, languageCode);
|
|
983
|
+
done();
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
assert.calledOnceWithMatch(webex.internal.voicea.on, VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE);
|
|
987
|
+
|
|
988
|
+
// Trigger the event
|
|
989
|
+
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
990
|
+
voiceaListenerLangugeUpdate({languageCode});
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
it('should reject if the language code does not exist in payload', (done) => {
|
|
994
|
+
meeting.isTranscriptionSupported.returns(true);
|
|
995
|
+
const languageCode = 'fr';
|
|
996
|
+
const rejectPayload = {
|
|
997
|
+
message: 'some error message',
|
|
684
998
|
};
|
|
685
999
|
|
|
686
|
-
meeting.
|
|
687
|
-
|
|
1000
|
+
meeting.setSpokenLanguage(languageCode).catch((payload) => {
|
|
1001
|
+
assert.equal(payload, rejectPayload);
|
|
1002
|
+
done();
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
assert.calledOnceWithMatch(webex.internal.voicea.on, VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE);
|
|
1006
|
+
|
|
1007
|
+
// Trigger the event
|
|
1008
|
+
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
1009
|
+
voiceaListenerLangugeUpdate(rejectPayload);
|
|
688
1010
|
});
|
|
689
1011
|
});
|
|
1012
|
+
|
|
1013
|
+
describe('transcription events', () => {
|
|
1014
|
+
beforeEach(() => {
|
|
1015
|
+
meeting.trigger = sinon.stub();
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
it('should trigger meeting:caption-received event', () => {
|
|
1019
|
+
meeting.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]({});
|
|
1020
|
+
assert.calledWith(
|
|
1021
|
+
meeting.trigger,
|
|
1022
|
+
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED
|
|
1023
|
+
);
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
it('should trigger meeting:receiveTranscription:started event', () => {
|
|
1027
|
+
meeting.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]({});
|
|
1028
|
+
assert.calledWith(
|
|
1029
|
+
meeting.trigger,
|
|
1030
|
+
EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION
|
|
1031
|
+
);
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
it('should trigger meeting:caption-received event', () => {
|
|
1035
|
+
meeting.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]({});
|
|
1036
|
+
assert.calledWith(
|
|
1037
|
+
meeting.trigger,
|
|
1038
|
+
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED
|
|
1039
|
+
);
|
|
1040
|
+
});
|
|
1041
|
+
});
|
|
1042
|
+
|
|
690
1043
|
describe('#isReactionsSupported', () => {
|
|
691
1044
|
it('should return false if the feature is not supported for the meeting', () => {
|
|
692
1045
|
meeting.locusInfo.controls = {reactions: {enabled: false}};
|
|
@@ -851,7 +1204,7 @@ describe('plugin-meetings', () => {
|
|
|
851
1204
|
setCorrelationIdSpy = sinon.spy(meeting, 'setCorrelationId');
|
|
852
1205
|
meeting.setLocus = sinon.stub().returns(true);
|
|
853
1206
|
webex.meetings.registered = true;
|
|
854
|
-
meeting.updateLLMConnection = sinon.stub();
|
|
1207
|
+
meeting.updateLLMConnection = sinon.stub().returns(Promise.resolve());
|
|
855
1208
|
});
|
|
856
1209
|
|
|
857
1210
|
describe('successful', () => {
|
|
@@ -861,6 +1214,7 @@ describe('plugin-meetings', () => {
|
|
|
861
1214
|
|
|
862
1215
|
it('should join the meeting and return promise', async () => {
|
|
863
1216
|
const join = meeting.join({pstnAudioType: 'dial-in'});
|
|
1217
|
+
meeting.config.enableAutomaticLLM = true;
|
|
864
1218
|
|
|
865
1219
|
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
866
1220
|
name: 'client.call.initiated',
|
|
@@ -878,6 +1232,16 @@ describe('plugin-meetings', () => {
|
|
|
878
1232
|
assert.calledOnce(MeetingUtil.joinMeeting);
|
|
879
1233
|
assert.calledOnce(meeting.setLocus);
|
|
880
1234
|
assert.equal(result, joinMeetingResult);
|
|
1235
|
+
|
|
1236
|
+
assert.calledWith(
|
|
1237
|
+
TriggerProxy.trigger,
|
|
1238
|
+
sinon.match.instanceOf(Meeting),
|
|
1239
|
+
{
|
|
1240
|
+
file: 'meeting/index',
|
|
1241
|
+
function: 'join',
|
|
1242
|
+
},
|
|
1243
|
+
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_CONNECTED
|
|
1244
|
+
);
|
|
881
1245
|
});
|
|
882
1246
|
|
|
883
1247
|
it('should take trigger from meeting joinTrigger if available', () => {
|
|
@@ -953,6 +1317,7 @@ describe('plugin-meetings', () => {
|
|
|
953
1317
|
});
|
|
954
1318
|
|
|
955
1319
|
it('should post error event if failed', async () => {
|
|
1320
|
+
MeetingUtil.isPinOrGuest = sinon.stub().returns(false);
|
|
956
1321
|
await meeting.join().catch(() => {
|
|
957
1322
|
assert.deepEqual(
|
|
958
1323
|
webex.internal.newMetrics.submitClientEvent.getCall(1).args[0].name,
|
|
@@ -1056,60 +1421,6 @@ describe('plugin-meetings', () => {
|
|
|
1056
1421
|
});
|
|
1057
1422
|
});
|
|
1058
1423
|
|
|
1059
|
-
describe('receive transcription', () => {
|
|
1060
|
-
it('should invoke `receiveTranscription()` if receiveTranscription is set to true', async () => {
|
|
1061
|
-
meeting.isTranscriptionSupported = sinon.stub().returns(true);
|
|
1062
|
-
meeting.receiveTranscription = sinon.stub().returns(Promise.resolve());
|
|
1063
|
-
|
|
1064
|
-
await meeting.join({receiveTranscription: true});
|
|
1065
|
-
assert.calledOnce(meeting.receiveTranscription);
|
|
1066
|
-
});
|
|
1067
|
-
|
|
1068
|
-
it('make sure that join does not wait for setting up receive transcriptions', async () => {
|
|
1069
|
-
const defer = new Defer();
|
|
1070
|
-
|
|
1071
|
-
meeting.isTranscriptionSupported = sinon.stub().returns(true);
|
|
1072
|
-
meeting.receiveTranscription = sinon.stub().returns(defer.promise);
|
|
1073
|
-
|
|
1074
|
-
const result = await meeting.join({receiveTranscription: true});
|
|
1075
|
-
|
|
1076
|
-
assert.equal(result, joinMeetingResult);
|
|
1077
|
-
|
|
1078
|
-
defer.resolve();
|
|
1079
|
-
});
|
|
1080
|
-
|
|
1081
|
-
it('handles catching error of receiveTranscription(), and join still resolves', async () => {
|
|
1082
|
-
const defer = new Defer();
|
|
1083
|
-
|
|
1084
|
-
meeting.isTranscriptionSupported = sinon.stub().returns(true);
|
|
1085
|
-
meeting.receiveTranscription = sinon.stub().returns(defer.promise);
|
|
1086
|
-
|
|
1087
|
-
const result = await meeting.join({receiveTranscription: true});
|
|
1088
|
-
|
|
1089
|
-
assert.equal(result, joinMeetingResult);
|
|
1090
|
-
|
|
1091
|
-
defer.reject(new Error('bad day', {cause: 'bad weather'}));
|
|
1092
|
-
|
|
1093
|
-
try {
|
|
1094
|
-
await defer.promise;
|
|
1095
|
-
} catch (err) {
|
|
1096
|
-
assert.deepEqual(Metrics.sendBehavioralMetric.getCalls()[0].args, [
|
|
1097
|
-
BEHAVIORAL_METRICS.JOIN_SUCCESS,
|
|
1098
|
-
{correlation_id: meeting.correlationId},
|
|
1099
|
-
]);
|
|
1100
|
-
|
|
1101
|
-
assert.deepEqual(Metrics.sendBehavioralMetric.getCalls()[1].args, [
|
|
1102
|
-
BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_AFTER_JOIN_FAILURE,
|
|
1103
|
-
{
|
|
1104
|
-
correlation_id: meeting.correlationId,
|
|
1105
|
-
reason: err.message,
|
|
1106
|
-
stack: err.stack,
|
|
1107
|
-
},
|
|
1108
|
-
]);
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
});
|
|
1112
|
-
|
|
1113
1424
|
describe('refreshPermissionToken', () => {
|
|
1114
1425
|
it('should continue if permissionTokenRefresh fails with a generic error', async () => {
|
|
1115
1426
|
meeting.checkAndRefreshPermissionToken = sinon.stub().rejects(new Error('bad day'));
|
|
@@ -2300,6 +2611,7 @@ describe('plugin-meetings', () => {
|
|
|
2300
2611
|
|
|
2301
2612
|
beforeEach(async () => {
|
|
2302
2613
|
meeting.meetingState = 'ACTIVE';
|
|
2614
|
+
meeting.remoteShareInstanceId = '1234';
|
|
2303
2615
|
prevConfigValue = meeting.config.stats.enableStatsAnalyzer;
|
|
2304
2616
|
|
|
2305
2617
|
meeting.config.stats.enableStatsAnalyzer = true;
|
|
@@ -2405,6 +2717,66 @@ describe('plugin-meetings', () => {
|
|
|
2405
2717
|
});
|
|
2406
2718
|
});
|
|
2407
2719
|
|
|
2720
|
+
it('REMOTE_MEDIA_STARTED triggers "meeting:media:remote:start" event and sends metrics for share', async () => {
|
|
2721
|
+
statsAnalyzerStub.emit(
|
|
2722
|
+
{file: 'test', function: 'test'},
|
|
2723
|
+
StatsAnalyzerModule.EVENTS.REMOTE_MEDIA_STARTED,
|
|
2724
|
+
{type: 'share'}
|
|
2725
|
+
);
|
|
2726
|
+
|
|
2727
|
+
assert.calledWith(
|
|
2728
|
+
TriggerProxy.trigger,
|
|
2729
|
+
sinon.match.instanceOf(Meeting),
|
|
2730
|
+
{
|
|
2731
|
+
file: 'meeting/index',
|
|
2732
|
+
function: 'addMedia',
|
|
2733
|
+
},
|
|
2734
|
+
EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
|
|
2735
|
+
{
|
|
2736
|
+
type: 'share',
|
|
2737
|
+
}
|
|
2738
|
+
);
|
|
2739
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2740
|
+
name: 'client.media.rx.start',
|
|
2741
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2742
|
+
options: {
|
|
2743
|
+
meetingId: meeting.id,
|
|
2744
|
+
},
|
|
2745
|
+
});
|
|
2746
|
+
|
|
2747
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2748
|
+
name: 'client.media.render.start',
|
|
2749
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2750
|
+
options: {
|
|
2751
|
+
meetingId: meeting.id,
|
|
2752
|
+
},
|
|
2753
|
+
});
|
|
2754
|
+
});
|
|
2755
|
+
|
|
2756
|
+
it('REMOTE_MEDIA_STOPPED triggers the right metrics for share', async () => {
|
|
2757
|
+
statsAnalyzerStub.emit(
|
|
2758
|
+
{file: 'test', function: 'test'},
|
|
2759
|
+
StatsAnalyzerModule.EVENTS.REMOTE_MEDIA_STOPPED,
|
|
2760
|
+
{type: 'share'}
|
|
2761
|
+
);
|
|
2762
|
+
|
|
2763
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2764
|
+
name: 'client.media.rx.stop',
|
|
2765
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2766
|
+
options: {
|
|
2767
|
+
meetingId: meeting.id,
|
|
2768
|
+
},
|
|
2769
|
+
});
|
|
2770
|
+
|
|
2771
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2772
|
+
name: 'client.media.render.stop',
|
|
2773
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2774
|
+
options: {
|
|
2775
|
+
meetingId: meeting.id,
|
|
2776
|
+
},
|
|
2777
|
+
});
|
|
2778
|
+
});
|
|
2779
|
+
|
|
2408
2780
|
it('calls submitMQE correctly', async () => {
|
|
2409
2781
|
const fakeData = {intervalMetadata: {bla: 'bla'}};
|
|
2410
2782
|
|
|
@@ -2649,9 +3021,10 @@ describe('plugin-meetings', () => {
|
|
|
2649
3021
|
meeting.setMercuryListener = sinon.stub();
|
|
2650
3022
|
meeting.locusInfo.onFullLocus = sinon.stub();
|
|
2651
3023
|
meeting.webex.meetings.geoHintInfo = {regionCode: 'EU', countryCode: 'UK'};
|
|
2652
|
-
meeting.roap.doTurnDiscovery = sinon
|
|
2653
|
-
|
|
2654
|
-
|
|
3024
|
+
meeting.roap.doTurnDiscovery = sinon.stub().resolves({
|
|
3025
|
+
turnServerInfo: {url: 'turn-url', username: 'turn user', password: 'turn password'},
|
|
3026
|
+
turnDiscoverySkippedReason: 'reachability',
|
|
3027
|
+
});
|
|
2655
3028
|
meeting.deferSDPAnswer = new Defer();
|
|
2656
3029
|
meeting.deferSDPAnswer.resolve();
|
|
2657
3030
|
meeting.webex.meetings.meetingCollection = new MeetingCollection();
|
|
@@ -2662,7 +3035,7 @@ describe('plugin-meetings', () => {
|
|
|
2662
3035
|
// setup things that are expected to be the same across all the tests and are actually irrelevant for these tests
|
|
2663
3036
|
expectedDebugId = `MC-${meeting.id.substring(0, 4)}`;
|
|
2664
3037
|
expectedMediaConnectionConfig = {
|
|
2665
|
-
iceServers: [{urls:
|
|
3038
|
+
iceServers: [{urls: 'turn-url', username: 'turn user', credential: 'turn password'}],
|
|
2666
3039
|
skipInactiveTransceivers: false,
|
|
2667
3040
|
requireH264: true,
|
|
2668
3041
|
sdpMunging: {
|
|
@@ -2927,28 +3300,52 @@ describe('plugin-meetings', () => {
|
|
|
2927
3300
|
if (stream !== undefined) {
|
|
2928
3301
|
switch (type) {
|
|
2929
3302
|
case 'audio':
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
3303
|
+
if (stream?.readyState === 'ended') {
|
|
3304
|
+
assert.notCalled(
|
|
3305
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream
|
|
3306
|
+
);
|
|
3307
|
+
} else {
|
|
3308
|
+
assert.calledOnceWithExactly(
|
|
3309
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream,
|
|
3310
|
+
stream
|
|
3311
|
+
);
|
|
3312
|
+
}
|
|
2934
3313
|
break;
|
|
2935
3314
|
case 'video':
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
3315
|
+
if (stream?.readyState === 'ended') {
|
|
3316
|
+
assert.notCalled(
|
|
3317
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoMain).publishStream
|
|
3318
|
+
);
|
|
3319
|
+
} else {
|
|
3320
|
+
assert.calledOnceWithExactly(
|
|
3321
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoMain).publishStream,
|
|
3322
|
+
stream
|
|
3323
|
+
);
|
|
3324
|
+
}
|
|
2940
3325
|
break;
|
|
2941
3326
|
case 'screenShareAudio':
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
3327
|
+
if (stream?.readyState === 'ended') {
|
|
3328
|
+
assert.notCalled(
|
|
3329
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream
|
|
3330
|
+
);
|
|
3331
|
+
} else {
|
|
3332
|
+
assert.calledOnceWithExactly(
|
|
3333
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream,
|
|
3334
|
+
stream
|
|
3335
|
+
);
|
|
3336
|
+
}
|
|
2946
3337
|
break;
|
|
2947
3338
|
case 'screenShareVideo':
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
3339
|
+
if (stream?.readyState === 'ended') {
|
|
3340
|
+
assert.notCalled(
|
|
3341
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream
|
|
3342
|
+
);
|
|
3343
|
+
} else {
|
|
3344
|
+
assert.calledOnceWithExactly(
|
|
3345
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream,
|
|
3346
|
+
stream
|
|
3347
|
+
);
|
|
3348
|
+
}
|
|
2952
3349
|
break;
|
|
2953
3350
|
}
|
|
2954
3351
|
}
|
|
@@ -3010,6 +3407,7 @@ describe('plugin-meetings', () => {
|
|
|
3010
3407
|
});
|
|
3011
3408
|
|
|
3012
3409
|
it('addMedia() works correctly when media is enabled with streams to publish', async () => {
|
|
3410
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3013
3411
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3014
3412
|
await simulateRoapOffer();
|
|
3015
3413
|
await simulateRoapOk();
|
|
@@ -3040,9 +3438,12 @@ describe('plugin-meetings', () => {
|
|
|
3040
3438
|
|
|
3041
3439
|
// and that these were the only /media requests that were sent
|
|
3042
3440
|
assert.calledTwice(locusMediaRequestStub);
|
|
3441
|
+
|
|
3442
|
+
assert.calledOnce(handleDeviceLoggingSpy);
|
|
3043
3443
|
});
|
|
3044
3444
|
|
|
3045
3445
|
it('addMedia() works correctly when media is enabled with streams to publish and stream is user muted', async () => {
|
|
3446
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3046
3447
|
fakeMicrophoneStream.userMuted = true;
|
|
3047
3448
|
|
|
3048
3449
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
@@ -3072,6 +3473,41 @@ describe('plugin-meetings', () => {
|
|
|
3072
3473
|
// check OK was sent with the right audioMuted/videoMuted values
|
|
3073
3474
|
checkOkSent({audioMuted: true, videoMuted: true});
|
|
3074
3475
|
|
|
3476
|
+
// and that these were the only /media requests that were sent
|
|
3477
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
3478
|
+
assert.calledOnce(handleDeviceLoggingSpy);
|
|
3479
|
+
});
|
|
3480
|
+
|
|
3481
|
+
it('addMedia() works correctly when media is enabled with tracks to publish and track is ended', async () => {
|
|
3482
|
+
fakeMicrophoneStream.readyState = 'ended';
|
|
3483
|
+
|
|
3484
|
+
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3485
|
+
await simulateRoapOffer();
|
|
3486
|
+
await simulateRoapOk();
|
|
3487
|
+
|
|
3488
|
+
// check RoapMediaConnection was created correctly
|
|
3489
|
+
checkMediaConnectionCreated({
|
|
3490
|
+
mediaConnectionConfig: expectedMediaConnectionConfig,
|
|
3491
|
+
localStreams: {
|
|
3492
|
+
audio: undefined,
|
|
3493
|
+
video: undefined,
|
|
3494
|
+
screenShareVideo: undefined,
|
|
3495
|
+
screenShareAudio: undefined,
|
|
3496
|
+
},
|
|
3497
|
+
direction: {
|
|
3498
|
+
audio: 'sendrecv',
|
|
3499
|
+
video: 'sendrecv',
|
|
3500
|
+
screenShare: 'recvonly',
|
|
3501
|
+
},
|
|
3502
|
+
remoteQualityLevel: 'HIGH',
|
|
3503
|
+
expectedDebugId,
|
|
3504
|
+
meetingId: meeting.id,
|
|
3505
|
+
});
|
|
3506
|
+
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
3507
|
+
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
3508
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
3509
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
3510
|
+
|
|
3075
3511
|
// and that these were the only /media requests that were sent
|
|
3076
3512
|
assert.calledTwice(locusMediaRequestStub);
|
|
3077
3513
|
});
|
|
@@ -3111,6 +3547,7 @@ describe('plugin-meetings', () => {
|
|
|
3111
3547
|
});
|
|
3112
3548
|
|
|
3113
3549
|
it('addMedia() works correctly when media is disabled with streams to publish', async () => {
|
|
3550
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3114
3551
|
await meeting.addMedia({
|
|
3115
3552
|
localStreams: {microphone: fakeMicrophoneStream},
|
|
3116
3553
|
audioEnabled: false,
|
|
@@ -3144,8 +3581,22 @@ describe('plugin-meetings', () => {
|
|
|
3144
3581
|
|
|
3145
3582
|
// and that these were the only /media requests that were sent
|
|
3146
3583
|
assert.calledTwice(locusMediaRequestStub);
|
|
3584
|
+
assert.calledOnce(handleDeviceLoggingSpy);
|
|
3147
3585
|
});
|
|
3148
3586
|
|
|
3587
|
+
it('handleDeviceLogging not called when media is disabled', async () => {
|
|
3588
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3589
|
+
await meeting.addMedia({
|
|
3590
|
+
localStreams: {microphone: fakeMicrophoneStream},
|
|
3591
|
+
audioEnabled: false,
|
|
3592
|
+
videoEnabled: false
|
|
3593
|
+
});
|
|
3594
|
+
await simulateRoapOffer();
|
|
3595
|
+
await simulateRoapOk();
|
|
3596
|
+
|
|
3597
|
+
assert.notCalled(handleDeviceLoggingSpy);
|
|
3598
|
+
})
|
|
3599
|
+
|
|
3149
3600
|
it('addMedia() works correctly when media is disabled with no streams to publish', async () => {
|
|
3150
3601
|
await meeting.addMedia({audioEnabled: false});
|
|
3151
3602
|
await simulateRoapOffer();
|
|
@@ -3716,6 +4167,7 @@ describe('plugin-meetings', () => {
|
|
|
3716
4167
|
meeting.unsetPeerConnections = sinon.stub().returns(true);
|
|
3717
4168
|
meeting.logger.error = sinon.stub().returns(true);
|
|
3718
4169
|
meeting.updateLLMConnection = sinon.stub().returns(Promise.resolve());
|
|
4170
|
+
webex.internal.voicea.off = sinon.stub().returns(true);
|
|
3719
4171
|
|
|
3720
4172
|
// A meeting needs to be joined to leave
|
|
3721
4173
|
meeting.meetingState = 'ACTIVE';
|
|
@@ -4518,6 +4970,8 @@ describe('plugin-meetings', () => {
|
|
|
4518
4970
|
sipUrl: 'some_sip_url', // or sipMeetingUri
|
|
4519
4971
|
meetingNumber: '123456', // this.config.experimental.enableUnifiedMeetings
|
|
4520
4972
|
hostId: 'some_host_id', // this.owner;
|
|
4973
|
+
permissionToken:
|
|
4974
|
+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtb2NrUGFzc3dvcmQiOiJ0aGlzSXNNb2NrUGFzc3dvcmQifQ.3-WXiR8vhGUH3VXO0DTpsTwnnkVQ3vhGQcktwIarj3I',
|
|
4521
4975
|
};
|
|
4522
4976
|
const FAKE_MEETING_INFO_LOOKUP_URL = 'meetingLookupUrl';
|
|
4523
4977
|
|
|
@@ -4942,6 +5396,8 @@ describe('plugin-meetings', () => {
|
|
|
4942
5396
|
sipUrl: 'some_sip_url', // or sipMeetingUri
|
|
4943
5397
|
meetingNumber: '123456', // this.config.experimental.enableUnifiedMeetings
|
|
4944
5398
|
hostId: 'some_host_id', // this.owner;
|
|
5399
|
+
permissionToken:
|
|
5400
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
4945
5401
|
};
|
|
4946
5402
|
|
|
4947
5403
|
[
|
|
@@ -5094,6 +5550,8 @@ describe('plugin-meetings', () => {
|
|
|
5094
5550
|
sipUrl: 'some_sip_url',
|
|
5095
5551
|
meetingNumber: '123456',
|
|
5096
5552
|
hostId: 'some_host_id',
|
|
5553
|
+
permissionToken:
|
|
5554
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
5097
5555
|
};
|
|
5098
5556
|
const FAKE_MEETING_INFO_LOOKUP_URL = 'meetingLookupUrl';
|
|
5099
5557
|
const FAKE_PERMISSION_TOKEN = {someField: 'some value'};
|
|
@@ -5540,6 +5998,8 @@ describe('plugin-meetings', () => {
|
|
|
5540
5998
|
meeting.unsetPeerConnections = sinon.stub().returns(true);
|
|
5541
5999
|
meeting.logger.error = sinon.stub().returns(true);
|
|
5542
6000
|
meeting.updateLLMConnection = sinon.stub().returns(Promise.resolve());
|
|
6001
|
+
meeting.transcription = {};
|
|
6002
|
+
meeting.stopTranscription = sinon.stub();
|
|
5543
6003
|
|
|
5544
6004
|
// A meeting needs to be joined to end
|
|
5545
6005
|
meeting.meetingState = 'ACTIVE';
|
|
@@ -5560,6 +6020,7 @@ describe('plugin-meetings', () => {
|
|
|
5560
6020
|
assert.calledOnce(meeting?.closePeerConnections);
|
|
5561
6021
|
assert.calledOnce(meeting?.unsetRemoteStreams);
|
|
5562
6022
|
assert.calledOnce(meeting?.unsetPeerConnections);
|
|
6023
|
+
assert.calledOnce(meeting?.stopTranscription);
|
|
5563
6024
|
});
|
|
5564
6025
|
});
|
|
5565
6026
|
|
|
@@ -6008,6 +6469,65 @@ describe('plugin-meetings', () => {
|
|
|
6008
6469
|
checkScreenShareVideoPublished(videoShareStream);
|
|
6009
6470
|
checkScreenShareAudioPublished(audioShareStream);
|
|
6010
6471
|
});
|
|
6472
|
+
|
|
6473
|
+
[
|
|
6474
|
+
{
|
|
6475
|
+
endedStream: 'microphone',
|
|
6476
|
+
streams: {
|
|
6477
|
+
microphone: {
|
|
6478
|
+
readyState: 'ended',
|
|
6479
|
+
},
|
|
6480
|
+
camera: undefined,
|
|
6481
|
+
screenShare: {
|
|
6482
|
+
audio: undefined,
|
|
6483
|
+
video: undefined,
|
|
6484
|
+
},
|
|
6485
|
+
},
|
|
6486
|
+
},
|
|
6487
|
+
{
|
|
6488
|
+
endedStream: 'camera',
|
|
6489
|
+
streams: {
|
|
6490
|
+
microphone: undefined,
|
|
6491
|
+
camera: {
|
|
6492
|
+
readyState: 'ended',
|
|
6493
|
+
},
|
|
6494
|
+
screenShare: {
|
|
6495
|
+
audio: undefined,
|
|
6496
|
+
video: undefined,
|
|
6497
|
+
},
|
|
6498
|
+
},
|
|
6499
|
+
},
|
|
6500
|
+
{
|
|
6501
|
+
endedStream: 'screenShare audio',
|
|
6502
|
+
streams: {
|
|
6503
|
+
microphone: undefined,
|
|
6504
|
+
camera: undefined,
|
|
6505
|
+
screenShare: {
|
|
6506
|
+
audio: {
|
|
6507
|
+
readyState: 'ended',
|
|
6508
|
+
},
|
|
6509
|
+
video: undefined,
|
|
6510
|
+
},
|
|
6511
|
+
},
|
|
6512
|
+
},
|
|
6513
|
+
{
|
|
6514
|
+
endedStream: 'screenShare video',
|
|
6515
|
+
streams: {
|
|
6516
|
+
microphone: undefined,
|
|
6517
|
+
camera: undefined,
|
|
6518
|
+
screenShare: {
|
|
6519
|
+
audio: undefined,
|
|
6520
|
+
video: {
|
|
6521
|
+
readyState: 'ended',
|
|
6522
|
+
},
|
|
6523
|
+
},
|
|
6524
|
+
},
|
|
6525
|
+
},
|
|
6526
|
+
].forEach(({endedStream, streams}) => {
|
|
6527
|
+
it(`throws error if readyState of ${endedStream} is ended`, async () => {
|
|
6528
|
+
assert.isRejected(meeting.publishStreams(streams));
|
|
6529
|
+
});
|
|
6530
|
+
});
|
|
6011
6531
|
});
|
|
6012
6532
|
|
|
6013
6533
|
describe('unpublishStreams', () => {
|
|
@@ -6597,6 +7117,7 @@ describe('plugin-meetings', () => {
|
|
|
6597
7117
|
|
|
6598
7118
|
describe('CONNECTION_STATE_CHANGED event when state = "Disconnected"', () => {
|
|
6599
7119
|
beforeEach(() => {
|
|
7120
|
+
Metrics.sendBehavioralMetric = sinon.stub();
|
|
6600
7121
|
meeting.reconnectionManager = new ReconnectionManager(meeting);
|
|
6601
7122
|
meeting.reconnectionManager.iceReconnected = sinon.stub().returns(undefined);
|
|
6602
7123
|
meeting.setNetworkStatus = sinon.stub().returns(undefined);
|
|
@@ -6631,7 +7152,6 @@ describe('plugin-meetings', () => {
|
|
|
6631
7152
|
meeting.reconnectionManager.waitForIceReconnect = sinon.stub().resolves();
|
|
6632
7153
|
|
|
6633
7154
|
mockDisconnectedEvent();
|
|
6634
|
-
|
|
6635
7155
|
await testUtils.flushPromises();
|
|
6636
7156
|
|
|
6637
7157
|
assert.calledOnce(meeting.setNetworkStatus);
|
|
@@ -7232,6 +7752,7 @@ describe('plugin-meetings', () => {
|
|
|
7232
7752
|
});
|
|
7233
7753
|
it('listens to the self admitted guest event', (done) => {
|
|
7234
7754
|
meeting.stopKeepAlive = sinon.stub();
|
|
7755
|
+
meeting.updateLLMConnection = sinon.stub();
|
|
7235
7756
|
meeting.locusInfo.emit({function: 'test', file: 'test'}, 'SELF_ADMITTED_GUEST', test1);
|
|
7236
7757
|
assert.calledOnceWithExactly(meeting.stopKeepAlive);
|
|
7237
7758
|
assert.calledThrice(TriggerProxy.trigger);
|
|
@@ -7242,6 +7763,7 @@ describe('plugin-meetings', () => {
|
|
|
7242
7763
|
'meeting:self:guestAdmitted',
|
|
7243
7764
|
{payload: test1}
|
|
7244
7765
|
);
|
|
7766
|
+
assert.calledOnce(meeting.updateLLMConnection);
|
|
7245
7767
|
done();
|
|
7246
7768
|
});
|
|
7247
7769
|
|
|
@@ -7748,10 +8270,11 @@ describe('plugin-meetings', () => {
|
|
|
7748
8270
|
});
|
|
7749
8271
|
|
|
7750
8272
|
describe('#setUpLocusInfoMeetingListener', () => {
|
|
8273
|
+
let cleanUpSpy;
|
|
7751
8274
|
it('listens to destroy meeting event from locus info ', (done) => {
|
|
7752
8275
|
TriggerProxy.trigger.reset();
|
|
7753
8276
|
sinon.stub(meeting.reconnectionManager, 'cleanUp');
|
|
7754
|
-
sinon.
|
|
8277
|
+
cleanUpSpy = sinon.stub(MeetingUtil, 'cleanUp');
|
|
7755
8278
|
|
|
7756
8279
|
meeting.locusInfo.emit({function: 'test', file: 'test'}, EVENTS.DESTROY_MEETING, {
|
|
7757
8280
|
shouldLeave: false,
|
|
@@ -7772,6 +8295,7 @@ describe('plugin-meetings', () => {
|
|
|
7772
8295
|
meetingId: meeting.id,
|
|
7773
8296
|
}
|
|
7774
8297
|
);
|
|
8298
|
+
cleanUpSpy.restore();
|
|
7775
8299
|
done();
|
|
7776
8300
|
});
|
|
7777
8301
|
});
|
|
@@ -7885,13 +8409,12 @@ describe('plugin-meetings', () => {
|
|
|
7885
8409
|
it('sets correctly', () => {
|
|
7886
8410
|
assert.notOk(meeting.permissionTokenPayload);
|
|
7887
8411
|
|
|
7888
|
-
const permissionTokenPayloadData = {permission: {userPolicies: {a: true}}, exp: '
|
|
7889
|
-
|
|
7890
|
-
const jwtDecodeStub = sinon.stub(jwt, 'decode').returns(permissionTokenPayloadData);
|
|
8412
|
+
const permissionTokenPayloadData = {permission: {userPolicies: {a: true}}, exp: '123456'};
|
|
7891
8413
|
|
|
7892
|
-
meeting.setPermissionTokenPayload(
|
|
8414
|
+
meeting.setPermissionTokenPayload(
|
|
8415
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0'
|
|
8416
|
+
);
|
|
7893
8417
|
|
|
7894
|
-
assert.calledOnce(jwtDecodeStub);
|
|
7895
8418
|
assert.deepEqual(meeting.permissionTokenPayload, permissionTokenPayloadData);
|
|
7896
8419
|
assert.deepEqual(meeting.permissionTokenReceivedLocalTime, now);
|
|
7897
8420
|
});
|
|
@@ -8079,7 +8602,8 @@ describe('plugin-meetings', () => {
|
|
|
8079
8602
|
locusUrl: url1,
|
|
8080
8603
|
meetingJoinUrl: url2,
|
|
8081
8604
|
meetingNumber: '12345',
|
|
8082
|
-
permissionToken:
|
|
8605
|
+
permissionToken:
|
|
8606
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8083
8607
|
sipMeetingUri: test1,
|
|
8084
8608
|
sipUrl: test1,
|
|
8085
8609
|
owner: test2,
|
|
@@ -8092,8 +8616,10 @@ describe('plugin-meetings', () => {
|
|
|
8092
8616
|
sipUri: 'locusSipUri',
|
|
8093
8617
|
meetingNumber: 'locusMeetingId',
|
|
8094
8618
|
meetingJoinUrl: url2,
|
|
8619
|
+
permissionToken:
|
|
8620
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8095
8621
|
owner: 'locusOwner',
|
|
8096
|
-
|
|
8622
|
+
selfUserPolicies: {a: true},
|
|
8097
8623
|
};
|
|
8098
8624
|
|
|
8099
8625
|
checkParseMeetingInfo(expectedInfoToParse);
|
|
@@ -8106,7 +8632,8 @@ describe('plugin-meetings', () => {
|
|
|
8106
8632
|
locusUrl: url1,
|
|
8107
8633
|
meetingJoinUrl: url2,
|
|
8108
8634
|
meetingNumber: '12345',
|
|
8109
|
-
permissionToken:
|
|
8635
|
+
permissionToken:
|
|
8636
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8110
8637
|
sipMeetingUri: test1,
|
|
8111
8638
|
sipUrl: test1,
|
|
8112
8639
|
owner: test2,
|
|
@@ -8119,8 +8646,10 @@ describe('plugin-meetings', () => {
|
|
|
8119
8646
|
sipUri: test1,
|
|
8120
8647
|
meetingNumber: '12345',
|
|
8121
8648
|
meetingJoinUrl: url2,
|
|
8649
|
+
permissionToken:
|
|
8650
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8122
8651
|
owner: test2,
|
|
8123
|
-
|
|
8652
|
+
selfUserPolicies: {a: true},
|
|
8124
8653
|
};
|
|
8125
8654
|
|
|
8126
8655
|
checkParseMeetingInfo(expectedInfoToParse);
|
|
@@ -8134,7 +8663,8 @@ describe('plugin-meetings', () => {
|
|
|
8134
8663
|
locusUrl: url1,
|
|
8135
8664
|
meetingJoinUrl: url2,
|
|
8136
8665
|
meetingNumber: '12345',
|
|
8137
|
-
permissionToken:
|
|
8666
|
+
permissionToken:
|
|
8667
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8138
8668
|
sipMeetingUri: test1,
|
|
8139
8669
|
sipUrl: test1,
|
|
8140
8670
|
owner: test2,
|
|
@@ -8148,11 +8678,41 @@ describe('plugin-meetings', () => {
|
|
|
8148
8678
|
meetingNumber: '12345',
|
|
8149
8679
|
meetingJoinUrl: url2,
|
|
8150
8680
|
owner: test2,
|
|
8151
|
-
permissionToken:
|
|
8681
|
+
permissionToken:
|
|
8682
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8683
|
+
selfUserPolicies: {a: true},
|
|
8152
8684
|
};
|
|
8153
8685
|
|
|
8154
8686
|
checkParseMeetingInfo(expectedInfoToParse);
|
|
8155
8687
|
});
|
|
8688
|
+
|
|
8689
|
+
it('should parse meeting info, set values, and return null when permissionToken is not present', () => {
|
|
8690
|
+
meeting.config.experimental = {enableMediaNegotiatedEvent: true};
|
|
8691
|
+
meeting.config.experimental.enableUnifiedMeetings = true;
|
|
8692
|
+
const FAKE_STRING_DESTINATION = 'sipUrl';
|
|
8693
|
+
const FAKE_MEETING_INFO = {
|
|
8694
|
+
conversationUrl: uuid1,
|
|
8695
|
+
locusUrl: url1,
|
|
8696
|
+
meetingJoinUrl: url2,
|
|
8697
|
+
meetingNumber: '12345',
|
|
8698
|
+
sipMeetingUri: test1,
|
|
8699
|
+
sipUrl: test1,
|
|
8700
|
+
owner: test2,
|
|
8701
|
+
};
|
|
8702
|
+
|
|
8703
|
+
meeting.parseMeetingInfo(FAKE_MEETING_INFO, FAKE_STRING_DESTINATION);
|
|
8704
|
+
const expectedInfoToParse = {
|
|
8705
|
+
conversationUrl: uuid1,
|
|
8706
|
+
locusUrl: url1,
|
|
8707
|
+
sipUri: test1,
|
|
8708
|
+
meetingNumber: '12345',
|
|
8709
|
+
meetingJoinUrl: url2,
|
|
8710
|
+
owner: test2,
|
|
8711
|
+
};
|
|
8712
|
+
|
|
8713
|
+
checkParseMeetingInfo(expectedInfoToParse);
|
|
8714
|
+
});
|
|
8715
|
+
|
|
8156
8716
|
it('should parse interpretation info correctly', () => {
|
|
8157
8717
|
const parseInterpretationInfo = sinon.spy(MeetingUtil, 'parseInterpretationInfo');
|
|
8158
8718
|
const mockToggleOnData = {
|
|
@@ -8169,6 +8729,8 @@ describe('plugin-meetings', () => {
|
|
|
8169
8729
|
},
|
|
8170
8730
|
],
|
|
8171
8731
|
},
|
|
8732
|
+
permissionToken:
|
|
8733
|
+
'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0',
|
|
8172
8734
|
};
|
|
8173
8735
|
meeting.parseMeetingInfo(mockToggleOnData);
|
|
8174
8736
|
assert.calledOnceWithExactly(parseInterpretationInfo, meeting, mockToggleOnData);
|
|
@@ -8872,7 +9434,7 @@ describe('plugin-meetings', () => {
|
|
|
8872
9434
|
// Due to import tree issues, hasHints must be stubed within the scope of the `it`.
|
|
8873
9435
|
const restorableHasHints = ControlsOptionsUtil.hasHints;
|
|
8874
9436
|
ControlsOptionsUtil.hasHints = sinon.stub().returns(true);
|
|
8875
|
-
|
|
9437
|
+
const hasPoliciesSpy = sinon.stub(ControlsOptionsUtil, 'hasPolicies').returns(true);
|
|
8876
9438
|
|
|
8877
9439
|
const selfUserPolicies = {a: true};
|
|
8878
9440
|
meeting.selfUserPolicies = {a: true};
|
|
@@ -9013,6 +9575,7 @@ describe('plugin-meetings', () => {
|
|
|
9013
9575
|
assert.notCalled(TriggerProxy.trigger);
|
|
9014
9576
|
|
|
9015
9577
|
ControlsOptionsUtil.hasHints = restorableHasHints;
|
|
9578
|
+
hasPoliciesSpy.restore();
|
|
9016
9579
|
});
|
|
9017
9580
|
});
|
|
9018
9581
|
|
|
@@ -9286,9 +9849,16 @@ describe('plugin-meetings', () => {
|
|
|
9286
9849
|
it('check triggerAnnotationInfoEvent event', () => {
|
|
9287
9850
|
TriggerProxy.trigger.reset();
|
|
9288
9851
|
const annotationInfo = {version: '1', policy: 'Approval'};
|
|
9289
|
-
const expectAnnotationInfo = {
|
|
9852
|
+
const expectAnnotationInfo = {
|
|
9853
|
+
annotationInfo,
|
|
9854
|
+
meetingId: meeting.id,
|
|
9855
|
+
resourceType: 'FILE',
|
|
9856
|
+
};
|
|
9290
9857
|
meeting.webex.meetings = {};
|
|
9291
|
-
meeting.triggerAnnotationInfoEvent(
|
|
9858
|
+
meeting.triggerAnnotationInfoEvent(
|
|
9859
|
+
{annotation: annotationInfo, resourceType: 'FILE'},
|
|
9860
|
+
{}
|
|
9861
|
+
);
|
|
9292
9862
|
assert.calledWith(
|
|
9293
9863
|
TriggerProxy.trigger,
|
|
9294
9864
|
{},
|
|
@@ -9302,8 +9872,8 @@ describe('plugin-meetings', () => {
|
|
|
9302
9872
|
|
|
9303
9873
|
TriggerProxy.trigger.reset();
|
|
9304
9874
|
meeting.triggerAnnotationInfoEvent(
|
|
9305
|
-
{annotation: annotationInfo},
|
|
9306
|
-
{annotation: annotationInfo}
|
|
9875
|
+
{annotation: annotationInfo, resourceType: 'FILE'},
|
|
9876
|
+
{annotation: annotationInfo, resourceType: 'FILE'}
|
|
9307
9877
|
);
|
|
9308
9878
|
assert.notCalled(TriggerProxy.trigger);
|
|
9309
9879
|
|
|
@@ -9312,10 +9882,11 @@ describe('plugin-meetings', () => {
|
|
|
9312
9882
|
const expectAnnotationInfoUpdated = {
|
|
9313
9883
|
annotationInfo: annotationInfoUpdate,
|
|
9314
9884
|
meetingId: meeting.id,
|
|
9885
|
+
resourceType: 'FILE',
|
|
9315
9886
|
};
|
|
9316
9887
|
meeting.triggerAnnotationInfoEvent(
|
|
9317
|
-
{annotation: annotationInfoUpdate},
|
|
9318
|
-
{annotation: annotationInfo}
|
|
9888
|
+
{annotation: annotationInfoUpdate, resourceType: 'FILE'},
|
|
9889
|
+
{annotation: annotationInfo, resourceType: 'FILE'}
|
|
9319
9890
|
);
|
|
9320
9891
|
assert.calledWith(
|
|
9321
9892
|
TriggerProxy.trigger,
|
|
@@ -9329,7 +9900,10 @@ describe('plugin-meetings', () => {
|
|
|
9329
9900
|
);
|
|
9330
9901
|
|
|
9331
9902
|
TriggerProxy.trigger.reset();
|
|
9332
|
-
meeting.triggerAnnotationInfoEvent(null, {
|
|
9903
|
+
meeting.triggerAnnotationInfoEvent(null, {
|
|
9904
|
+
annotation: annotationInfoUpdate,
|
|
9905
|
+
resourceType: 'FILE',
|
|
9906
|
+
});
|
|
9333
9907
|
assert.notCalled(TriggerProxy.trigger);
|
|
9334
9908
|
});
|
|
9335
9909
|
});
|
|
@@ -9353,6 +9927,11 @@ describe('plugin-meetings', () => {
|
|
|
9353
9927
|
'https://board-a.wbx2.com/board/api/v1/channels/977a7330-54f4-11eb-b1ef-91f5eefc7bf3',
|
|
9354
9928
|
};
|
|
9355
9929
|
|
|
9930
|
+
const SHARE_TYPE = {
|
|
9931
|
+
FILE: 'FILE',
|
|
9932
|
+
DESKTOP: 'DESKTOP',
|
|
9933
|
+
};
|
|
9934
|
+
|
|
9356
9935
|
const DEVICE_URL = {
|
|
9357
9936
|
LOCAL_WEB: 'my-web-url',
|
|
9358
9937
|
LOCAL_MAC: 'my-mac-url',
|
|
@@ -9364,11 +9943,14 @@ describe('plugin-meetings', () => {
|
|
|
9364
9943
|
beneficiaryId = null,
|
|
9365
9944
|
disposition = null,
|
|
9366
9945
|
deviceUrlSharing = null,
|
|
9367
|
-
annotation = undefined
|
|
9946
|
+
annotation = undefined,
|
|
9947
|
+
resourceType = undefined
|
|
9368
9948
|
) => ({
|
|
9369
9949
|
beneficiaryId,
|
|
9370
9950
|
disposition,
|
|
9371
9951
|
deviceUrlSharing,
|
|
9952
|
+
annotation,
|
|
9953
|
+
resourceType,
|
|
9372
9954
|
});
|
|
9373
9955
|
const generateWhiteboard = (
|
|
9374
9956
|
beneficiaryId = null,
|
|
@@ -9387,7 +9969,8 @@ describe('plugin-meetings', () => {
|
|
|
9387
9969
|
annotation,
|
|
9388
9970
|
url,
|
|
9389
9971
|
shareInstanceId,
|
|
9390
|
-
deviceUrlSharing
|
|
9972
|
+
deviceUrlSharing,
|
|
9973
|
+
resourceType
|
|
9391
9974
|
) => {
|
|
9392
9975
|
const newPayload = cloneDeep(payload);
|
|
9393
9976
|
|
|
@@ -9421,7 +10004,8 @@ describe('plugin-meetings', () => {
|
|
|
9421
10004
|
beneficiaryId,
|
|
9422
10005
|
FLOOR_ACTION.GRANTED,
|
|
9423
10006
|
deviceUrlSharing,
|
|
9424
|
-
annotation
|
|
10007
|
+
annotation,
|
|
10008
|
+
resourceType
|
|
9425
10009
|
);
|
|
9426
10010
|
|
|
9427
10011
|
if (isEqual(newPayload.current, newPayload.previous)) {
|
|
@@ -9482,6 +10066,7 @@ describe('plugin-meetings', () => {
|
|
|
9482
10066
|
url,
|
|
9483
10067
|
shareInstanceId,
|
|
9484
10068
|
annotationInfo: undefined,
|
|
10069
|
+
resourceType: undefined,
|
|
9485
10070
|
},
|
|
9486
10071
|
});
|
|
9487
10072
|
}
|
|
@@ -10323,7 +10908,8 @@ describe('plugin-meetings', () => {
|
|
|
10323
10908
|
undefined,
|
|
10324
10909
|
undefined,
|
|
10325
10910
|
undefined,
|
|
10326
|
-
DEVICE_URL.REMOTE_A
|
|
10911
|
+
DEVICE_URL.REMOTE_A,
|
|
10912
|
+
undefined
|
|
10327
10913
|
);
|
|
10328
10914
|
const data2 = generateData(
|
|
10329
10915
|
data1.payload,
|
|
@@ -10336,9 +10922,39 @@ describe('plugin-meetings', () => {
|
|
|
10336
10922
|
undefined,
|
|
10337
10923
|
undefined,
|
|
10338
10924
|
undefined,
|
|
10339
|
-
DEVICE_URL.REMOTE_B
|
|
10925
|
+
DEVICE_URL.REMOTE_B,
|
|
10926
|
+
undefined
|
|
10927
|
+
);
|
|
10928
|
+
const data3 = generateData(data2.payload, false, true, USER_IDS.REMOTE_B, undefined);
|
|
10929
|
+
|
|
10930
|
+
payloadTestHelper([data1, data2, data3]);
|
|
10931
|
+
});
|
|
10932
|
+
});
|
|
10933
|
+
|
|
10934
|
+
describe('File Share --> Desktop Share', () => {
|
|
10935
|
+
it('Scenario #1: remote person A shares file then share desktop', () => {
|
|
10936
|
+
const data1 = generateData(
|
|
10937
|
+
blankPayload,
|
|
10938
|
+
true,
|
|
10939
|
+
true,
|
|
10940
|
+
USER_IDS.ME,
|
|
10941
|
+
undefined,
|
|
10942
|
+
false,
|
|
10943
|
+
undefined,
|
|
10944
|
+
undefined,
|
|
10945
|
+
undefined,
|
|
10946
|
+
undefined,
|
|
10947
|
+
DEVICE_URL.LOCAL_WEB,
|
|
10948
|
+
SHARE_TYPE.FILE
|
|
10949
|
+
);
|
|
10950
|
+
const data2 = generateData(
|
|
10951
|
+
data1.payload,
|
|
10952
|
+
true,
|
|
10953
|
+
false,
|
|
10954
|
+
USER_IDS.ME,
|
|
10955
|
+
SHARE_TYPE.DESKTOP
|
|
10340
10956
|
);
|
|
10341
|
-
const data3 = generateData(data2.payload,
|
|
10957
|
+
const data3 = generateData(data2.payload, true, true, USER_IDS.ME);
|
|
10342
10958
|
|
|
10343
10959
|
payloadTestHelper([data1, data2, data3]);
|
|
10344
10960
|
});
|