@webex/plugin-meetings 3.7.0-next.56 → 3.7.0-next.58
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/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/brbState.js +167 -0
- package/dist/meeting/brbState.js.map +1 -0
- package/dist/meeting/index.js +237 -243
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/meeting/brbState.d.ts +54 -0
- package/dist/types/meeting/index.d.ts +2 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +3 -3
- package/src/meeting/brbState.ts +169 -0
- package/src/meeting/index.ts +10 -18
- package/test/unit/spec/meeting/brbState.ts +114 -0
- package/test/unit/spec/meeting/index.js +29 -26
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type Meeting from '.';
|
|
2
|
+
import SendSlotManager from '../multistream/sendSlotManager';
|
|
3
|
+
export declare const createBrbState: (meeting: Meeting, enabled: boolean) => BrbState;
|
|
4
|
+
/** The purpose of this class is to manage the local and remote brb state
|
|
5
|
+
* and make sure that the server state always matches the last requested state by the client.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BrbState {
|
|
8
|
+
state: {
|
|
9
|
+
client: {
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
};
|
|
12
|
+
server: {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
};
|
|
15
|
+
syncToServerInProgress: boolean;
|
|
16
|
+
};
|
|
17
|
+
meeting: Meeting;
|
|
18
|
+
/**
|
|
19
|
+
* Constructor
|
|
20
|
+
*
|
|
21
|
+
* @param {Meeting} meeting - the meeting object
|
|
22
|
+
* @param {boolean} enabled - whether the client audio/video is enabled at all
|
|
23
|
+
*/
|
|
24
|
+
constructor(meeting: Meeting, enabled: boolean);
|
|
25
|
+
/**
|
|
26
|
+
* Enables/disables brb
|
|
27
|
+
*
|
|
28
|
+
* @param {boolean} enabled
|
|
29
|
+
* @param {SendSlotManager} sendSlotManager
|
|
30
|
+
* @returns {Promise}
|
|
31
|
+
*/
|
|
32
|
+
enable(enabled: boolean, sendSlotManager: SendSlotManager): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Updates the server local and remote brb values so that they match the current client desired state.
|
|
35
|
+
*
|
|
36
|
+
* @param {SendSlotManager} sendSlotManager
|
|
37
|
+
* @returns {Promise}
|
|
38
|
+
*/
|
|
39
|
+
private applyClientStateToServer;
|
|
40
|
+
/**
|
|
41
|
+
* Send the local brb state to the server
|
|
42
|
+
*
|
|
43
|
+
* @param {SendSlotManager} sendSlotManager
|
|
44
|
+
* @returns {Promise}
|
|
45
|
+
*/
|
|
46
|
+
private sendLocalBrbStateToServer;
|
|
47
|
+
/**
|
|
48
|
+
* This method should be called whenever the server brb state is changed
|
|
49
|
+
*
|
|
50
|
+
* @param {Boolean} [enabled] true if user has brb enabled, false otherwise
|
|
51
|
+
* @returns {undefined}
|
|
52
|
+
*/
|
|
53
|
+
handleServerBrbUpdate(enabled?: boolean): void;
|
|
54
|
+
}
|
|
@@ -19,6 +19,7 @@ import InMeetingActions from './in-meeting-actions';
|
|
|
19
19
|
import RecordingController from '../recording-controller';
|
|
20
20
|
import ControlsOptionsManager from '../controls-options-manager';
|
|
21
21
|
import { LocusMediaRequest } from './locusMediaRequest';
|
|
22
|
+
import { BrbState } from './brbState';
|
|
22
23
|
export type CaptionData = {
|
|
23
24
|
id: string;
|
|
24
25
|
isFinal: boolean;
|
|
@@ -449,6 +450,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
449
450
|
turnServerUsed: boolean;
|
|
450
451
|
areVoiceaEventsSetup: boolean;
|
|
451
452
|
isMoveToInProgress: boolean;
|
|
453
|
+
brbState: BrbState;
|
|
452
454
|
voiceaListenerCallbacks: object;
|
|
453
455
|
private addMediaData;
|
|
454
456
|
private sendSlotManager;
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-meetings": "3.7.0-next.
|
|
46
|
+
"@webex/plugin-meetings": "3.7.0-next.58",
|
|
47
47
|
"@webex/plugin-rooms": "3.7.0-next.22",
|
|
48
48
|
"@webex/test-helper-chai": "3.7.0-next.16",
|
|
49
49
|
"@webex/test-helper-mocha": "3.7.0-next.16",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@webex/internal-plugin-metrics": "3.7.0-next.16",
|
|
72
72
|
"@webex/internal-plugin-support": "3.7.0-next.23",
|
|
73
73
|
"@webex/internal-plugin-user": "3.7.0-next.16",
|
|
74
|
-
"@webex/internal-plugin-voicea": "3.7.0-next.
|
|
74
|
+
"@webex/internal-plugin-voicea": "3.7.0-next.58",
|
|
75
75
|
"@webex/media-helpers": "3.7.0-next.22",
|
|
76
76
|
"@webex/plugin-people": "3.7.0-next.20",
|
|
77
77
|
"@webex/plugin-rooms": "3.7.0-next.22",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"//": [
|
|
93
93
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
94
94
|
],
|
|
95
|
-
"version": "3.7.0-next.
|
|
95
|
+
"version": "3.7.0-next.58"
|
|
96
96
|
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {MediaType} from '@webex/internal-media-core';
|
|
2
|
+
import LoggerProxy from '../common/logs/logger-proxy';
|
|
3
|
+
import type Meeting from '.';
|
|
4
|
+
import SendSlotManager from '../multistream/sendSlotManager';
|
|
5
|
+
|
|
6
|
+
export const createBrbState = (meeting: Meeting, enabled: boolean) => {
|
|
7
|
+
LoggerProxy.logger.info(
|
|
8
|
+
`Meeting:brbState#createBrbState: creating BrbState for meeting id ${meeting?.id}`
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const brbState = new BrbState(meeting, enabled);
|
|
12
|
+
|
|
13
|
+
return brbState;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** The purpose of this class is to manage the local and remote brb state
|
|
17
|
+
* and make sure that the server state always matches the last requested state by the client.
|
|
18
|
+
*/
|
|
19
|
+
export class BrbState {
|
|
20
|
+
state: {
|
|
21
|
+
client: {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
};
|
|
24
|
+
server: {
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
};
|
|
27
|
+
syncToServerInProgress: boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
meeting: Meeting;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Constructor
|
|
34
|
+
*
|
|
35
|
+
* @param {Meeting} meeting - the meeting object
|
|
36
|
+
* @param {boolean} enabled - whether the client audio/video is enabled at all
|
|
37
|
+
*/
|
|
38
|
+
constructor(meeting: Meeting, enabled: boolean) {
|
|
39
|
+
this.meeting = meeting;
|
|
40
|
+
this.state = {
|
|
41
|
+
client: {
|
|
42
|
+
enabled,
|
|
43
|
+
},
|
|
44
|
+
server: {
|
|
45
|
+
enabled: false,
|
|
46
|
+
},
|
|
47
|
+
syncToServerInProgress: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Enables/disables brb
|
|
53
|
+
*
|
|
54
|
+
* @param {boolean} enabled
|
|
55
|
+
* @param {SendSlotManager} sendSlotManager
|
|
56
|
+
* @returns {Promise}
|
|
57
|
+
*/
|
|
58
|
+
public enable(enabled: boolean, sendSlotManager: SendSlotManager) {
|
|
59
|
+
this.state.client.enabled = enabled;
|
|
60
|
+
|
|
61
|
+
return this.applyClientStateToServer(sendSlotManager);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Updates the server local and remote brb values so that they match the current client desired state.
|
|
66
|
+
*
|
|
67
|
+
* @param {SendSlotManager} sendSlotManager
|
|
68
|
+
* @returns {Promise}
|
|
69
|
+
*/
|
|
70
|
+
private applyClientStateToServer(sendSlotManager: SendSlotManager) {
|
|
71
|
+
if (this.state.syncToServerInProgress) {
|
|
72
|
+
LoggerProxy.logger.info(
|
|
73
|
+
`Meeting:brbState#applyClientStateToServer: request to server in progress, we need to wait for it to complete`
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return Promise.resolve();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const remoteBrbRequiresSync = this.state.client.enabled !== this.state.server.enabled;
|
|
80
|
+
|
|
81
|
+
LoggerProxy.logger.info(
|
|
82
|
+
`Meeting:brbState#applyClientStateToServer: remoteBrbRequiresSync: ${remoteBrbRequiresSync}`
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
if (!remoteBrbRequiresSync) {
|
|
86
|
+
LoggerProxy.logger.info(
|
|
87
|
+
`Meeting:brbState#applyClientStateToServer: client state already matching server state, nothing to do`
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
return Promise.resolve();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.state.syncToServerInProgress = true;
|
|
94
|
+
|
|
95
|
+
return this.sendLocalBrbStateToServer(sendSlotManager)
|
|
96
|
+
.then(() => {
|
|
97
|
+
this.state.syncToServerInProgress = false;
|
|
98
|
+
LoggerProxy.logger.info(
|
|
99
|
+
`Meeting:brbState#applyClientStateToServer: sync with server completed`
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// need to check if a new sync is required, because this.state.client may have changed while we were doing the current sync
|
|
103
|
+
this.applyClientStateToServer(sendSlotManager);
|
|
104
|
+
})
|
|
105
|
+
.catch((e) => {
|
|
106
|
+
this.state.syncToServerInProgress = false;
|
|
107
|
+
LoggerProxy.logger.warn(`Meeting:brbState#applyClientStateToServer: error: ${e}`);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Send the local brb state to the server
|
|
113
|
+
*
|
|
114
|
+
* @param {SendSlotManager} sendSlotManager
|
|
115
|
+
* @returns {Promise}
|
|
116
|
+
*/
|
|
117
|
+
private async sendLocalBrbStateToServer(sendSlotManager: SendSlotManager) {
|
|
118
|
+
const {enabled} = this.state.client;
|
|
119
|
+
|
|
120
|
+
if (!this.meeting.isMultistream) {
|
|
121
|
+
const errorMessage = 'Meeting:brbState#sendLocalBrbStateToServer: Not a multistream meeting';
|
|
122
|
+
const error = new Error(errorMessage);
|
|
123
|
+
|
|
124
|
+
LoggerProxy.logger.error(error);
|
|
125
|
+
|
|
126
|
+
return Promise.reject(error);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!this.meeting.mediaProperties.webrtcMediaConnection) {
|
|
130
|
+
const errorMessage =
|
|
131
|
+
'Meeting:brbState#sendLocalBrbStateToServer: WebRTC media connection is not defined';
|
|
132
|
+
const error = new Error(errorMessage);
|
|
133
|
+
|
|
134
|
+
LoggerProxy.logger.error(error);
|
|
135
|
+
|
|
136
|
+
return Promise.reject(error);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// this logic should be applied only to multistream meetings
|
|
140
|
+
return this.meeting.meetingRequest
|
|
141
|
+
.setBrb({
|
|
142
|
+
enabled,
|
|
143
|
+
locusUrl: this.meeting.locusUrl,
|
|
144
|
+
deviceUrl: this.meeting.deviceUrl,
|
|
145
|
+
selfId: this.meeting.selfId,
|
|
146
|
+
})
|
|
147
|
+
.then(() => {
|
|
148
|
+
sendSlotManager.setSourceStateOverride(MediaType.VideoMain, enabled ? 'away' : null);
|
|
149
|
+
})
|
|
150
|
+
.catch((error) => {
|
|
151
|
+
LoggerProxy.logger.error('Meeting:brbState#sendLocalBrbStateToServer: Error ', error);
|
|
152
|
+
|
|
153
|
+
return Promise.reject(error);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* This method should be called whenever the server brb state is changed
|
|
159
|
+
*
|
|
160
|
+
* @param {Boolean} [enabled] true if user has brb enabled, false otherwise
|
|
161
|
+
* @returns {undefined}
|
|
162
|
+
*/
|
|
163
|
+
public handleServerBrbUpdate(enabled?: boolean) {
|
|
164
|
+
LoggerProxy.logger.info(
|
|
165
|
+
`Meeting:brbState#handleServerBrbUpdate: updating server brb to (${enabled})`
|
|
166
|
+
);
|
|
167
|
+
this.state.server.enabled = !!enabled;
|
|
168
|
+
}
|
|
169
|
+
}
|
package/src/meeting/index.ts
CHANGED
|
@@ -163,6 +163,7 @@ import {LocusMediaRequest} from './locusMediaRequest';
|
|
|
163
163
|
import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
|
|
164
164
|
import JoinWebinarError from '../common/errors/join-webinar-error';
|
|
165
165
|
import Member from '../member';
|
|
166
|
+
import {BrbState, createBrbState} from './brbState';
|
|
166
167
|
import MultistreamNotSupportedError from '../common/errors/multistream-not-supported-error';
|
|
167
168
|
import JoinForbiddenError from '../common/errors/join-forbidden-error';
|
|
168
169
|
|
|
@@ -649,6 +650,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
649
650
|
turnServerUsed: boolean;
|
|
650
651
|
areVoiceaEventsSetup = false;
|
|
651
652
|
isMoveToInProgress = false;
|
|
653
|
+
brbState: BrbState;
|
|
652
654
|
|
|
653
655
|
voiceaListenerCallbacks: object = {
|
|
654
656
|
[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]: (payload: Transcription['languageOptions']) => {
|
|
@@ -3407,6 +3409,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3407
3409
|
});
|
|
3408
3410
|
|
|
3409
3411
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_MEETING_BRB_CHANGED, (payload) => {
|
|
3412
|
+
this.brbState?.handleServerBrbUpdate(payload?.brb?.enabled);
|
|
3410
3413
|
Trigger.trigger(
|
|
3411
3414
|
this,
|
|
3412
3415
|
{
|
|
@@ -3650,22 +3653,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3650
3653
|
return Promise.reject(error);
|
|
3651
3654
|
}
|
|
3652
3655
|
|
|
3653
|
-
|
|
3654
|
-
return this.meetingRequest
|
|
3655
|
-
.setBrb({
|
|
3656
|
-
enabled,
|
|
3657
|
-
locusUrl: this.locusUrl,
|
|
3658
|
-
deviceUrl: this.deviceUrl,
|
|
3659
|
-
selfId: this.selfId,
|
|
3660
|
-
})
|
|
3661
|
-
.then(() => {
|
|
3662
|
-
this.sendSlotManager.setSourceStateOverride(MediaType.VideoMain, enabled ? 'away' : null);
|
|
3663
|
-
})
|
|
3664
|
-
.catch((error) => {
|
|
3665
|
-
LoggerProxy.logger.error('Meeting:index#beRightBack --> Error ', error);
|
|
3666
|
-
|
|
3667
|
-
return Promise.reject(error);
|
|
3668
|
-
});
|
|
3656
|
+
return this.brbState.enable(enabled, this.sendSlotManager);
|
|
3669
3657
|
}
|
|
3670
3658
|
|
|
3671
3659
|
/**
|
|
@@ -6099,9 +6087,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6099
6087
|
* @returns {undefined}
|
|
6100
6088
|
*/
|
|
6101
6089
|
public roapMessageReceived = (roapMessage: RoapMessage) => {
|
|
6102
|
-
const mediaServer =
|
|
6090
|
+
const mediaServer =
|
|
6091
|
+
roapMessage.messageType === 'ANSWER'
|
|
6092
|
+
? MeetingsUtil.getMediaServer(roapMessage.sdp)
|
|
6093
|
+
: undefined;
|
|
6103
6094
|
|
|
6104
|
-
if (this.isMultistream && mediaServer !== 'homer') {
|
|
6095
|
+
if (this.isMultistream && mediaServer && mediaServer !== 'homer') {
|
|
6105
6096
|
throw new MultistreamNotSupportedError(
|
|
6106
6097
|
`Client asked for multistream backend (Homer), but got ${mediaServer} instead`
|
|
6107
6098
|
);
|
|
@@ -7432,6 +7423,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7432
7423
|
|
|
7433
7424
|
this.audio = createMuteState(AUDIO, this, audioEnabled);
|
|
7434
7425
|
this.video = createMuteState(VIDEO, this, videoEnabled);
|
|
7426
|
+
this.brbState = createBrbState(this, false);
|
|
7435
7427
|
|
|
7436
7428
|
try {
|
|
7437
7429
|
await this.setUpLocalStreamReferences(localStreams);
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
|
|
4
|
+
import testUtils from '../../../utils/testUtils';
|
|
5
|
+
import {BrbState, createBrbState} from '@webex/plugin-meetings/src/meeting/brbState';
|
|
6
|
+
|
|
7
|
+
describe('plugin-meetings', () => {
|
|
8
|
+
let meeting: any;
|
|
9
|
+
let brbState: BrbState;
|
|
10
|
+
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
meeting = {
|
|
13
|
+
isMultistream: true,
|
|
14
|
+
locusUrl: 'locus url',
|
|
15
|
+
deviceUrl: 'device url',
|
|
16
|
+
selfId: 'self id',
|
|
17
|
+
mediaProperties: {
|
|
18
|
+
webrtcMediaConnection: true,
|
|
19
|
+
},
|
|
20
|
+
sendSlotManager: {
|
|
21
|
+
setSourceStateOverride: sinon.stub(),
|
|
22
|
+
},
|
|
23
|
+
meetingRequest: {
|
|
24
|
+
setBrb: sinon.stub().resolves(),
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
brbState = new BrbState(meeting, false);
|
|
29
|
+
await testUtils.flushPromises();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('brbState library', () => {
|
|
33
|
+
it('takes into account current status when instantiated', async () => {
|
|
34
|
+
// create a new BrbState instance
|
|
35
|
+
brbState = createBrbState(meeting, true);
|
|
36
|
+
await testUtils.flushPromises();
|
|
37
|
+
|
|
38
|
+
assert.isTrue(brbState.state.client.enabled);
|
|
39
|
+
|
|
40
|
+
// now check the opposite case
|
|
41
|
+
brbState = createBrbState(meeting, false);
|
|
42
|
+
await testUtils.flushPromises();
|
|
43
|
+
|
|
44
|
+
assert.isFalse(brbState.state.client.enabled);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('can be enabled', async () => {
|
|
48
|
+
brbState.enable(true, meeting.sendSlotManager);
|
|
49
|
+
brbState.handleServerBrbUpdate(true);
|
|
50
|
+
await testUtils.flushPromises();
|
|
51
|
+
|
|
52
|
+
assert.isTrue(brbState.state.client.enabled);
|
|
53
|
+
assert.isTrue(brbState.state.server.enabled);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('can be disabled', async () => {
|
|
57
|
+
brbState.enable(false, meeting.sendSlotManager);
|
|
58
|
+
brbState.handleServerBrbUpdate(false);
|
|
59
|
+
await testUtils.flushPromises();
|
|
60
|
+
|
|
61
|
+
assert.isFalse(brbState.state.client.enabled);
|
|
62
|
+
assert.isFalse(brbState.state.server.enabled);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('does not send local brb state to server if it is not a multistream meeting', async () => {
|
|
66
|
+
meeting.isMultistream = false;
|
|
67
|
+
brbState.enable(true, meeting.sendSlotManager);
|
|
68
|
+
brbState.handleServerBrbUpdate(true);
|
|
69
|
+
await testUtils.flushPromises();
|
|
70
|
+
|
|
71
|
+
assert.isTrue(meeting.meetingRequest.setBrb.notCalled);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('does not send local brb state to server if webrtc media connection is not defined', async () => {
|
|
75
|
+
meeting.mediaProperties.webrtcMediaConnection = undefined;
|
|
76
|
+
brbState.enable(true, meeting.sendSlotManager);
|
|
77
|
+
brbState.handleServerBrbUpdate(true);
|
|
78
|
+
await testUtils.flushPromises();
|
|
79
|
+
|
|
80
|
+
assert.isTrue(meeting.meetingRequest.setBrb.notCalled);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('does not send request twice when in progress', async () => {
|
|
84
|
+
brbState.state.syncToServerInProgress = true;
|
|
85
|
+
brbState.enable(true, meeting.sendSlotManager);
|
|
86
|
+
await testUtils.flushPromises();
|
|
87
|
+
|
|
88
|
+
assert.isTrue(meeting.meetingRequest.setBrb.notCalled);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('syncs with server when client state does not match server state', async () => {
|
|
92
|
+
brbState.enable(true, meeting.sendSlotManager);
|
|
93
|
+
brbState.handleServerBrbUpdate(true);
|
|
94
|
+
await testUtils.flushPromises();
|
|
95
|
+
|
|
96
|
+
assert.isTrue(meeting.meetingRequest.setBrb.calledOnce);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('sets source state override when client state does not match server state', async () => {
|
|
100
|
+
brbState.enable(true, meeting.sendSlotManager);
|
|
101
|
+
brbState.handleServerBrbUpdate(true);
|
|
102
|
+
await testUtils.flushPromises();
|
|
103
|
+
|
|
104
|
+
assert.isTrue(meeting.sendSlotManager.setSourceStateOverride.calledOnce);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('handles server update', async () => {
|
|
108
|
+
brbState.handleServerBrbUpdate(true);
|
|
109
|
+
await testUtils.flushPromises();
|
|
110
|
+
|
|
111
|
+
assert.isTrue(brbState.state.server.enabled);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -114,6 +114,7 @@ import {ERROR_DESCRIPTIONS} from '@webex/internal-plugin-metrics/src/call-diagno
|
|
|
114
114
|
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
115
115
|
|
|
116
116
|
import {EVENT_TRIGGERS as VOICEAEVENTS} from '@webex/internal-plugin-voicea';
|
|
117
|
+
import { createBrbState } from '@webex/plugin-meetings/src/meeting/brbState';
|
|
117
118
|
import JoinForbiddenError from '../../../../src/common/errors/join-forbidden-error';
|
|
118
119
|
|
|
119
120
|
describe('plugin-meetings', () => {
|
|
@@ -3812,7 +3813,6 @@ describe('plugin-meetings', () => {
|
|
|
3812
3813
|
};
|
|
3813
3814
|
|
|
3814
3815
|
beforeEach(() => {
|
|
3815
|
-
meeting.meetingRequest.setBrb = sinon.stub().resolves({body: 'test'});
|
|
3816
3816
|
meeting.mediaProperties.webrtcMediaConnection = {createSendSlot: sinon.stub()};
|
|
3817
3817
|
meeting.sendSlotManager.createSlot(
|
|
3818
3818
|
fakeMultistreamRoapMediaConnection,
|
|
@@ -3822,6 +3822,8 @@ describe('plugin-meetings', () => {
|
|
|
3822
3822
|
meeting.locusUrl = 'locus url';
|
|
3823
3823
|
meeting.deviceUrl = 'device url';
|
|
3824
3824
|
meeting.selfId = 'self id';
|
|
3825
|
+
meeting.brbState = createBrbState(meeting, false);
|
|
3826
|
+
meeting.brbState.enable = sinon.stub().resolves();
|
|
3825
3827
|
});
|
|
3826
3828
|
|
|
3827
3829
|
afterEach(() => {
|
|
@@ -3843,7 +3845,7 @@ describe('plugin-meetings', () => {
|
|
|
3843
3845
|
|
|
3844
3846
|
await brbResult;
|
|
3845
3847
|
assert.exists(brbResult.then);
|
|
3846
|
-
assert.calledOnce(meeting.
|
|
3848
|
+
assert.calledOnce(meeting.brbState.enable);
|
|
3847
3849
|
})
|
|
3848
3850
|
|
|
3849
3851
|
it('should disable #beRightBack and return a promise', async () => {
|
|
@@ -3851,12 +3853,12 @@ describe('plugin-meetings', () => {
|
|
|
3851
3853
|
|
|
3852
3854
|
await brbResult;
|
|
3853
3855
|
assert.exists(brbResult.then);
|
|
3854
|
-
assert.calledOnce(meeting.
|
|
3856
|
+
assert.calledOnce(meeting.brbState.enable);
|
|
3855
3857
|
})
|
|
3856
3858
|
|
|
3857
3859
|
it('should throw an error and reject the promise if setBrb fails', async () => {
|
|
3858
3860
|
const error = new Error('setBrb failed');
|
|
3859
|
-
meeting.
|
|
3861
|
+
meeting.brbState.enable.rejects(error);
|
|
3860
3862
|
|
|
3861
3863
|
try {
|
|
3862
3864
|
await meeting.beRightBack(true);
|
|
@@ -3867,27 +3869,6 @@ describe('plugin-meetings', () => {
|
|
|
3867
3869
|
}
|
|
3868
3870
|
})
|
|
3869
3871
|
});
|
|
3870
|
-
|
|
3871
|
-
describe('when in a transcoded meeting', () => {
|
|
3872
|
-
|
|
3873
|
-
beforeEach(() => {
|
|
3874
|
-
meeting.isMultistream = false;
|
|
3875
|
-
});
|
|
3876
|
-
|
|
3877
|
-
it('should ignore enabling #beRightBack', async () => {
|
|
3878
|
-
meeting.beRightBack(true);
|
|
3879
|
-
|
|
3880
|
-
assert.isRejected((Promise.reject()));
|
|
3881
|
-
assert.notCalled(meeting.meetingRequest.setBrb);
|
|
3882
|
-
})
|
|
3883
|
-
|
|
3884
|
-
it('should ignore disabling #beRightBack', async () => {
|
|
3885
|
-
meeting.beRightBack(false);
|
|
3886
|
-
|
|
3887
|
-
assert.isRejected((Promise.reject()));
|
|
3888
|
-
assert.notCalled(meeting.meetingRequest.setBrb);
|
|
3889
|
-
})
|
|
3890
|
-
});
|
|
3891
3872
|
});
|
|
3892
3873
|
|
|
3893
3874
|
/* This set of tests are like semi-integration tests, they use real MuteState, Media, LocusMediaRequest and Roap classes.
|
|
@@ -9230,6 +9211,7 @@ describe('plugin-meetings', () => {
|
|
|
9230
9211
|
|
|
9231
9212
|
it('listens to the brb state changed event', () => {
|
|
9232
9213
|
const assertBrb = (enabled) => {
|
|
9214
|
+
meeting.brbState = createBrbState(meeting, false);
|
|
9233
9215
|
meeting.locusInfo.emit(
|
|
9234
9216
|
{ function: 'test', file: 'test' },
|
|
9235
9217
|
LOCUSINFO.EVENTS.SELF_MEETING_BRB_CHANGED,
|
|
@@ -13260,7 +13242,7 @@ describe('plugin-meetings', () => {
|
|
|
13260
13242
|
|
|
13261
13243
|
describe('#roapMessageReceived', () => {
|
|
13262
13244
|
it('calls roapMessageReceived on the webrtc media connection', () => {
|
|
13263
|
-
const fakeMessage = {messageType: '
|
|
13245
|
+
const fakeMessage = {messageType: 'ANSWER', sdp: 'fake sdp'};
|
|
13264
13246
|
|
|
13265
13247
|
const getMediaServer = sinon.stub(MeetingsUtil, 'getMediaServer').returns('homer');
|
|
13266
13248
|
|
|
@@ -13298,5 +13280,26 @@ describe('plugin-meetings', () => {
|
|
|
13298
13280
|
|
|
13299
13281
|
assert.notCalled(meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived);
|
|
13300
13282
|
});
|
|
13283
|
+
|
|
13284
|
+
it('does not call getMediaServer for a roap message other than ANSWER', async () => {
|
|
13285
|
+
const fakeMessage = {messageType: 'ERROR', sdp: 'fake sdp'};
|
|
13286
|
+
|
|
13287
|
+
meeting.isMultistream = true;
|
|
13288
|
+
meeting.mediaProperties.webrtcMediaConnection = {
|
|
13289
|
+
roapMessageReceived: sinon.stub(),
|
|
13290
|
+
};
|
|
13291
|
+
meeting.mediaProperties.webrtcMediaConnection.mediaServer = 'linus';
|
|
13292
|
+
|
|
13293
|
+
const getMediaServerStub = sinon.stub(MeetingsUtil, 'getMediaServer').returns('something');
|
|
13294
|
+
|
|
13295
|
+
meeting.roapMessageReceived(fakeMessage);
|
|
13296
|
+
|
|
13297
|
+
assert.calledOnceWithExactly(
|
|
13298
|
+
meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived,
|
|
13299
|
+
fakeMessage
|
|
13300
|
+
);
|
|
13301
|
+
assert.notCalled(getMediaServerStub);
|
|
13302
|
+
assert.equal(meeting.mediaProperties.webrtcMediaConnection.mediaServer, 'linus'); // check that it hasn't been overwritten
|
|
13303
|
+
});
|
|
13301
13304
|
});
|
|
13302
13305
|
});
|