@webex/plugin-meetings 3.0.0-beta.39 → 3.0.0-beta.391
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +94 -15
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +671 -81
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +45 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.js +242 -33
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +110 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +380 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +386 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +71 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +65 -102
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +135 -330
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +86 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +4075 -2827
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +224 -136
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +177 -152
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +672 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +192 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +484 -119
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +73 -7
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +58 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +132 -25
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +102 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +18 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -446
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +223 -32
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +10 -0
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +39 -36
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +3 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +76 -5
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +366 -104
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +255 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +263 -390
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +6 -4
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reconnection-manager/index.js +266 -202
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +51 -28
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +48 -64
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +220 -70
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +179 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +357 -295
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +296 -156
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/utils.d.ts +14 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +2 -7
- package/dist/types/constants.d.ts +203 -31
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -5
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +66 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -49
- package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
- package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
- package/dist/types/meeting/index.d.ts +567 -496
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +93 -25
- package/dist/types/meeting/request.d.ts +64 -43
- package/dist/types/meeting/util.d.ts +117 -1
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +17 -0
- package/dist/types/meetings/index.d.ts +113 -21
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +17 -0
- package/dist/types/metrics/index.d.ts +4 -111
- package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
- package/dist/types/multistream/receiveSlot.d.ts +7 -3
- package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
- package/dist/types/multistream/remoteMedia.d.ts +3 -31
- package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
- package/dist/types/multistream/sendSlotManager.d.ts +70 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +60 -95
- package/dist/types/reachability/request.d.ts +3 -1
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reconnection-manager/index.d.ts +19 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +9 -8
- package/dist/types/roap/turnDiscovery.d.ts +39 -5
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +61 -0
- package/dist/types/statsAnalyzer/index.d.ts +34 -12
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +22 -19
- 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 +35 -11
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +558 -59
- package/src/breakouts/utils.ts +42 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- 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 +4 -9
- package/src/constants.ts +229 -21
- 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 +349 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +417 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +80 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +100 -108
- package/src/media/properties.ts +88 -117
- package/src/mediaQualityMetrics/config.ts +103 -238
- package/src/meeting/in-meeting-actions.ts +171 -3
- package/src/meeting/index.ts +3411 -2435
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +223 -136
- package/src/meeting/request.ts +155 -120
- package/src/meeting/util.ts +685 -395
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +170 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +507 -127
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +81 -12
- package/src/member/index.ts +58 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +134 -8
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +17 -0
- package/src/metrics/index.ts +1 -469
- package/src/multistream/mediaRequestManager.ts +271 -56
- package/src/multistream/receiveSlot.ts +11 -4
- package/src/multistream/receiveSlotManager.ts +34 -24
- package/src/multistream/remoteMedia.ts +5 -3
- package/src/multistream/remoteMediaGroup.ts +78 -0
- package/src/multistream/remoteMediaManager.ts +248 -44
- package/src/multistream/sendSlotManager.ts +199 -0
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +229 -346
- package/src/reachability/request.ts +8 -4
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +128 -97
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +52 -23
- package/src/roap/request.ts +48 -67
- package/src/roap/turnDiscovery.ts +147 -49
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +166 -0
- package/src/statsAnalyzer/index.ts +457 -416
- package/src/statsAnalyzer/mqaUtil.ts +317 -170
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +118 -28
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1349 -114
- package/test/unit/spec/breakouts/utils.js +52 -1
- 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 +625 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1363 -37
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +173 -81
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
- package/test/unit/spec/meeting/index.js +6821 -2172
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +402 -212
- package/test/unit/spec/meeting/request.js +473 -54
- package/test/unit/spec/meeting/utils.js +773 -67
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +526 -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 +1415 -213
- package/test/unit/spec/meetings/utils.js +229 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +781 -114
- package/test/unit/spec/multistream/receiveSlot.ts +9 -1
- package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
- package/test/unit/spec/multistream/remoteMedia.ts +2 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +551 -14
- package/test/unit/spec/reachability/request.js +3 -1
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +171 -11
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +180 -83
- package/test/unit/spec/roap/request.ts +100 -62
- package/test/unit/spec/roap/turnDiscovery.ts +388 -96
- package/test/unit/spec/rtcMetrics/index.ts +122 -0
- package/test/unit/spec/stats-analyzer/index.js +1252 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -57
- package/test/utils/webex-test-users.js +12 -4
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/metrics/config.d.ts +0 -169
- package/src/index.js +0 -18
- package/src/metrics/config.ts +0 -485
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
2
|
import {assert} from '@webex/test-helper-chai';
|
|
3
3
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
4
|
-
import {createMuteState} from '@webex/plugin-meetings/src/meeting/muteState';
|
|
5
|
-
import Media from '@webex/plugin-meetings/src/media/index';
|
|
4
|
+
import {createMuteState, MuteState} from '@webex/plugin-meetings/src/meeting/muteState';
|
|
6
5
|
import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
|
|
7
6
|
import {AUDIO, VIDEO} from '@webex/plugin-meetings/src/constants';
|
|
8
7
|
|
|
@@ -16,28 +15,44 @@ describe('plugin-meetings', () => {
|
|
|
16
15
|
|
|
17
16
|
const fakeLocus = {info: 'this is a fake locus'};
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
const createFakeLocalStream = (id, muted) => {
|
|
19
|
+
return {
|
|
20
|
+
id,
|
|
21
|
+
setServerMuted: sinon.stub(),
|
|
22
|
+
setUnmuteAllowed: sinon.stub(),
|
|
23
|
+
setMuted: sinon.stub(),
|
|
24
|
+
muted,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
beforeEach(async () => {
|
|
20
29
|
meeting = {
|
|
21
30
|
mediaProperties: {
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
audioStream: createFakeLocalStream('fake audio stream', false),
|
|
32
|
+
videoStream: createFakeLocalStream('fake video stream', false),
|
|
24
33
|
},
|
|
25
34
|
remoteMuted: false,
|
|
26
35
|
unmuteAllowed: true,
|
|
36
|
+
remoteVideoMuted: false,
|
|
37
|
+
unmuteVideoAllowed: true,
|
|
38
|
+
|
|
27
39
|
locusInfo: {
|
|
28
|
-
|
|
40
|
+
handleLocusDelta: sinon.stub(),
|
|
29
41
|
},
|
|
30
42
|
members: {
|
|
31
43
|
selfId: 'fake self id',
|
|
32
44
|
muteMember: sinon.stub().resolves(),
|
|
33
45
|
},
|
|
34
46
|
};
|
|
35
|
-
audio = createMuteState(AUDIO, meeting, {sendAudio: true});
|
|
36
|
-
video = createMuteState(VIDEO, meeting, {sendVideo: true});
|
|
37
47
|
|
|
38
48
|
originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
|
|
39
49
|
|
|
40
50
|
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves(fakeLocus);
|
|
51
|
+
|
|
52
|
+
audio = createMuteState(AUDIO, meeting, true);
|
|
53
|
+
video = createMuteState(VIDEO, meeting, true);
|
|
54
|
+
|
|
55
|
+
await testUtils.flushPromises();
|
|
41
56
|
});
|
|
42
57
|
|
|
43
58
|
afterEach(() => {
|
|
@@ -45,250 +60,242 @@ describe('plugin-meetings', () => {
|
|
|
45
60
|
});
|
|
46
61
|
|
|
47
62
|
describe('mute state library', () => {
|
|
48
|
-
it('does not create an audio instance if we are not sending audio', async () => {
|
|
49
|
-
assert.isNull(createMuteState(AUDIO, meeting, {sendAudio: false}));
|
|
50
|
-
assert.isNull(createMuteState(AUDIO, meeting, {}));
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('does not create a video instance if we are not sending video', async () => {
|
|
54
|
-
assert.isNull(createMuteState(VIDEO, meeting, {sendVideo: false}));
|
|
55
|
-
assert.isNull(createMuteState(VIDEO, meeting, {}));
|
|
56
|
-
});
|
|
57
|
-
|
|
58
63
|
it('takes into account current remote mute status when instantiated', async () => {
|
|
59
64
|
// simulate being already remote muted
|
|
60
65
|
meeting.remoteMuted = true;
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
|
|
67
|
+
// create a new MuteState instance
|
|
68
|
+
audio = createMuteState(AUDIO, meeting, true);
|
|
69
|
+
|
|
70
|
+
await testUtils.flushPromises();
|
|
63
71
|
|
|
64
72
|
assert.isTrue(audio.isMuted());
|
|
65
|
-
assert.
|
|
73
|
+
assert.isTrue(audio.isRemotelyMuted());
|
|
66
74
|
|
|
67
75
|
// now check the opposite case
|
|
68
76
|
meeting.remoteMuted = false;
|
|
69
77
|
|
|
70
|
-
// create a new MuteState
|
|
71
|
-
audio = createMuteState(AUDIO, meeting,
|
|
78
|
+
// create a new MuteState instance
|
|
79
|
+
audio = createMuteState(AUDIO, meeting, true);
|
|
72
80
|
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
await testUtils.flushPromises();
|
|
82
|
+
|
|
83
|
+
assert.isTrue(audio.isMuted()); // because we start with no stream
|
|
84
|
+
assert.isFalse(audio.isRemotelyMuted());
|
|
75
85
|
});
|
|
76
86
|
|
|
77
87
|
it('initialises correctly for video', async () => {
|
|
78
|
-
// setup fields related to
|
|
79
|
-
meeting.
|
|
80
|
-
meeting.
|
|
81
|
-
// create a new video MuteState intance
|
|
82
|
-
video = createMuteState(VIDEO, meeting, {sendVideo: true});
|
|
88
|
+
// setup fields related to video remote state
|
|
89
|
+
meeting.remoteVideoMuted = false;
|
|
90
|
+
meeting.unmuteVideoAllowed = false;
|
|
83
91
|
|
|
84
|
-
|
|
92
|
+
// create a new video MuteState instance
|
|
93
|
+
video = createMuteState(VIDEO, meeting, true);
|
|
94
|
+
|
|
95
|
+
await testUtils.flushPromises();
|
|
96
|
+
|
|
97
|
+
assert.isTrue(video.isMuted()); // because we start with no stream
|
|
98
|
+
assert.isFalse(video.isRemotelyMuted());
|
|
85
99
|
assert.isFalse(video.state.server.remoteMute);
|
|
86
|
-
assert.
|
|
100
|
+
assert.isFalse(video.state.server.unmuteAllowed);
|
|
87
101
|
});
|
|
88
102
|
|
|
89
103
|
it('takes remote mute into account when reporting current state', async () => {
|
|
90
|
-
assert.isFalse(audio.
|
|
104
|
+
assert.isFalse(audio.isRemotelyMuted());
|
|
91
105
|
|
|
92
106
|
// simulate remote mute
|
|
93
|
-
audio.handleServerRemoteMuteUpdate(true, true);
|
|
107
|
+
audio.handleServerRemoteMuteUpdate(meeting, true, true);
|
|
94
108
|
|
|
95
|
-
assert.isTrue(audio.
|
|
96
|
-
assert.isFalse(audio.isSelf());
|
|
109
|
+
assert.isTrue(audio.isRemotelyMuted());
|
|
97
110
|
});
|
|
98
111
|
|
|
99
112
|
it('does local unmute if localAudioUnmuteRequired is received', async () => {
|
|
100
|
-
// first we need to mute
|
|
101
|
-
|
|
113
|
+
// first we need to mute have the local stream muted
|
|
114
|
+
meeting.mediaProperties.audioStream.muted = true;
|
|
115
|
+
audio.handleLocalStreamChange(meeting);
|
|
102
116
|
|
|
103
117
|
assert.isTrue(audio.isMuted());
|
|
104
|
-
assert.isTrue(audio.isSelf());
|
|
105
118
|
|
|
106
119
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
107
120
|
|
|
108
121
|
// now simulate server requiring us to locally unmute
|
|
109
122
|
audio.handleServerLocalUnmuteRequired(meeting);
|
|
123
|
+
|
|
110
124
|
await testUtils.flushPromises();
|
|
111
125
|
|
|
112
|
-
// check that local
|
|
113
|
-
assert.calledWith(
|
|
126
|
+
// check that local stream was unmuted
|
|
127
|
+
assert.calledWith(
|
|
128
|
+
meeting.mediaProperties.audioStream.setServerMuted,
|
|
129
|
+
false,
|
|
130
|
+
'localUnmuteRequired'
|
|
131
|
+
);
|
|
114
132
|
|
|
115
133
|
// and local unmute was sent to server
|
|
116
134
|
assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
|
|
117
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, undefined
|
|
135
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
|
|
118
136
|
|
|
119
137
|
assert.isFalse(audio.isMuted());
|
|
120
|
-
assert.isFalse(audio.isSelf());
|
|
121
138
|
});
|
|
122
139
|
|
|
123
|
-
it('
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// first we need to mute and make that request last forever
|
|
128
|
-
let serverResponseResolve;
|
|
129
|
-
|
|
130
|
-
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
|
|
131
|
-
new Promise((resolve) => {
|
|
132
|
-
serverResponseResolve = resolve;
|
|
133
|
-
})
|
|
134
|
-
);
|
|
140
|
+
it('does local video unmute if localVideoUnmuteRequired is received', async () => {
|
|
141
|
+
// first we need to mute
|
|
142
|
+
meeting.mediaProperties.videoStream.muted = true;
|
|
143
|
+
video.handleLocalStreamChange(meeting);
|
|
135
144
|
|
|
136
|
-
|
|
137
|
-
.handleClientRequest(meeting, true)
|
|
138
|
-
.then(() => {
|
|
139
|
-
clientPromiseResolved = true;
|
|
140
|
-
})
|
|
141
|
-
.catch(() => {
|
|
142
|
-
clientPromiseRejected = true;
|
|
143
|
-
});
|
|
145
|
+
assert.isTrue(video.isMuted());
|
|
144
146
|
|
|
145
147
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
146
148
|
|
|
147
149
|
// now simulate server requiring us to locally unmute
|
|
148
|
-
|
|
150
|
+
video.handleServerLocalUnmuteRequired(meeting);
|
|
149
151
|
await testUtils.flushPromises();
|
|
150
152
|
|
|
151
|
-
//
|
|
152
|
-
assert.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
await testUtils.flushPromises();
|
|
153
|
+
// check that local stream was unmuted
|
|
154
|
+
assert.calledWith(
|
|
155
|
+
meeting.mediaProperties.videoStream.setServerMuted,
|
|
156
|
+
false,
|
|
157
|
+
'localUnmuteRequired'
|
|
158
|
+
);
|
|
158
159
|
|
|
159
|
-
// local unmute
|
|
160
|
+
// and local unmute was sent to server
|
|
160
161
|
assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
|
|
161
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo,
|
|
162
|
-
|
|
163
|
-
// and local track should be unmuted
|
|
164
|
-
assert.calledWith(meeting.mediaProperties.audioTrack.setMuted, false);
|
|
162
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
|
|
165
163
|
|
|
166
|
-
assert.isFalse(
|
|
167
|
-
assert.isFalse(audio.isSelf());
|
|
164
|
+
assert.isFalse(video.isMuted());
|
|
168
165
|
});
|
|
169
166
|
|
|
170
167
|
describe('#isLocallyMuted()', () => {
|
|
171
168
|
it('does not consider remote mute status for audio', async () => {
|
|
172
|
-
// simulate being already remote muted
|
|
169
|
+
// simulate being already remote muted and locally unmuted
|
|
173
170
|
meeting.remoteMuted = true;
|
|
174
|
-
|
|
175
|
-
|
|
171
|
+
meeting.mediaProperties.audioStream.muted = false;
|
|
172
|
+
|
|
173
|
+
// create a new MuteState instance
|
|
174
|
+
audio = createMuteState(AUDIO, meeting, true);
|
|
175
|
+
audio.handleLocalStreamChange(meeting);
|
|
176
|
+
|
|
177
|
+
await testUtils.flushPromises();
|
|
176
178
|
|
|
177
179
|
assert.isFalse(audio.isLocallyMuted());
|
|
178
180
|
});
|
|
179
|
-
});
|
|
180
181
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
assert.calledWith(meeting.mediaProperties.audioTrack.setMuted, true);
|
|
182
|
+
it('does not consider remote mute status for video', async () => {
|
|
183
|
+
// simulate being already remote muted
|
|
184
|
+
meeting.remoteVideoMuted = true;
|
|
185
|
+
meeting.mediaProperties.videoStream.muted = false;
|
|
186
186
|
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
// create a new MuteState instance
|
|
188
|
+
video = createMuteState(VIDEO, meeting, true);
|
|
189
|
+
video.handleLocalStreamChange(meeting);
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
audio.handleClientRequest(meeting, false);
|
|
193
|
-
assert.calledWith(meeting.mediaProperties.audioTrack.setMuted, false);
|
|
191
|
+
await testUtils.flushPromises();
|
|
194
192
|
|
|
195
|
-
|
|
196
|
-
audio.handleClientRequest(meeting, false);
|
|
197
|
-
assert.calledWith(meeting.mediaProperties.audioTrack.setMuted, false);
|
|
193
|
+
assert.isFalse(video.isLocallyMuted());
|
|
198
194
|
});
|
|
195
|
+
});
|
|
199
196
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
197
|
+
describe('handling local stream mute events', () => {
|
|
198
|
+
beforeEach(async () => {
|
|
199
|
+
audio.handleLocalStreamChange(meeting);
|
|
200
|
+
video.handleLocalStreamChange(meeting);
|
|
201
|
+
|
|
202
|
+
await testUtils.flushPromises();
|
|
203
|
+
});
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
const simulateAudioMuteChange = async (muteValue) => {
|
|
206
|
+
meeting.mediaProperties.audioStream.muted = muteValue;
|
|
207
|
+
audio.handleLocalStreamMuteStateChange(meeting, muteValue);
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
assert.calledWith(meeting.mediaProperties.videoTrack.setMuted, false);
|
|
209
|
+
await testUtils.flushPromises();
|
|
210
|
+
};
|
|
212
211
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
212
|
+
const simulateVideoMuteChange = async (muteValue) => {
|
|
213
|
+
meeting.mediaProperties.videoStream.muted = muteValue;
|
|
214
|
+
video.handleLocalStreamMuteStateChange(meeting, muteValue);
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
audio.handleClientRequest(meeting, true);
|
|
216
|
+
await testUtils.flushPromises();
|
|
217
|
+
};
|
|
221
218
|
|
|
219
|
+
it('returns correct value in isMuted() methods after local stream is muted/unmuted', async () => {
|
|
220
|
+
// mute
|
|
221
|
+
await simulateAudioMuteChange(true);
|
|
222
222
|
assert.isTrue(audio.isMuted());
|
|
223
|
-
assert.isTrue(audio.isSelf());
|
|
224
223
|
|
|
225
224
|
// unmute
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
await simulateAudioMuteChange(false);
|
|
228
226
|
assert.isFalse(audio.isMuted());
|
|
229
|
-
assert.isFalse(audio.isSelf());
|
|
230
227
|
});
|
|
231
228
|
|
|
232
229
|
it('does remote unmute when unmuting and remote mute is on', async () => {
|
|
233
230
|
// simulate remote mute
|
|
234
|
-
audio.handleServerRemoteMuteUpdate(true, true);
|
|
231
|
+
audio.handleServerRemoteMuteUpdate(meeting, true, true);
|
|
235
232
|
|
|
236
233
|
// unmute
|
|
237
|
-
await
|
|
234
|
+
await simulateAudioMuteChange(false);
|
|
238
235
|
|
|
239
236
|
// check that remote unmute was sent to server
|
|
240
237
|
assert.calledOnce(meeting.members.muteMember);
|
|
241
|
-
assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false);
|
|
238
|
+
assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false, true);
|
|
242
239
|
|
|
243
240
|
assert.isFalse(audio.isMuted());
|
|
244
|
-
assert.isFalse(audio.isSelf());
|
|
245
241
|
});
|
|
246
242
|
|
|
247
|
-
it('
|
|
248
|
-
|
|
243
|
+
it('does video remote unmute when unmuting and remote mute is on', async () => {
|
|
244
|
+
// simulate remote mute
|
|
245
|
+
video.handleServerRemoteMuteUpdate(meeting, true, true);
|
|
249
246
|
|
|
250
|
-
|
|
247
|
+
// unmute
|
|
248
|
+
await simulateVideoMuteChange(false);
|
|
251
249
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
})
|
|
256
|
-
);
|
|
250
|
+
// check that remote unmute was sent to server
|
|
251
|
+
assert.calledOnce(meeting.members.muteMember);
|
|
252
|
+
assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false, false);
|
|
257
253
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
});
|
|
254
|
+
assert.isFalse(video.isMuted());
|
|
255
|
+
});
|
|
261
256
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
257
|
+
it('does not video remote unmute when unmuting and remote mute is off', async () => {
|
|
258
|
+
// simulate remote mute
|
|
259
|
+
video.handleServerRemoteMuteUpdate(meeting, false, true);
|
|
265
260
|
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
|
|
261
|
+
// unmute
|
|
262
|
+
await simulateVideoMuteChange(false);
|
|
263
|
+
|
|
264
|
+
// check that remote unmute was not sent to server
|
|
265
|
+
assert.notCalled(meeting.members.muteMember);
|
|
269
266
|
|
|
270
|
-
assert.
|
|
267
|
+
assert.isFalse(video.isMuted());
|
|
271
268
|
});
|
|
272
269
|
|
|
273
|
-
it('
|
|
274
|
-
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().
|
|
275
|
-
new Promise((resolve, reject) => {
|
|
276
|
-
reject();
|
|
277
|
-
})
|
|
278
|
-
);
|
|
270
|
+
it('calls setServerMuted with "clientRequestFailed" when server request for local mute fails', async () => {
|
|
271
|
+
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().rejects(new Error('fake error'));
|
|
279
272
|
|
|
280
|
-
|
|
273
|
+
await simulateAudioMuteChange(true);
|
|
274
|
+
|
|
275
|
+
assert.calledOnceWithExactly(
|
|
276
|
+
meeting.mediaProperties.audioStream.setServerMuted,
|
|
277
|
+
false,
|
|
278
|
+
'clientRequestFailed'
|
|
279
|
+
);
|
|
281
280
|
});
|
|
282
281
|
|
|
283
|
-
it('
|
|
282
|
+
it('calls setServerMuted with "clientRequestFailed" if server request for remote mute fails', async () => {
|
|
284
283
|
// we only send remote mute requests when we're unmuting, so first we need to do a remote mute
|
|
285
|
-
audio.handleServerRemoteMuteUpdate(true, true);
|
|
284
|
+
audio.handleServerRemoteMuteUpdate(meeting, true, true);
|
|
285
|
+
|
|
286
|
+
await testUtils.flushPromises();
|
|
286
287
|
|
|
287
288
|
// setup the stub to simulate server error response
|
|
288
289
|
meeting.members.muteMember = sinon.stub().rejects();
|
|
290
|
+
meeting.mediaProperties.audioStream.setServerMuted.resetHistory();
|
|
289
291
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
+
await simulateAudioMuteChange(false);
|
|
293
|
+
|
|
294
|
+
assert.calledOnceWithExactly(
|
|
295
|
+
meeting.mediaProperties.audioStream.setServerMuted,
|
|
296
|
+
true,
|
|
297
|
+
'clientRequestFailed'
|
|
298
|
+
);
|
|
292
299
|
|
|
293
300
|
// even though remote mute update in the server failed, isMuted() should still return true,
|
|
294
301
|
// because of local mute
|
|
@@ -304,12 +311,13 @@ describe('plugin-meetings', () => {
|
|
|
304
311
|
})
|
|
305
312
|
);
|
|
306
313
|
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
// the stream is initially unmuted
|
|
315
|
+
// simulate many mute changes with the last one matching the first one
|
|
316
|
+
await simulateAudioMuteChange(true);
|
|
317
|
+
await simulateAudioMuteChange(false);
|
|
318
|
+
await simulateAudioMuteChange(true);
|
|
319
|
+
await simulateAudioMuteChange(false);
|
|
320
|
+
await simulateAudioMuteChange(true);
|
|
313
321
|
|
|
314
322
|
// so far there should have been only 1 request to server (because our stub hasn't resolved yet
|
|
315
323
|
// and MuteState sends only 1 server request at a time)
|
|
@@ -324,7 +332,7 @@ describe('plugin-meetings', () => {
|
|
|
324
332
|
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
325
333
|
});
|
|
326
334
|
|
|
327
|
-
it('queues up server requests when multiple
|
|
335
|
+
it('queues up server requests when multiple mute changes happen to local stream', async () => {
|
|
328
336
|
let serverResponseResolve;
|
|
329
337
|
|
|
330
338
|
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
|
|
@@ -333,104 +341,286 @@ describe('plugin-meetings', () => {
|
|
|
333
341
|
})
|
|
334
342
|
);
|
|
335
343
|
|
|
336
|
-
let firstClientPromiseResolved = false;
|
|
337
|
-
let secondClientPromiseResolved = false;
|
|
338
|
-
|
|
339
344
|
// 2 client requests, one after another without waiting for first one to resolve
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
});
|
|
343
|
-
audio.handleClientRequest(meeting, false).then(() => {
|
|
344
|
-
secondClientPromiseResolved = true;
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
await testUtils.flushPromises();
|
|
345
|
+
await simulateAudioMuteChange(true);
|
|
346
|
+
await simulateAudioMuteChange(false);
|
|
348
347
|
|
|
349
348
|
assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
|
|
350
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, undefined
|
|
349
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
|
|
351
350
|
|
|
352
351
|
// now allow the first request to complete
|
|
353
352
|
serverResponseResolve();
|
|
354
353
|
await testUtils.flushPromises();
|
|
355
|
-
assert.isTrue(firstClientPromiseResolved);
|
|
356
354
|
|
|
357
355
|
// that should trigger the second server request to be sent
|
|
358
356
|
assert.calledTwice(MeetingUtil.remoteUpdateAudioVideo);
|
|
359
|
-
assert.
|
|
360
|
-
|
|
361
|
-
|
|
357
|
+
assert.deepEqual(
|
|
358
|
+
[meeting, false, undefined],
|
|
359
|
+
MeetingUtil.remoteUpdateAudioVideo.getCall(1).args
|
|
360
|
+
);
|
|
362
361
|
|
|
363
362
|
serverResponseResolve();
|
|
364
|
-
await testUtils.flushPromises();
|
|
365
|
-
|
|
366
|
-
assert.isTrue(secondClientPromiseResolved);
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
it('rejects client request to unmute if hard mute is used', (done) => {
|
|
370
|
-
audio.handleServerRemoteMuteUpdate(true, false);
|
|
371
|
-
|
|
372
|
-
audio
|
|
373
|
-
.handleClientRequest(meeting, false)
|
|
374
|
-
.then(() => {
|
|
375
|
-
done(new Error('expected handleClientRequest to fail, but it did not!'));
|
|
376
|
-
})
|
|
377
|
-
.catch((e) => {
|
|
378
|
-
assert.isTrue(e instanceof PermissionError);
|
|
379
|
-
done();
|
|
380
|
-
});
|
|
381
363
|
});
|
|
382
364
|
|
|
383
365
|
it('does not send remote mute for video', async () => {
|
|
384
366
|
// mute
|
|
385
|
-
await
|
|
367
|
+
await simulateVideoMuteChange(true);
|
|
386
368
|
|
|
387
369
|
assert.isTrue(video.isMuted());
|
|
388
|
-
assert.isTrue(video.isSelf());
|
|
389
370
|
|
|
390
371
|
// check local mute is done, but not remote one
|
|
391
|
-
assert.calledWith(
|
|
392
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, undefined, true, meeting);
|
|
372
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
|
|
393
373
|
assert.notCalled(meeting.members.muteMember);
|
|
394
374
|
|
|
395
|
-
meeting.mediaProperties.videoTrack.setMuted.resetHistory();
|
|
396
375
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
397
376
|
meeting.members.muteMember.resetHistory();
|
|
398
377
|
|
|
399
378
|
// unmute
|
|
400
|
-
await
|
|
379
|
+
await simulateVideoMuteChange(false);
|
|
401
380
|
|
|
402
381
|
assert.isFalse(video.isMuted());
|
|
403
|
-
assert.isFalse(video.isSelf());
|
|
404
382
|
|
|
405
|
-
assert.calledWith(
|
|
406
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, undefined, false, meeting);
|
|
383
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
|
|
407
384
|
assert.notCalled(meeting.members.muteMember);
|
|
408
385
|
});
|
|
409
386
|
|
|
410
|
-
it('sends
|
|
387
|
+
it('sends undefined value for the other media type when sending local mute', async () => {
|
|
411
388
|
// make sure the meeting object has mute state machines for both audio and video
|
|
412
389
|
meeting.audio = audio;
|
|
413
390
|
meeting.video = video;
|
|
414
391
|
|
|
415
|
-
// mute audio ->
|
|
416
|
-
await
|
|
417
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo,
|
|
392
|
+
// mute audio -> the call to remoteUpdateAudioVideo should have video undefined
|
|
393
|
+
await simulateAudioMuteChange(true);
|
|
394
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
|
|
418
395
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
419
396
|
|
|
420
|
-
// now mute video ->
|
|
421
|
-
await
|
|
422
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo,
|
|
397
|
+
// now mute video -> the call to remoteUpdateAudioVideo should have unmute for video and undefined for audio
|
|
398
|
+
await simulateVideoMuteChange(true);
|
|
399
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
|
|
423
400
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
424
401
|
|
|
425
|
-
// now unmute the audio ->
|
|
426
|
-
await
|
|
427
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo,
|
|
402
|
+
// now unmute the audio -> the call to remoteUpdateAudioVideo should have video undefined
|
|
403
|
+
await simulateAudioMuteChange(false);
|
|
404
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
|
|
428
405
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
429
406
|
|
|
430
|
-
// unmute video ->
|
|
431
|
-
await
|
|
432
|
-
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo,
|
|
407
|
+
// unmute video -> the call to remoteUpdateAudioVideo should have audio undefined
|
|
408
|
+
await simulateVideoMuteChange(false);
|
|
409
|
+
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
|
|
433
410
|
});
|
|
434
411
|
});
|
|
412
|
+
|
|
413
|
+
describe('#init, #handleLocalStreamChange', () => {
|
|
414
|
+
let meeting;
|
|
415
|
+
let muteState;
|
|
416
|
+
let setServerMutedSpy;
|
|
417
|
+
let setMutedSpy, setUnmuteAllowedSpy;
|
|
418
|
+
|
|
419
|
+
const setupMeeting = (
|
|
420
|
+
mediaType,
|
|
421
|
+
remoteMuted = false,
|
|
422
|
+
muted = false,
|
|
423
|
+
defineStreams = true
|
|
424
|
+
) => {
|
|
425
|
+
const remoteMuteField = mediaType === AUDIO ? 'remoteMuted' : 'remoteVideoMuted';
|
|
426
|
+
|
|
427
|
+
meeting = {
|
|
428
|
+
mediaProperties: {
|
|
429
|
+
audioStream: defineStreams
|
|
430
|
+
? createFakeLocalStream('fake audio stream', muted)
|
|
431
|
+
: undefined,
|
|
432
|
+
videoStream: defineStreams
|
|
433
|
+
? createFakeLocalStream('fake video stream', muted)
|
|
434
|
+
: undefined,
|
|
435
|
+
},
|
|
436
|
+
[remoteMuteField]: remoteMuted,
|
|
437
|
+
unmuteAllowed: true,
|
|
438
|
+
unmuteVideoAllowed: true,
|
|
439
|
+
|
|
440
|
+
locusInfo: {
|
|
441
|
+
onFullLocus: sinon.stub(),
|
|
442
|
+
},
|
|
443
|
+
members: {
|
|
444
|
+
selfId: 'fake self id',
|
|
445
|
+
muteMember: sinon.stub().resolves(),
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
const setup = async (mediaType, remoteMuted = false, muted = false, defineStreams = true) => {
|
|
451
|
+
setupMeeting(mediaType, remoteMuted, muted, defineStreams);
|
|
452
|
+
|
|
453
|
+
muteState = createMuteState(mediaType, meeting, true);
|
|
454
|
+
muteState.handleLocalStreamChange(meeting);
|
|
455
|
+
|
|
456
|
+
await testUtils.flushPromises();
|
|
457
|
+
|
|
458
|
+
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
const setupSpies = (mediaType) => {
|
|
462
|
+
setUnmuteAllowedSpy =
|
|
463
|
+
mediaType === AUDIO
|
|
464
|
+
? meeting.mediaProperties.audioStream?.setUnmuteAllowed
|
|
465
|
+
: meeting.mediaProperties.videoStream?.setUnmuteAllowed;
|
|
466
|
+
setServerMutedSpy =
|
|
467
|
+
mediaType === AUDIO
|
|
468
|
+
? meeting.mediaProperties.audioStream?.setServerMuted
|
|
469
|
+
: meeting.mediaProperties.videoStream?.setServerMuted;
|
|
470
|
+
setMutedSpy =
|
|
471
|
+
mediaType === AUDIO
|
|
472
|
+
? meeting.mediaProperties.audioStream?.setMuted
|
|
473
|
+
: meeting.mediaProperties.videoStream?.setMuted;
|
|
474
|
+
|
|
475
|
+
clearSpies();
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const clearSpies = () => {
|
|
479
|
+
setUnmuteAllowedSpy?.resetHistory();
|
|
480
|
+
setServerMutedSpy?.resetHistory();
|
|
481
|
+
setMutedSpy?.resetHistory();
|
|
482
|
+
};
|
|
483
|
+
const tests = [
|
|
484
|
+
{mediaType: AUDIO, title: 'audio'},
|
|
485
|
+
{mediaType: VIDEO, title: 'video'},
|
|
486
|
+
];
|
|
487
|
+
|
|
488
|
+
tests.forEach(({mediaType, title}) =>
|
|
489
|
+
describe(title, () => {
|
|
490
|
+
let originalRemoteUpdateAudioVideo;
|
|
491
|
+
|
|
492
|
+
beforeEach(() => {
|
|
493
|
+
originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
|
|
494
|
+
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves({info: 'fake locus'});
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
afterEach(() => {
|
|
498
|
+
MeetingUtil.remoteUpdateAudioVideo = originalRemoteUpdateAudioVideo;
|
|
499
|
+
sinon.restore();
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
describe('#handleLocalStreamChange', () => {
|
|
503
|
+
it('calls init()', async () => {
|
|
504
|
+
await setup(mediaType);
|
|
505
|
+
const spy = sinon.spy(muteState, 'init');
|
|
506
|
+
muteState.handleLocalStreamChange(meeting);
|
|
507
|
+
assert.calledOnceWithExactly(spy, meeting);
|
|
508
|
+
});
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
describe('#init', () => {
|
|
512
|
+
// does the setup by calling new MuteState() so that MuteState.init() doesn't get called
|
|
513
|
+
const setupWithoutInit = async (
|
|
514
|
+
mediaType,
|
|
515
|
+
remoteMuted = false,
|
|
516
|
+
muted = false,
|
|
517
|
+
defineStreams = true
|
|
518
|
+
) => {
|
|
519
|
+
setupMeeting(mediaType, remoteMuted, muted, defineStreams);
|
|
520
|
+
|
|
521
|
+
muteState = new MuteState(mediaType, meeting, true);
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
it('nothing goes bad when stream is undefined', async () => {
|
|
525
|
+
await setupWithoutInit(mediaType, false, false, false);
|
|
526
|
+
setupSpies(mediaType);
|
|
527
|
+
|
|
528
|
+
muteState.init(meeting);
|
|
529
|
+
|
|
530
|
+
assert.isTrue(muteState.state.client.localMute);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
it('tests when stream muted is true and remoteMuted is false', async () => {
|
|
534
|
+
await setupWithoutInit(mediaType, false, true);
|
|
535
|
+
setupSpies(mediaType);
|
|
536
|
+
|
|
537
|
+
muteState.init(meeting);
|
|
538
|
+
|
|
539
|
+
assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
|
|
540
|
+
assert.notCalled(setServerMutedSpy);
|
|
541
|
+
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
542
|
+
assert.isTrue(muteState.state.client.localMute);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
it('tests when stream muted is false and remoteMuted is false', async () => {
|
|
546
|
+
await setupWithoutInit(mediaType, false, false);
|
|
547
|
+
setupSpies(mediaType);
|
|
548
|
+
|
|
549
|
+
muteState.init(meeting);
|
|
550
|
+
|
|
551
|
+
assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
|
|
552
|
+
assert.notCalled(setServerMutedSpy);
|
|
553
|
+
assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
|
|
554
|
+
assert.isFalse(muteState.state.client.localMute);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('tests when remoteMuted is true', async () => {
|
|
558
|
+
// testing that muteLocalStream is called
|
|
559
|
+
await setupWithoutInit(mediaType, true);
|
|
560
|
+
setupSpies(mediaType);
|
|
561
|
+
|
|
562
|
+
muteState.init(meeting);
|
|
563
|
+
|
|
564
|
+
assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
|
|
565
|
+
assert.calledOnceWithExactly(setServerMutedSpy, true, 'remotelyMuted');
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
describe('#handleLocalStreamMuteStateChange', () => {
|
|
570
|
+
it('checks when ignoreMuteStateChange is true nothing changes', async () => {
|
|
571
|
+
await setup(mediaType, false, false);
|
|
572
|
+
muteState.ignoreMuteStateChange = true;
|
|
573
|
+
|
|
574
|
+
muteState.handleLocalStreamMuteStateChange(meeting, true);
|
|
575
|
+
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
576
|
+
|
|
577
|
+
assert.isFalse(muteState.state.client.localMute);
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
it('tests localMute - true to false', async () => {
|
|
581
|
+
await setup(mediaType, false, true);
|
|
582
|
+
|
|
583
|
+
muteState.handleLocalStreamMuteStateChange(meeting, false);
|
|
584
|
+
assert.equal(muteState.state.client.localMute, false);
|
|
585
|
+
assert.called(MeetingUtil.remoteUpdateAudioVideo);
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it('tests localMute - false to true', async () => {
|
|
589
|
+
await setup(mediaType, false, false);
|
|
590
|
+
|
|
591
|
+
muteState.handleLocalStreamMuteStateChange(meeting, true);
|
|
592
|
+
assert.equal(muteState.state.client.localMute, true);
|
|
593
|
+
assert.called(MeetingUtil.remoteUpdateAudioVideo);
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
describe('#applyClientStateLocally', () => {
|
|
598
|
+
afterEach(() => {
|
|
599
|
+
sinon.restore();
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
it('calls setServerMuted on the stream', async () => {
|
|
603
|
+
await setup(mediaType);
|
|
604
|
+
setupSpies(mediaType);
|
|
605
|
+
|
|
606
|
+
muteState.applyClientStateLocally(meeting, 'somereason');
|
|
607
|
+
assert.calledOnceWithExactly(
|
|
608
|
+
setServerMutedSpy,
|
|
609
|
+
muteState.state.client.localMute,
|
|
610
|
+
'somereason'
|
|
611
|
+
);
|
|
612
|
+
assert.notCalled(setMutedSpy);
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
it('nothing explodes when streams are undefined', async () => {
|
|
616
|
+
await setup(mediaType, false, false, false);
|
|
617
|
+
setupSpies(mediaType);
|
|
618
|
+
|
|
619
|
+
muteState.applyClientStateLocally(meeting, 'somereason');
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
})
|
|
623
|
+
);
|
|
624
|
+
});
|
|
435
625
|
});
|
|
436
626
|
});
|