@webex/plugin-meetings 2.10.0 → 2.12.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/README.md +4 -0
- package/dist/meeting/index.js +2 -0
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +38 -5
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/members/index.js +24 -1
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +11 -0
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +22 -0
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +8 -1
- package/dist/metrics/constants.js.map +1 -1
- package/package.json +6 -6
- package/src/meeting/index.js +7 -1
- package/src/meeting-info/meeting-info-v2.js +45 -0
- package/src/members/index.js +21 -1
- package/src/members/request.js +10 -0
- package/src/members/util.js +21 -0
- package/src/metrics/constants.js +8 -1
- package/test/unit/spec/meeting/index.js +15 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +19 -0
- package/test/unit/spec/members/index.js +112 -13
- package/test/unit/spec/members/request.js +70 -1
- package/test/unit/spec/members/utils.js +39 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"contributors": [
|
|
@@ -24,19 +24,19 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime-corejs2": "^7.14.8",
|
|
27
|
-
"@webex/webex-core": "2.
|
|
28
|
-
"@webex/internal-plugin-mercury": "2.
|
|
29
|
-
"@webex/internal-plugin-conversation": "2.
|
|
27
|
+
"@webex/webex-core": "2.12.0",
|
|
28
|
+
"@webex/internal-plugin-mercury": "2.12.0",
|
|
29
|
+
"@webex/internal-plugin-conversation": "2.12.0",
|
|
30
30
|
"webrtc-adapter": "^7.7.0",
|
|
31
31
|
"lodash": "^4.17.21",
|
|
32
32
|
"uuid": "^3.3.2",
|
|
33
33
|
"global": "^4.4.0",
|
|
34
34
|
"ip-anonymize": "^0.1.0",
|
|
35
|
-
"@webex/common": "2.
|
|
35
|
+
"@webex/common": "2.12.0",
|
|
36
36
|
"bowser": "^2.11.0",
|
|
37
37
|
"sdp-transform": "^2.12.0",
|
|
38
38
|
"readable-stream": "^3.6.0",
|
|
39
|
-
"@webex/common-timers": "2.
|
|
39
|
+
"@webex/common-timers": "2.12.0",
|
|
40
40
|
"btoa": "^1.2.1",
|
|
41
41
|
"@webex/internal-media-core": "^0.0.4-beta",
|
|
42
42
|
"javascript-state-machine": "^3.1.0",
|
package/src/meeting/index.js
CHANGED
|
@@ -1023,7 +1023,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1023
1023
|
return this.fetchMeetingInfo({
|
|
1024
1024
|
password, captchaCode
|
|
1025
1025
|
})
|
|
1026
|
-
.then(() =>
|
|
1026
|
+
.then(() => {
|
|
1027
|
+
Metrics.sendBehavioralMetric(
|
|
1028
|
+
BEHAVIORAL_METRICS.VERIFY_PASSWORD_SUCCESS
|
|
1029
|
+
);
|
|
1030
|
+
|
|
1031
|
+
return {isPasswordValid: true, requiredCaptcha: null, failureReason: MEETING_INFO_FAILURE_REASON.NONE};
|
|
1032
|
+
})
|
|
1027
1033
|
.catch((error) => {
|
|
1028
1034
|
if (error instanceof PasswordError || error instanceof CaptchaError) {
|
|
1029
1035
|
return {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import {HTTP_VERBS, _CONVERSATION_URL_} from '../constants';
|
|
3
|
+
import Metrics from '../metrics';
|
|
4
|
+
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
3
5
|
|
|
4
6
|
import MeetingInfoUtil from './utilv2';
|
|
5
7
|
|
|
@@ -141,6 +143,10 @@ export default class MeetingInfoV2 {
|
|
|
141
143
|
const uri = this.webex.meetings.preferredWebexSite ?
|
|
142
144
|
`https://${this.webex.meetings.preferredWebexSite}/wbxappapi/v2/meetings/spaceInstant` : '';
|
|
143
145
|
|
|
146
|
+
Metrics.sendBehavioralMetric(
|
|
147
|
+
BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS
|
|
148
|
+
);
|
|
149
|
+
|
|
144
150
|
return this.webex.request({
|
|
145
151
|
method: HTTP_VERBS.POST,
|
|
146
152
|
uri,
|
|
@@ -149,6 +155,16 @@ export default class MeetingInfoV2 {
|
|
|
149
155
|
.catch((err) => {
|
|
150
156
|
throw new MeetingInfoV2AdhocMeetingError(err.body?.code, err.body?.message);
|
|
151
157
|
});
|
|
158
|
+
})
|
|
159
|
+
.catch((err) => {
|
|
160
|
+
Metrics.sendBehavioralMetric(
|
|
161
|
+
BEHAVIORAL_METRICS.ADHOC_MEETING_FAILURE,
|
|
162
|
+
{
|
|
163
|
+
reason: err.message,
|
|
164
|
+
stack: err.stack
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
throw new MeetingInfoV2AdhocMeetingError(err.body?.code, err.body?.message);
|
|
152
168
|
});
|
|
153
169
|
}
|
|
154
170
|
|
|
@@ -189,11 +205,32 @@ export default class MeetingInfoV2 {
|
|
|
189
205
|
if (directURI) options.directURI = directURI;
|
|
190
206
|
|
|
191
207
|
return this.webex.request(options)
|
|
208
|
+
.then(() => {
|
|
209
|
+
Metrics.sendBehavioralMetric(
|
|
210
|
+
BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_SUCCESS
|
|
211
|
+
);
|
|
212
|
+
})
|
|
192
213
|
.catch((err) => {
|
|
193
214
|
if (err?.statusCode === 403) {
|
|
215
|
+
Metrics.sendBehavioralMetric(
|
|
216
|
+
BEHAVIORAL_METRICS.VERIFY_PASSWORD_ERROR,
|
|
217
|
+
{
|
|
218
|
+
reason: err.message,
|
|
219
|
+
stack: err.stack
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
|
|
194
223
|
throw new MeetingInfoV2PasswordError(err.body?.code, err.body?.data?.meetingInfo);
|
|
195
224
|
}
|
|
196
225
|
if (err?.statusCode === 423) {
|
|
226
|
+
Metrics.sendBehavioralMetric(
|
|
227
|
+
BEHAVIORAL_METRICS.VERIFY_CAPTCHA_ERROR,
|
|
228
|
+
{
|
|
229
|
+
reason: err.message,
|
|
230
|
+
stack: err.stack
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
|
|
197
234
|
throw new MeetingInfoV2CaptchaError(err.body?.code, {
|
|
198
235
|
captchaId: err.body.captchaID,
|
|
199
236
|
verificationImageURL: err.body.verificationImageURL,
|
|
@@ -201,6 +238,14 @@ export default class MeetingInfoV2 {
|
|
|
201
238
|
refreshURL: err.body.refreshURL
|
|
202
239
|
});
|
|
203
240
|
}
|
|
241
|
+
|
|
242
|
+
Metrics.sendBehavioralMetric(
|
|
243
|
+
BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_FAILURE,
|
|
244
|
+
{
|
|
245
|
+
reason: err.message,
|
|
246
|
+
stack: err.stack
|
|
247
|
+
}
|
|
248
|
+
);
|
|
204
249
|
throw err;
|
|
205
250
|
});
|
|
206
251
|
}
|
package/src/members/index.js
CHANGED
|
@@ -756,9 +756,29 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
756
756
|
}
|
|
757
757
|
const options = MembersUtil.generateRaiseHandMemberOptions(memberId, raise, this.locusUrl);
|
|
758
758
|
|
|
759
|
-
return this.membersRequest.
|
|
759
|
+
return this.membersRequest.raiseOrLowerHandMember(options);
|
|
760
760
|
}
|
|
761
761
|
|
|
762
|
+
/**
|
|
763
|
+
* Lower all hands of members in a meeting
|
|
764
|
+
* @param {String} requestingMemberId - id of the participant which requested the lower all hands
|
|
765
|
+
* @returns {Promise}
|
|
766
|
+
* @public
|
|
767
|
+
* @memberof Members
|
|
768
|
+
*/
|
|
769
|
+
lowerAllHands(requestingMemberId) {
|
|
770
|
+
if (!this.locusUrl) {
|
|
771
|
+
return Promise.reject(new ParameterError('The associated locus url for this meetings members object must be defined.'));
|
|
772
|
+
}
|
|
773
|
+
if (!requestingMemberId) {
|
|
774
|
+
return Promise.reject(new ParameterError('The requestingMemberId must be defined to lower all hands in a meeting.'));
|
|
775
|
+
}
|
|
776
|
+
const options = MembersUtil.generateLowerAllHandsMemberOptions(requestingMemberId, this.locusUrl);
|
|
777
|
+
|
|
778
|
+
return this.membersRequest.lowerAllHandsMember(options);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
|
|
762
782
|
/**
|
|
763
783
|
* Transfers the host to another member
|
|
764
784
|
* @param {String} memberId
|
package/src/members/request.js
CHANGED
|
@@ -74,6 +74,16 @@ export default class MembersRequest extends StatelessWebexPlugin {
|
|
|
74
74
|
return this.request(requestParams);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
lowerAllHandsMember(options) {
|
|
78
|
+
if (!options || !options.locusUrl || !options.requestingParticipantId) {
|
|
79
|
+
throw new ParameterError('requestingParticipantId must be defined, and the associated locus url for this meeting object must be defined.');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const requestParams = MembersUtil.getLowerAllHandsMemberRequestParams(options);
|
|
83
|
+
|
|
84
|
+
return this.request(requestParams);
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
transferHostToMember(options) {
|
|
78
88
|
if (!options || !options.locusUrl || !options.memberId || !options.moderator) {
|
|
79
89
|
throw new ParameterError('memberId must be defined, the associated locus url, and the moderator for this meeting object must be defined.');
|
package/src/members/util.js
CHANGED
|
@@ -136,6 +136,11 @@ MembersUtil.generateRaiseHandMemberOptions = (memberId, status, locusUrl) => ({
|
|
|
136
136
|
locusUrl
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
+
MembersUtil.generateLowerAllHandsMemberOptions = (requestingParticipantId, locusUrl) => ({
|
|
140
|
+
requestingParticipantId,
|
|
141
|
+
locusUrl
|
|
142
|
+
});
|
|
143
|
+
|
|
139
144
|
MembersUtil.getMuteMemberRequestParams = (options) => {
|
|
140
145
|
const body = {
|
|
141
146
|
audio: {
|
|
@@ -166,6 +171,22 @@ MembersUtil.getRaiseHandMemberRequestParams = (options) => {
|
|
|
166
171
|
};
|
|
167
172
|
};
|
|
168
173
|
|
|
174
|
+
MembersUtil.getLowerAllHandsMemberRequestParams = (options) => {
|
|
175
|
+
const body = {
|
|
176
|
+
hand: {
|
|
177
|
+
raised: false
|
|
178
|
+
},
|
|
179
|
+
requestingParticipantId: options.requestingParticipantId
|
|
180
|
+
};
|
|
181
|
+
const uri = `${options.locusUrl}/${CONTROLS}`;
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
method: HTTP_VERBS.PATCH,
|
|
185
|
+
uri,
|
|
186
|
+
body
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
|
|
169
190
|
MembersUtil.getTransferHostToMemberRequestParams = (options) => {
|
|
170
191
|
const body = {
|
|
171
192
|
role: {
|
package/src/metrics/constants.js
CHANGED
|
@@ -44,7 +44,14 @@ const BEHAVIORAL_METRICS = {
|
|
|
44
44
|
ENABLE_BNR_SUCCESS: 'js_sdk_enable_bnr_success',
|
|
45
45
|
ENABLE_BNR_FAILURE: 'js_sdk_enable_bnr_failure',
|
|
46
46
|
DISABLE_BNR_SUCCESS: 'js_sdk_disable_bnr_success',
|
|
47
|
-
DISABLE_BNR_FAILURE: 'js_sdk_disable_bnr_failure'
|
|
47
|
+
DISABLE_BNR_FAILURE: 'js_sdk_disable_bnr_failure',
|
|
48
|
+
FETCH_MEETING_INFO_V1_SUCCESS: 'js_sdk_fetch_meeting_info_v1_success',
|
|
49
|
+
FETCH_MEETING_INFO_V1_FAILURE: 'js_sdk_fetch_meeting_info_v1_failure',
|
|
50
|
+
ADHOC_MEETING_SUCCESS: 'js_sdk_adhoc_meeting_success',
|
|
51
|
+
ADHOC_MEETING_FAILURE: 'js_sdk_adhoc_meeting_failure',
|
|
52
|
+
VERIFY_PASSWORD_SUCCESS: 'js_sdk_verify_password_success',
|
|
53
|
+
VERIFY_PASSWORD_ERROR: 'js_sdk_verify_password_error',
|
|
54
|
+
VERIFY_CAPTCHA_ERROR: 'js_sdk_verify_captcha_error'
|
|
48
55
|
};
|
|
49
56
|
|
|
50
57
|
|
|
@@ -2366,6 +2366,11 @@ describe('plugin-meetings', () => {
|
|
|
2366
2366
|
assert.equal(meeting.requiredCaptcha, null);
|
|
2367
2367
|
assert.calledTwice(TriggerProxy.trigger);
|
|
2368
2368
|
assert.calledWith(TriggerProxy.trigger, meeting, {file: 'meetings', function: 'fetchMeetingInfo'}, 'meeting:meetingInfoAvailable');
|
|
2369
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
2370
|
+
assert.calledWith(
|
|
2371
|
+
Metrics.sendBehavioralMetric,
|
|
2372
|
+
BEHAVIORAL_METRICS.VERIFY_PASSWORD_SUCCESS,
|
|
2373
|
+
);
|
|
2369
2374
|
});
|
|
2370
2375
|
|
|
2371
2376
|
it('calls meetingInfoProvider with all the right parameters and parses the result when random delay is applied', async () => {
|
|
@@ -2437,6 +2442,11 @@ describe('plugin-meetings', () => {
|
|
|
2437
2442
|
|
|
2438
2443
|
assert.calledWith(meeting.attrs.meetingInfoProvider.fetchMeetingInfo, FAKE_DESTINATION, FAKE_TYPE, null, null);
|
|
2439
2444
|
|
|
2445
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
2446
|
+
assert.calledWith(
|
|
2447
|
+
Metrics.sendBehavioralMetric,
|
|
2448
|
+
BEHAVIORAL_METRICS.VERIFY_PASSWORD_ERROR,
|
|
2449
|
+
);
|
|
2440
2450
|
assert.deepEqual(meeting.meetingInfo, FAKE_MEETING_INFO);
|
|
2441
2451
|
assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD);
|
|
2442
2452
|
assert.equal(meeting.requiredCaptcha, null);
|
|
@@ -2457,6 +2467,11 @@ describe('plugin-meetings', () => {
|
|
|
2457
2467
|
|
|
2458
2468
|
assert.calledWith(meeting.attrs.meetingInfoProvider.fetchMeetingInfo, FAKE_DESTINATION, FAKE_TYPE, 'aaa', null);
|
|
2459
2469
|
|
|
2470
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
2471
|
+
assert.calledWith(
|
|
2472
|
+
Metrics.sendBehavioralMetric,
|
|
2473
|
+
BEHAVIORAL_METRICS.VERIFY_CAPTCHA_ERROR,
|
|
2474
|
+
);
|
|
2460
2475
|
assert.deepEqual(meeting.meetingInfo, {});
|
|
2461
2476
|
assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD);
|
|
2462
2477
|
assert.equal(meeting.passwordStatus, PASSWORD_STATUS.REQUIRED);
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
} from '@webex/plugin-meetings/src/constants';
|
|
17
17
|
import MeetingInfo, {MeetingInfoV2PasswordError, MeetingInfoV2CaptchaError, MeetingInfoV2AdhocMeetingError} from '@webex/plugin-meetings/src/meeting-info/meeting-info-v2';
|
|
18
18
|
import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
|
|
19
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
20
|
+
import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
|
|
19
21
|
|
|
20
22
|
describe('plugin-meetings', () => {
|
|
21
23
|
const conversation = {
|
|
@@ -42,6 +44,13 @@ describe('plugin-meetings', () => {
|
|
|
42
44
|
let webex;
|
|
43
45
|
let meetingInfo = null;
|
|
44
46
|
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
49
|
+
});
|
|
50
|
+
afterEach(() => {
|
|
51
|
+
sinon.restore();
|
|
52
|
+
});
|
|
53
|
+
|
|
45
54
|
describe('Meeting Info V2', () => {
|
|
46
55
|
beforeEach(() => {
|
|
47
56
|
webex = new MockWebex({
|
|
@@ -125,6 +134,11 @@ describe('plugin-meetings', () => {
|
|
|
125
134
|
captchaVerifyCode: 'aabbcc11'
|
|
126
135
|
}
|
|
127
136
|
});
|
|
137
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
138
|
+
assert.calledWith(
|
|
139
|
+
Metrics.sendBehavioralMetric,
|
|
140
|
+
BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_SUCCESS,
|
|
141
|
+
);
|
|
128
142
|
});
|
|
129
143
|
|
|
130
144
|
it('create adhoc meeting when conversationUrl passed with enableAdhocMeetings toggle', async () => {
|
|
@@ -254,6 +268,11 @@ describe('plugin-meetings', () => {
|
|
|
254
268
|
invitees: invitee
|
|
255
269
|
}
|
|
256
270
|
});
|
|
271
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
272
|
+
assert.calledWith(
|
|
273
|
+
Metrics.sendBehavioralMetric,
|
|
274
|
+
BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS,
|
|
275
|
+
);
|
|
257
276
|
});
|
|
258
277
|
});
|
|
259
278
|
});
|
|
@@ -10,8 +10,9 @@ import chaiAsPromised from 'chai-as-promised';
|
|
|
10
10
|
import {Credentials} from '@webex/webex-core';
|
|
11
11
|
import Support from '@webex/internal-plugin-support';
|
|
12
12
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
13
|
-
import Meetings from '@webex/plugin-meetings';
|
|
14
13
|
|
|
14
|
+
import Meetings from '@webex/plugin-meetings';
|
|
15
|
+
import ParameterError from '@webex/plugin-meetings/src/common/errors/parameter';
|
|
15
16
|
import Members from '@webex/plugin-meetings/src/members';
|
|
16
17
|
import MembersUtil from '@webex/plugin-meetings/src/members/util';
|
|
17
18
|
|
|
@@ -191,25 +192,123 @@ describe('plugin-meetings', () => {
|
|
|
191
192
|
});
|
|
192
193
|
});
|
|
193
194
|
|
|
194
|
-
describe('#
|
|
195
|
-
|
|
196
|
-
const members = createMembers({url:
|
|
195
|
+
describe('#raiseOrLowerHand', () => {
|
|
196
|
+
const setup = (locusUrl) => {
|
|
197
|
+
const members = createMembers({url: locusUrl});
|
|
197
198
|
|
|
198
|
-
const
|
|
199
|
+
const spies = {
|
|
200
|
+
generateRaiseHandMemberOptions: sandbox.spy(MembersUtil, 'generateRaiseHandMemberOptions'),
|
|
201
|
+
raiseOrLowerHandMember: sandbox.spy(members.membersRequest, 'raiseOrLowerHandMember'),
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
return {members, spies};
|
|
205
|
+
};
|
|
199
206
|
|
|
200
|
-
|
|
201
|
-
|
|
207
|
+
const checkInvalid = async (resultPromise, expectedMessage, spies) => {
|
|
208
|
+
await assert.isRejected(resultPromise, ParameterError, expectedMessage);
|
|
209
|
+
assert.notCalled(spies.generateRaiseHandMemberOptions);
|
|
210
|
+
assert.notCalled(spies.raiseOrLowerHandMember);
|
|
211
|
+
};
|
|
202
212
|
|
|
203
|
-
|
|
213
|
+
const checkValid = async (resultPromise, spies, expectedMemberId, expectedRaise, expectedLocusUrl) => {
|
|
214
|
+
await assert.isFulfilled(resultPromise);
|
|
215
|
+
assert.calledOnceWithExactly(spies.generateRaiseHandMemberOptions, expectedMemberId, expectedRaise, expectedLocusUrl);
|
|
216
|
+
assert.calledOnceWithExactly(spies.raiseOrLowerHandMember, {memberId: expectedMemberId, raised: expectedRaise, locusUrl: expectedLocusUrl});
|
|
217
|
+
assert.strictEqual(resultPromise, spies.raiseOrLowerHandMember.getCall(0).returnValue);
|
|
218
|
+
};
|
|
204
219
|
|
|
205
|
-
|
|
206
|
-
|
|
220
|
+
it('should not make a request if there is no member id', async () => {
|
|
221
|
+
const {members, spies} = setup(url1);
|
|
222
|
+
|
|
223
|
+
const resultPromise = members.raiseOrLowerHand();
|
|
224
|
+
|
|
225
|
+
await checkInvalid(resultPromise, 'The member id must be defined to raise/lower the hand of the member.', spies);
|
|
207
226
|
});
|
|
208
227
|
|
|
209
|
-
it('should
|
|
210
|
-
const members =
|
|
228
|
+
it('should not make a request if there is no locus url', async () => {
|
|
229
|
+
const {members, spies} = setup();
|
|
230
|
+
|
|
231
|
+
const resultPromise = members.raiseOrLowerHand(uuid.v4());
|
|
232
|
+
|
|
233
|
+
await checkInvalid(resultPromise, 'The associated locus url for this meetings members object must be defined.', spies);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('should make the correct request when called with raise as true', async () => {
|
|
237
|
+
const memberId = uuid.v4();
|
|
238
|
+
const {members, spies} = setup(url1);
|
|
239
|
+
|
|
240
|
+
const resultPromise = members.raiseOrLowerHand(memberId, true);
|
|
241
|
+
|
|
242
|
+
await checkValid(resultPromise, spies, memberId, true, url1);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('should make the correct request when called with raise as false', async () => {
|
|
246
|
+
const memberId = uuid.v4();
|
|
247
|
+
const {members, spies} = setup(url1);
|
|
248
|
+
|
|
249
|
+
const resultPromise = members.raiseOrLowerHand(memberId, false);
|
|
250
|
+
|
|
251
|
+
await checkValid(resultPromise, spies, memberId, false, url1);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should make the correct request when called with raise as default', async () => {
|
|
255
|
+
const memberId = uuid.v4();
|
|
256
|
+
const {members, spies} = setup(url1);
|
|
257
|
+
|
|
258
|
+
const resultPromise = members.raiseOrLowerHand(memberId);
|
|
259
|
+
|
|
260
|
+
await checkValid(resultPromise, spies, memberId, true, url1);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe('#lowerAllHands', () => {
|
|
265
|
+
const setup = (locusUrl) => {
|
|
266
|
+
const members = createMembers({url: locusUrl});
|
|
267
|
+
|
|
268
|
+
const spies = {
|
|
269
|
+
generateLowerAllHandsMemberOptions: sandbox.spy(MembersUtil, 'generateLowerAllHandsMemberOptions'),
|
|
270
|
+
lowerAllHandsMember: sandbox.spy(members.membersRequest, 'lowerAllHandsMember'),
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
return {members, spies};
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const checkInvalid = async (resultPromise, expectedMessage, spies) => {
|
|
277
|
+
await assert.isRejected(resultPromise, ParameterError, expectedMessage);
|
|
278
|
+
assert.notCalled(spies.generateLowerAllHandsMemberOptions);
|
|
279
|
+
assert.notCalled(spies.lowerAllHandsMember);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
const checkValid = async (resultPromise, spies, expectedRequestingMemberId, expectedLocusUrl) => {
|
|
283
|
+
await assert.isFulfilled(resultPromise);
|
|
284
|
+
assert.calledOnceWithExactly(spies.generateLowerAllHandsMemberOptions, expectedRequestingMemberId, expectedLocusUrl);
|
|
285
|
+
assert.calledOnceWithExactly(spies.lowerAllHandsMember, {requestingParticipantId: expectedRequestingMemberId, locusUrl: expectedLocusUrl});
|
|
286
|
+
assert.strictEqual(resultPromise, spies.lowerAllHandsMember.getCall(0).returnValue);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
it('should not make a request if there is no requestingMemberId', async () => {
|
|
290
|
+
const {members, spies} = setup(url1);
|
|
291
|
+
|
|
292
|
+
const resultPromise = members.lowerAllHands();
|
|
293
|
+
|
|
294
|
+
await checkInvalid(resultPromise, 'The requestingMemberId must be defined to lower all hands in a meeting.', spies);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should not make a request if there is no locus url', async () => {
|
|
298
|
+
const {members, spies} = setup();
|
|
299
|
+
|
|
300
|
+
const resultPromise = members.lowerAllHands(uuid.v4());
|
|
301
|
+
|
|
302
|
+
await checkInvalid(resultPromise, 'The associated locus url for this meetings members object must be defined.', spies);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('should make the correct request when called with requestingMemberId', async () => {
|
|
306
|
+
const requestingMemberId = uuid.v4();
|
|
307
|
+
const {members, spies} = setup(url1);
|
|
308
|
+
|
|
309
|
+
const resultPromise = members.lowerAllHands(requestingMemberId);
|
|
211
310
|
|
|
212
|
-
|
|
311
|
+
await checkValid(resultPromise, spies, requestingMemberId, url1);
|
|
213
312
|
});
|
|
214
313
|
});
|
|
215
314
|
});
|
|
@@ -3,9 +3,11 @@ import chai from 'chai';
|
|
|
3
3
|
import uuid from 'uuid';
|
|
4
4
|
import chaiAsPromised from 'chai-as-promised';
|
|
5
5
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
6
|
-
import Meetings from '@webex/plugin-meetings';
|
|
7
6
|
|
|
7
|
+
import Meetings from '@webex/plugin-meetings';
|
|
8
8
|
import MembersRequest from '@webex/plugin-meetings/src/members/request';
|
|
9
|
+
import membersUtil from '@webex/plugin-meetings/src/members/util';
|
|
10
|
+
import ParameterError from '@webex/plugin-meetings/src/common/errors/parameter';
|
|
9
11
|
|
|
10
12
|
const {assert} = chai;
|
|
11
13
|
|
|
@@ -118,5 +120,72 @@ describe('plugin-meetings', () => {
|
|
|
118
120
|
assert.equal(requestParams.body.hand.raised, true);
|
|
119
121
|
});
|
|
120
122
|
});
|
|
123
|
+
|
|
124
|
+
describe('#lowerAllHands', () => {
|
|
125
|
+
const parameterErrorMessage = 'requestingParticipantId must be defined, and the associated locus url for this meeting object must be defined.';
|
|
126
|
+
|
|
127
|
+
const checkInvalid = async (functionParams) => {
|
|
128
|
+
assert.throws(() => membersRequest.lowerAllHandsMember(functionParams), ParameterError, parameterErrorMessage);
|
|
129
|
+
assert(membersRequest.request.notCalled);
|
|
130
|
+
assert(membersUtil.getLowerAllHandsMemberRequestParams.notCalled);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
it('rejects if no options are passed in', async () => {
|
|
134
|
+
checkInvalid();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('rejects if no locusUrl are passed in', async () => {
|
|
138
|
+
checkInvalid({requestingParticipantId: 'test'});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('rejects if no requestingParticipantId are passed in', async () => {
|
|
142
|
+
checkInvalid({locusUrl: 'test'});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('returns a promise', async () => {
|
|
146
|
+
const locusUrl = url1;
|
|
147
|
+
const memberId = 'test1';
|
|
148
|
+
|
|
149
|
+
const options = {
|
|
150
|
+
requestingParticipantId: memberId,
|
|
151
|
+
locusUrl,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
assert.strictEqual(membersRequest.lowerAllHandsMember(options), membersRequest.request.getCall(0).returnValue);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('sends a PATCH to the locus endpoint', async () => {
|
|
158
|
+
const locusUrl = url1;
|
|
159
|
+
const memberId = 'test1';
|
|
160
|
+
|
|
161
|
+
const options = {
|
|
162
|
+
requestingParticipantId: memberId,
|
|
163
|
+
locusUrl,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
const getRequestParamsSpy = sandbox.spy(membersUtil, 'getLowerAllHandsMemberRequestParams');
|
|
168
|
+
|
|
169
|
+
await membersRequest.lowerAllHandsMember(options);
|
|
170
|
+
|
|
171
|
+
assert.calledOnceWithExactly(getRequestParamsSpy, {
|
|
172
|
+
requestingParticipantId: memberId,
|
|
173
|
+
locusUrl: url1
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const requestParams = membersRequest.request.getCall(0).args[0];
|
|
177
|
+
|
|
178
|
+
assert.deepEqual(requestParams, {
|
|
179
|
+
method: 'PATCH',
|
|
180
|
+
uri: `${locusUrl}/controls`,
|
|
181
|
+
body: {
|
|
182
|
+
hand: {
|
|
183
|
+
raised: false
|
|
184
|
+
},
|
|
185
|
+
requestingParticipantId: memberId
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
});
|
|
121
190
|
});
|
|
122
191
|
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import chai from 'chai';
|
|
3
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
4
|
+
|
|
5
|
+
import MembersUtil from '@webex/plugin-meetings/src/members/util';
|
|
6
|
+
|
|
7
|
+
const {assert} = chai;
|
|
8
|
+
|
|
9
|
+
chai.use(chaiAsPromised);
|
|
10
|
+
sinon.assert.expose(chai.assert, {prefix: ''});
|
|
11
|
+
|
|
12
|
+
describe('plugin-meetings', () => {
|
|
13
|
+
describe('members utils library', () => {
|
|
14
|
+
describe('#generateRaiseHandMemberOptions', () => {
|
|
15
|
+
it('returns the correct options', () => {
|
|
16
|
+
const memberId = 'test';
|
|
17
|
+
const status = true;
|
|
18
|
+
const locusUrl = 'urlTest1';
|
|
19
|
+
|
|
20
|
+
assert.deepEqual(MembersUtil.generateRaiseHandMemberOptions(memberId, status, locusUrl), {
|
|
21
|
+
memberId,
|
|
22
|
+
raised: status,
|
|
23
|
+
locusUrl
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('#generateLowerAllHandsMemberOptions', () => {
|
|
28
|
+
it('returns the correct options', () => {
|
|
29
|
+
const requestingParticipantId = 'test';
|
|
30
|
+
const locusUrl = 'urlTest1';
|
|
31
|
+
|
|
32
|
+
assert.deepEqual(MembersUtil.generateLowerAllHandsMemberOptions(requestingParticipantId, locusUrl), {
|
|
33
|
+
requestingParticipantId,
|
|
34
|
+
locusUrl
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|