@webex/plugin-meetings 3.12.0-next.20 → 3.12.0-next.22

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.
@@ -91,6 +91,7 @@ describe('plugin-meetings', () => {
91
91
  locusInfo = {
92
92
  parse: sinon.stub().returns(true),
93
93
  updateMainSessionLocusCache: sinon.stub(),
94
+ syncAllHashTreeDatasets: sinon.stub(),
94
95
  };
95
96
  webex = new MockWebex({
96
97
  children: {
@@ -1391,7 +1392,7 @@ describe('plugin-meetings', () => {
1391
1392
  it('should have #syncMeetings', () => {
1392
1393
  assert.exists(webex.meetings.syncMeetings);
1393
1394
  });
1394
- it('should do nothing and return a resolved promise if unverified guest', async () => {
1395
+ it('should skip getActiveMeetings but still call syncAllHashTreeDatasets if unverified guest', async () => {
1395
1396
  webex.meetings.request.getActiveMeetings = sinon.stub().returns(
1396
1397
  Promise.resolve({
1397
1398
  loci: [
@@ -1404,13 +1405,23 @@ describe('plugin-meetings', () => {
1404
1405
  webex.credentials.isUnverifiedGuest = true;
1405
1406
  LoggerProxy.logger.info = sinon.stub();
1406
1407
 
1408
+ const mockLocusInfo = {
1409
+ syncAllHashTreeDatasets: sinon.stub().resolves(),
1410
+ };
1411
+ webex.meetings.meetingCollection.getAll = sinon.stub().returns({
1412
+ meeting1: {locusInfo: mockLocusInfo},
1413
+ meeting2: {locusInfo: undefined},
1414
+ meeting3: {},
1415
+ });
1416
+
1407
1417
  await webex.meetings.syncMeetings();
1408
1418
 
1409
1419
  assert.notCalled(webex.meetings.request.getActiveMeetings);
1410
1420
  assert.calledWith(
1411
1421
  LoggerProxy.logger.info,
1412
- 'Meetings:index#syncMeetings --> skipping meeting sync as unverified guest'
1422
+ 'Meetings:index#syncMeetings --> user is unverified guest, skipping calling Locus for meeting sync'
1413
1423
  );
1424
+ assert.calledOnce(mockLocusInfo.syncAllHashTreeDatasets);
1414
1425
  });
1415
1426
  describe('succesful requests', () => {
1416
1427
  beforeEach(() => {
@@ -1429,6 +1440,9 @@ describe('plugin-meetings', () => {
1429
1440
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
1430
1441
  locusInfo,
1431
1442
  });
1443
+ webex.meetings.meetingCollection.getAll = sinon.stub().returns({
1444
+ meeting1: {locusInfo, locusUrl: url1},
1445
+ });
1432
1446
  });
1433
1447
  it('tests the sync meeting calls for existing meeting', async () => {
1434
1448
  await webex.meetings.syncMeetings();
@@ -1436,6 +1450,7 @@ describe('plugin-meetings', () => {
1436
1450
  assert.calledOnce(webex.meetings.meetingCollection.getByKey);
1437
1451
  assert.calledOnce(locusInfo.parse);
1438
1452
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1453
+ assert.calledOnce(locusInfo.syncAllHashTreeDatasets);
1439
1454
  });
1440
1455
  });
1441
1456
  describe('when meeting is not returned', () => {
@@ -1520,7 +1535,7 @@ describe('plugin-meetings', () => {
1520
1535
  it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings is not defined', async () => {
1521
1536
  await webex.meetings.syncMeetings();
1522
1537
  assert.calledOnce(webex.meetings.request.getActiveMeetings);
1523
- assert.calledOnce(webex.meetings.meetingCollection.getAll);
1538
+ assert.calledTwice(webex.meetings.meetingCollection.getAll);
1524
1539
  assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
1525
1540
  assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
1526
1541
  assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
@@ -1532,7 +1547,7 @@ describe('plugin-meetings', () => {
1532
1547
  it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings === true', async () => {
1533
1548
  await webex.meetings.syncMeetings({keepOnlyLocusMeetings: true});
1534
1549
  assert.calledOnce(webex.meetings.request.getActiveMeetings);
1535
- assert.calledOnce(webex.meetings.meetingCollection.getAll);
1550
+ assert.calledTwice(webex.meetings.meetingCollection.getAll);
1536
1551
  assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
1537
1552
  assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
1538
1553
  assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
@@ -1544,7 +1559,7 @@ describe('plugin-meetings', () => {
1544
1559
  it('destroy any LOCUS meetings that have no active locus url if keepOnlyLocusMeetings === false', async () => {
1545
1560
  await webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
1546
1561
  assert.calledOnce(webex.meetings.request.getActiveMeetings);
1547
- assert.calledOnce(webex.meetings.meetingCollection.getAll);
1562
+ assert.calledTwice(webex.meetings.meetingCollection.getAll);
1548
1563
  assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
1549
1564
  assert.callCount(destroySpy, 1);
1550
1565
 
@@ -1552,6 +1567,113 @@ describe('plugin-meetings', () => {
1552
1567
  });
1553
1568
  });
1554
1569
  });
1570
+
1571
+ describe('when globalMeetingId preserves breakout meetings', () => {
1572
+ let destroySpy;
1573
+ let cleanUpSpy;
1574
+
1575
+ beforeEach(() => {
1576
+ destroySpy = sinon.spy(webex.meetings, 'destroy');
1577
+ cleanUpSpy = sinon.stub(MeetingUtil, 'cleanUp').returns(Promise.resolve());
1578
+ });
1579
+
1580
+ afterEach(() => {
1581
+ cleanUpSpy.restore();
1582
+ });
1583
+
1584
+ it('should not destroy a meeting whose globalMeetingId matches an active locus', async () => {
1585
+ const meetingCollectionMeetings = {
1586
+ breakoutMeeting: {
1587
+ locusUrl: 'breakout-url',
1588
+ locusInfo: {
1589
+ info: {globalMeetingId: 'gmid-123'},
1590
+ syncAllHashTreeDatasets: sinon.stub().resolves(),
1591
+ },
1592
+ sendCallAnalyzerMetrics: sinon.stub(),
1593
+ },
1594
+ };
1595
+
1596
+ webex.meetings.meetingCollection.getAll = sinon
1597
+ .stub()
1598
+ .returns(meetingCollectionMeetings);
1599
+ webex.meetings.request.getActiveMeetings = sinon.stub().resolves({
1600
+ loci: [{url: 'main-url', info: {globalMeetingId: 'gmid-123'}}],
1601
+ });
1602
+
1603
+ await webex.meetings.syncMeetings();
1604
+
1605
+ assert.notCalled(destroySpy);
1606
+ });
1607
+
1608
+ it('should destroy a meeting whose globalMeetingId does NOT match any active locus', async () => {
1609
+ const meetingCollectionMeetings = {
1610
+ breakoutMeeting: {
1611
+ locusUrl: 'breakout-url',
1612
+ locusInfo: {
1613
+ info: {globalMeetingId: 'gmid-other'},
1614
+ syncAllHashTreeDatasets: sinon.stub().resolves(),
1615
+ },
1616
+ sendCallAnalyzerMetrics: sinon.stub(),
1617
+ },
1618
+ };
1619
+
1620
+ webex.meetings.meetingCollection.getAll = sinon
1621
+ .stub()
1622
+ .returns(meetingCollectionMeetings);
1623
+ webex.meetings.request.getActiveMeetings = sinon.stub().resolves({
1624
+ loci: [{url: 'main-url', info: {globalMeetingId: 'gmid-123'}}],
1625
+ });
1626
+
1627
+ await webex.meetings.syncMeetings();
1628
+
1629
+ assert.calledOnce(destroySpy);
1630
+ assert.calledWith(destroySpy, meetingCollectionMeetings.breakoutMeeting);
1631
+ });
1632
+ });
1633
+
1634
+ describe('syncAllHashTreeDatasets in syncMeetings', () => {
1635
+ it('should call syncAllHashTreeDatasets for multiple meetings, skipping those without locusInfo', async () => {
1636
+ const mockLocusInfo1 = {
1637
+ syncAllHashTreeDatasets: sinon.stub().resolves(),
1638
+ };
1639
+ const mockLocusInfo2 = {
1640
+ syncAllHashTreeDatasets: sinon.stub().resolves(),
1641
+ };
1642
+
1643
+ webex.meetings.request.getActiveMeetings = sinon.stub().resolves({loci: []});
1644
+ webex.meetings.meetingCollection.getAll = sinon.stub().returns({
1645
+ meeting1: {locusInfo: mockLocusInfo1},
1646
+ meeting2: {locusInfo: undefined},
1647
+ meeting3: {locusInfo: mockLocusInfo2},
1648
+ meeting4: {},
1649
+ });
1650
+
1651
+ await webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
1652
+
1653
+ assert.calledOnce(mockLocusInfo1.syncAllHashTreeDatasets);
1654
+ assert.calledOnce(mockLocusInfo2.syncAllHashTreeDatasets);
1655
+ });
1656
+
1657
+ it('should not call syncAllHashTreeDatasets when getActiveMeetings throws an error', async () => {
1658
+ const mockLocusInfo = {
1659
+ syncAllHashTreeDatasets: sinon.stub().resolves(),
1660
+ };
1661
+
1662
+ webex.meetings.request.getActiveMeetings = sinon.stub().rejects(new Error('network error'));
1663
+ webex.meetings.meetingCollection.getAll = sinon.stub().returns({
1664
+ meeting1: {locusInfo: mockLocusInfo},
1665
+ });
1666
+
1667
+ try {
1668
+ await webex.meetings.syncMeetings();
1669
+ assert.fail('should have thrown');
1670
+ } catch (err) {
1671
+ assert.equal(err.message, 'network error');
1672
+ }
1673
+
1674
+ assert.notCalled(mockLocusInfo.syncAllHashTreeDatasets);
1675
+ });
1676
+ });
1555
1677
  });
1556
1678
  describe('#fetchStaticMeetingLink', () => {
1557
1679
  const conversationUrl = 'conv.fakeconversationurl.com';