@webex/plugin-meetings 3.12.0-next.82 → 3.12.0-next.84
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/aiEnableRequest/index.js +1 -1
- 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/member/util.js +27 -0
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +93 -42
- package/dist/members/index.js.map +1 -1
- package/dist/types/member/util.d.ts +8 -0
- package/dist/types/members/index.d.ts +12 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +20 -20
- package/src/member/util.ts +26 -0
- package/src/members/index.ts +59 -3
- package/test/unit/spec/member/util.js +65 -0
- package/test/unit/spec/members/index.js +155 -0
|
@@ -699,3 +699,68 @@ describe('extractMediaStatus', () => {
|
|
|
699
699
|
assert.deepEqual(mediaStatus, {audio: 'RECVONLY', video: 'SENDRECV'});
|
|
700
700
|
});
|
|
701
701
|
});
|
|
702
|
+
|
|
703
|
+
describe('MemberUtil.extractCsis', () => {
|
|
704
|
+
it('returns an empty array when participant is undefined', () => {
|
|
705
|
+
assert.deepEqual(MemberUtil.extractCsis(undefined), []);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
it('returns an empty array when participant has no devices', () => {
|
|
709
|
+
assert.deepEqual(MemberUtil.extractCsis({}), []);
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
it('returns an empty array when devices have no csis or mediaSessions', () => {
|
|
713
|
+
const participant = {devices: [{}, {csis: [], mediaSessions: []}]};
|
|
714
|
+
|
|
715
|
+
assert.deepEqual(MemberUtil.extractCsis(participant), []);
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
it('collects CSIs from device.csis arrays', () => {
|
|
719
|
+
const participant = {
|
|
720
|
+
devices: [{csis: [1, 2]}, {csis: [3]}],
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
assert.deepEqual(MemberUtil.extractCsis(participant), [1, 2, 3]);
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
it('collects CSIs from device.mediaSessions[].csi values', () => {
|
|
727
|
+
const participant = {
|
|
728
|
+
devices: [
|
|
729
|
+
{mediaSessions: [{csi: 10}, {csi: 11}]},
|
|
730
|
+
{mediaSessions: [{csi: 12}]},
|
|
731
|
+
],
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
assert.deepEqual(MemberUtil.extractCsis(participant), [10, 11, 12]);
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it('merges CSIs from both csis and mediaSessions, deduplicated', () => {
|
|
738
|
+
const participant = {
|
|
739
|
+
devices: [
|
|
740
|
+
{csis: [1, 2], mediaSessions: [{csi: 2}, {csi: 3}]},
|
|
741
|
+
{csis: [3, 4], mediaSessions: [{csi: 5}]},
|
|
742
|
+
],
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
assert.deepEqual(MemberUtil.extractCsis(participant), [1, 2, 3, 4, 5]);
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
it('ignores non-numeric csi values', () => {
|
|
749
|
+
const participant = {
|
|
750
|
+
devices: [
|
|
751
|
+
{csis: [1, '2', null, undefined]},
|
|
752
|
+
{mediaSessions: [{csi: 'abc'}, {csi: null}, {csi: 3}, {}]},
|
|
753
|
+
],
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
assert.deepEqual(MemberUtil.extractCsis(participant), [1, 3]);
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('skips falsy devices and mediaSessions entries', () => {
|
|
760
|
+
const participant = {
|
|
761
|
+
devices: [null, undefined, {csis: [7], mediaSessions: [null, {csi: 8}, undefined]}],
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
assert.deepEqual(MemberUtil.extractCsis(participant), [7, 8]);
|
|
765
|
+
});
|
|
766
|
+
});
|
|
@@ -322,6 +322,28 @@ describe('plugin-meetings', () => {
|
|
|
322
322
|
);
|
|
323
323
|
sinon.restore();
|
|
324
324
|
});
|
|
325
|
+
|
|
326
|
+
it('should not clear memberIdByHistoryCsi so it survives member removal (e.g. BO entry/exit)', () => {
|
|
327
|
+
const members = createMembers({url: url1});
|
|
328
|
+
members.memberIdByHistoryCsi.set(1000, 'test1');
|
|
329
|
+
members.clearMembers();
|
|
330
|
+
assert.strictEqual(members.memberIdByHistoryCsi.size, 1);
|
|
331
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1000), 'test1');
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("captures the current members' CSIs into memberIdByHistoryCsi before resetting", () => {
|
|
335
|
+
const members = createMembers({url: url1});
|
|
336
|
+
members.membersCollection.setAll({
|
|
337
|
+
m1: {id: 'm1', participant: {devices: [{csis: [1000, 1001]}]}},
|
|
338
|
+
m2: {id: 'm2', participant: {devices: [{csis: [2000]}]}},
|
|
339
|
+
});
|
|
340
|
+
sinon.stub(Trigger, 'trigger');
|
|
341
|
+
members.clearMembers();
|
|
342
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1000), 'm1');
|
|
343
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1001), 'm1');
|
|
344
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(2000), 'm2');
|
|
345
|
+
sinon.restore();
|
|
346
|
+
});
|
|
325
347
|
});
|
|
326
348
|
describe('#locusParticipantsUpdate', () => {
|
|
327
349
|
beforeEach(() => {
|
|
@@ -1165,6 +1187,139 @@ describe('plugin-meetings', () => {
|
|
|
1165
1187
|
it('returns correct member when CSI matches the second device', () => {
|
|
1166
1188
|
assert.strictEqual(members.findMemberByCsi(2001), fakeCollection.oneWithSomeCsis);
|
|
1167
1189
|
});
|
|
1190
|
+
|
|
1191
|
+
it('falls back to memberIdByHistoryCsi when CSI is no longer on the current devices', () => {
|
|
1192
|
+
members.memberIdByHistoryCsi.set(9999, 'oneWithDevicesWithoutCsis');
|
|
1193
|
+
assert.strictEqual(
|
|
1194
|
+
members.findMemberByCsi(9999),
|
|
1195
|
+
fakeCollection.oneWithDevicesWithoutCsis
|
|
1196
|
+
);
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1199
|
+
it('returns undefined when the memberIdByHistoryCsi entry points to a removed member', () => {
|
|
1200
|
+
members.memberIdByHistoryCsi.set(8888, 'not-in-collection');
|
|
1201
|
+
assert.strictEqual(members.findMemberByCsi(8888), undefined);
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1204
|
+
it('prefers a current device match over a memberIdByHistoryCsi match', () => {
|
|
1205
|
+
members.memberIdByHistoryCsi.set(1001, 'oneWithDevicesWithoutCsis');
|
|
1206
|
+
assert.strictEqual(members.findMemberByCsi(1001), fakeCollection.oneWithSomeCsis);
|
|
1207
|
+
});
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
describe('memberIdByHistoryCsi tracking', () => {
|
|
1211
|
+
let members;
|
|
1212
|
+
|
|
1213
|
+
const participantWithCsis = (id, csis) => ({
|
|
1214
|
+
id,
|
|
1215
|
+
type: 'USER',
|
|
1216
|
+
person: {},
|
|
1217
|
+
devices: [{csis}],
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1220
|
+
beforeEach(() => {
|
|
1221
|
+
sinon.stub(Trigger, 'trigger');
|
|
1222
|
+
members = createMembers({url: url1});
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
afterEach(() => {
|
|
1226
|
+
sinon.restore();
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
it('does not populate the map when adding a brand new member', () => {
|
|
1230
|
+
members.locusParticipantsUpdate({
|
|
1231
|
+
participants: [participantWithCsis('m1', [1000])],
|
|
1232
|
+
});
|
|
1233
|
+
assert.strictEqual(members.memberIdByHistoryCsi.size, 0);
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
it('does not populate the map when devices have not changed between updates', () => {
|
|
1237
|
+
const devices = [{csis: [1000]}];
|
|
1238
|
+
|
|
1239
|
+
members.locusParticipantsUpdate({
|
|
1240
|
+
participants: [{id: 'm1', type: 'USER', person: {}, devices}],
|
|
1241
|
+
});
|
|
1242
|
+
members.locusParticipantsUpdate({
|
|
1243
|
+
participants: [{id: 'm1', type: 'USER', person: {}, devices}],
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
assert.strictEqual(members.memberIdByHistoryCsi.size, 0);
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
it('captures previous CSIs into the map when devices change on update', () => {
|
|
1250
|
+
members.locusParticipantsUpdate({
|
|
1251
|
+
participants: [participantWithCsis('m1', [1000, 1001])],
|
|
1252
|
+
});
|
|
1253
|
+
members.locusParticipantsUpdate({
|
|
1254
|
+
participants: [participantWithCsis('m1', [2000])],
|
|
1255
|
+
});
|
|
1256
|
+
|
|
1257
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1000), 'm1');
|
|
1258
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1001), 'm1');
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
it('preserves history when a member is removed and re-added (breakout scenario)', () => {
|
|
1262
|
+
members.locusParticipantsUpdate({
|
|
1263
|
+
participants: [participantWithCsis('m1', [1000])],
|
|
1264
|
+
});
|
|
1265
|
+
// change devices so previous CSIs are captured into history
|
|
1266
|
+
members.locusParticipantsUpdate({
|
|
1267
|
+
participants: [participantWithCsis('m1', [2000])],
|
|
1268
|
+
});
|
|
1269
|
+
// remove the member
|
|
1270
|
+
members.locusParticipantsUpdate({
|
|
1271
|
+
participants: [],
|
|
1272
|
+
removedParticipantIds: ['m1'],
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1000), 'm1');
|
|
1276
|
+
|
|
1277
|
+
// re-add the member with brand new CSIs
|
|
1278
|
+
members.locusParticipantsUpdate({
|
|
1279
|
+
participants: [participantWithCsis('m1', [3000])],
|
|
1280
|
+
});
|
|
1281
|
+
|
|
1282
|
+
const member = members.findMemberByCsi(1000);
|
|
1283
|
+
assert.isDefined(member);
|
|
1284
|
+
assert.strictEqual(member.id, 'm1');
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
it("captures the removed member's current CSIs even without a prior device-change update", () => {
|
|
1288
|
+
// member is added, then removed in the very next delta without any
|
|
1289
|
+
// intermediate device-change update - their current CSIs must still be
|
|
1290
|
+
// captured into the history map on removal
|
|
1291
|
+
members.locusParticipantsUpdate({
|
|
1292
|
+
participants: [participantWithCsis('m1', [1000, 1001])],
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
assert.strictEqual(members.memberIdByHistoryCsi.size, 0);
|
|
1296
|
+
|
|
1297
|
+
members.locusParticipantsUpdate({
|
|
1298
|
+
participants: [],
|
|
1299
|
+
removedParticipantIds: ['m1'],
|
|
1300
|
+
});
|
|
1301
|
+
|
|
1302
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1000), 'm1');
|
|
1303
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1001), 'm1');
|
|
1304
|
+
});
|
|
1305
|
+
|
|
1306
|
+
it('merges existing history with CSIs captured at removal time', () => {
|
|
1307
|
+
members.locusParticipantsUpdate({
|
|
1308
|
+
participants: [participantWithCsis('m1', [1000])],
|
|
1309
|
+
});
|
|
1310
|
+
// device change captures 1000 into history; member now reports 2000
|
|
1311
|
+
members.locusParticipantsUpdate({
|
|
1312
|
+
participants: [participantWithCsis('m1', [2000])],
|
|
1313
|
+
});
|
|
1314
|
+
// removal should additionally capture the member's current CSIs (2000)
|
|
1315
|
+
members.locusParticipantsUpdate({
|
|
1316
|
+
participants: [],
|
|
1317
|
+
removedParticipantIds: ['m1'],
|
|
1318
|
+
});
|
|
1319
|
+
|
|
1320
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(1000), 'm1');
|
|
1321
|
+
assert.strictEqual(members.memberIdByHistoryCsi.get(2000), 'm1');
|
|
1322
|
+
});
|
|
1168
1323
|
});
|
|
1169
1324
|
|
|
1170
1325
|
describe('getCsisForMember()', () => {
|