@webex/plugin-meetings 3.11.0-next.2 → 3.11.0-next.21
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/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +307 -139
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +2 -1
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +55 -42
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/index.js +33 -22
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +108 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +76 -26
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +47 -12
- package/dist/types/hashTree/types.d.ts +1 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/locus-info/index.d.ts +9 -2
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/index.d.ts +8 -5
- package/dist/types/meeting/util.d.ts +28 -0
- package/dist/types/meetings/index.d.ts +3 -1
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +294 -96
- package/src/hashTree/types.ts +1 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/locus-info/index.ts +83 -35
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/index.ts +24 -11
- package/src/meeting/util.ts +132 -1
- package/src/meetings/index.ts +93 -8
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +1 -1
- package/src/reactions/reactions.type.ts +1 -0
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +942 -110
- package/test/unit/spec/locus-info/index.js +88 -17
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/index.js +160 -2
- package/test/unit/spec/meeting/utils.js +294 -22
- package/test/unit/spec/meetings/index.js +594 -17
|
@@ -61,8 +61,9 @@ describe('plugin-meetings', () => {
|
|
|
61
61
|
meeting.trigger = sinon.stub();
|
|
62
62
|
meeting.webex = webex;
|
|
63
63
|
meeting.webex.internal.newMetrics.callDiagnosticMetrics =
|
|
64
|
-
|
|
65
|
-
meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId =
|
|
64
|
+
meeting.webex.internal.newMetrics.callDiagnosticMetrics || {};
|
|
65
|
+
meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId =
|
|
66
|
+
sinon.stub();
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
afterEach(() => {
|
|
@@ -245,7 +246,11 @@ describe('plugin-meetings', () => {
|
|
|
245
246
|
const response = MeetingUtil.updateLocusFromApiResponse(meeting, originalResponse);
|
|
246
247
|
|
|
247
248
|
assert.deepEqual(response, originalResponse);
|
|
248
|
-
assert.calledOnceWithExactly(
|
|
249
|
+
assert.calledOnceWithExactly(
|
|
250
|
+
meeting.locusInfo.handleLocusAPIResponse,
|
|
251
|
+
meeting,
|
|
252
|
+
originalResponse.body
|
|
253
|
+
);
|
|
249
254
|
});
|
|
250
255
|
|
|
251
256
|
it('should handle locus being missing from the response', () => {
|
|
@@ -361,8 +366,8 @@ describe('plugin-meetings', () => {
|
|
|
361
366
|
describe('remoteUpdateAudioVideo', () => {
|
|
362
367
|
it('#Should call meetingRequest.locusMediaRequest with correct parameters and return the full response', async () => {
|
|
363
368
|
const fakeResponse = {
|
|
364
|
-
body: {
|
|
365
|
-
headers: {
|
|
369
|
+
body: {locus: {url: 'locusUrl'}},
|
|
370
|
+
headers: {},
|
|
366
371
|
};
|
|
367
372
|
const meeting = {
|
|
368
373
|
id: 'meeting-id',
|
|
@@ -480,6 +485,11 @@ describe('plugin-meetings', () => {
|
|
|
480
485
|
identifiers: {
|
|
481
486
|
trackingId: 'trackingId',
|
|
482
487
|
},
|
|
488
|
+
eventData: {
|
|
489
|
+
hasMismatchedSocket: false,
|
|
490
|
+
mercurySocketUrl: '',
|
|
491
|
+
deviceSocketUrl: 'ws://example.com',
|
|
492
|
+
},
|
|
483
493
|
},
|
|
484
494
|
options: {
|
|
485
495
|
meetingId: meeting.id,
|
|
@@ -649,21 +659,26 @@ describe('plugin-meetings', () => {
|
|
|
649
659
|
it('should post client event with error when join fails', async () => {
|
|
650
660
|
const joinError = new Error('Join failed');
|
|
651
661
|
meeting.meetingRequest.joinMeeting.rejects(joinError);
|
|
652
|
-
meeting.meetingInfo = {
|
|
662
|
+
meeting.meetingInfo = {meetingLookupUrl: 'test-lookup-url'};
|
|
653
663
|
|
|
654
664
|
try {
|
|
655
665
|
await MeetingUtil.joinMeeting(meeting, {});
|
|
656
666
|
assert.fail('Expected joinMeeting to throw an error');
|
|
657
667
|
} catch (error) {
|
|
658
668
|
assert.equal(error, joinError);
|
|
659
|
-
|
|
669
|
+
|
|
660
670
|
// Verify error client event was submitted
|
|
661
671
|
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
662
672
|
name: 'client.locus.join.response',
|
|
663
673
|
payload: {
|
|
664
|
-
identifiers: {
|
|
674
|
+
identifiers: {meetingLookupUrl: 'test-lookup-url'},
|
|
675
|
+
eventData: {
|
|
676
|
+
hasMismatchedSocket: false,
|
|
677
|
+
mercurySocketUrl: '',
|
|
678
|
+
deviceSocketUrl: 'ws://example.com',
|
|
679
|
+
},
|
|
665
680
|
},
|
|
666
|
-
options: {
|
|
681
|
+
options: {meetingId: meeting.id, rawError: joinError},
|
|
667
682
|
});
|
|
668
683
|
}
|
|
669
684
|
});
|
|
@@ -721,7 +736,7 @@ describe('plugin-meetings', () => {
|
|
|
721
736
|
assert.fail('Expected joinMeetingOptions to throw PasswordError');
|
|
722
737
|
} catch (error) {
|
|
723
738
|
assert.instanceOf(error, PasswordError);
|
|
724
|
-
|
|
739
|
+
|
|
725
740
|
// Verify client event was submitted with error details
|
|
726
741
|
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
727
742
|
name: 'client.meetinginfo.response',
|
|
@@ -759,7 +774,7 @@ describe('plugin-meetings', () => {
|
|
|
759
774
|
assert.fail('Expected joinMeetingOptions to throw CaptchaError');
|
|
760
775
|
} catch (error) {
|
|
761
776
|
assert.instanceOf(error, CaptchaError);
|
|
762
|
-
|
|
777
|
+
|
|
763
778
|
// Verify client event was submitted with error details
|
|
764
779
|
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
765
780
|
name: 'client.meetinginfo.response',
|
|
@@ -972,15 +987,18 @@ describe('plugin-meetings', () => {
|
|
|
972
987
|
{functionName: 'canStartManualCaption', displayHint: 'MANUAL_CAPTION_START'},
|
|
973
988
|
{functionName: 'canStopManualCaption', displayHint: 'MANUAL_CAPTION_STOP'},
|
|
974
989
|
|
|
975
|
-
{functionName: 'isLocalRecordingStarted',displayHint:'LOCAL_RECORDING_STATUS_STARTED'},
|
|
990
|
+
{functionName: 'isLocalRecordingStarted', displayHint: 'LOCAL_RECORDING_STATUS_STARTED'},
|
|
976
991
|
{functionName: 'isLocalRecordingStopped', displayHint: 'LOCAL_RECORDING_STATUS_STOPPED'},
|
|
977
992
|
{functionName: 'isLocalRecordingPaused', displayHint: 'LOCAL_RECORDING_STATUS_PAUSED'},
|
|
978
|
-
{functionName: 'isLocalStreamingStarted',displayHint:'STREAMING_STATUS_STARTED'},
|
|
993
|
+
{functionName: 'isLocalStreamingStarted', displayHint: 'STREAMING_STATUS_STARTED'},
|
|
979
994
|
{functionName: 'isLocalStreamingStopped', displayHint: 'STREAMING_STATUS_STOPPED'},
|
|
980
995
|
|
|
981
996
|
{functionName: 'isManualCaptionActive', displayHint: 'MANUAL_CAPTION_STATUS_ACTIVE'},
|
|
982
997
|
|
|
983
|
-
{
|
|
998
|
+
{
|
|
999
|
+
functionName: 'isSpokenLanguageAutoDetectionEnabled',
|
|
1000
|
+
displayHint: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED',
|
|
1001
|
+
},
|
|
984
1002
|
|
|
985
1003
|
{functionName: 'isWebexAssistantActive', displayHint: 'WEBEX_ASSISTANT_STATUS_ACTIVE'},
|
|
986
1004
|
{functionName: 'canViewCaptionPanel', displayHint: 'ENABLE_CAPTION_PANEL'},
|
|
@@ -1446,11 +1464,9 @@ describe('plugin-meetings', () => {
|
|
|
1446
1464
|
id: 'selfId123',
|
|
1447
1465
|
},
|
|
1448
1466
|
},
|
|
1467
|
+
metaData: {id: 'some hash tree metadata'},
|
|
1449
1468
|
dataSets: [{name: 'dataset1', url: 'http://dataset.com'}],
|
|
1450
|
-
mediaConnections: [
|
|
1451
|
-
{mediaId: 'mediaId456'},
|
|
1452
|
-
{someOtherField: 'value'},
|
|
1453
|
-
],
|
|
1469
|
+
mediaConnections: [{mediaId: 'mediaId456'}, {someOtherField: 'value'}],
|
|
1454
1470
|
},
|
|
1455
1471
|
};
|
|
1456
1472
|
});
|
|
@@ -1466,6 +1482,7 @@ describe('plugin-meetings', () => {
|
|
|
1466
1482
|
locusId: '12345',
|
|
1467
1483
|
selfId: 'selfId123',
|
|
1468
1484
|
mediaId: 'mediaId456',
|
|
1485
|
+
metadata: {id: 'some hash tree metadata'},
|
|
1469
1486
|
});
|
|
1470
1487
|
});
|
|
1471
1488
|
|
|
@@ -1495,20 +1512,275 @@ describe('plugin-meetings', () => {
|
|
|
1495
1512
|
locusUrl: 'https://locus-a.wbx2.com/locus/api/v1/loci/12345',
|
|
1496
1513
|
locusId: '12345',
|
|
1497
1514
|
selfId: 'selfId123',
|
|
1515
|
+
metadata: {id: 'some hash tree metadata'},
|
|
1498
1516
|
});
|
|
1499
1517
|
assert.isUndefined(result.mediaId);
|
|
1500
1518
|
});
|
|
1501
1519
|
|
|
1502
1520
|
it('handles mediaConnections without mediaId', () => {
|
|
1503
|
-
response.body.mediaConnections = [
|
|
1504
|
-
{someField: 'value1'},
|
|
1505
|
-
{anotherField: 'value2'},
|
|
1506
|
-
];
|
|
1521
|
+
response.body.mediaConnections = [{someField: 'value1'}, {anotherField: 'value2'}];
|
|
1507
1522
|
|
|
1508
1523
|
const result = MeetingUtil.parseLocusJoin(response);
|
|
1509
1524
|
|
|
1510
1525
|
assert.isUndefined(result.mediaId);
|
|
1511
1526
|
});
|
|
1512
1527
|
});
|
|
1528
|
+
|
|
1529
|
+
describe('#sanitizeWebSocketUrl', () => {
|
|
1530
|
+
it('extracts protocol, host, and pathname from URL', () => {
|
|
1531
|
+
const url = 'wss://example.com:443/mercury/path?token=secret&key=value#fragment';
|
|
1532
|
+
const result = MeetingUtil.sanitizeWebSocketUrl(url);
|
|
1533
|
+
|
|
1534
|
+
assert.equal(result, 'wss://example.com:443/mercury/path');
|
|
1535
|
+
});
|
|
1536
|
+
|
|
1537
|
+
it('handles URL without query string or hash', () => {
|
|
1538
|
+
const url = 'wss://example.com/path';
|
|
1539
|
+
const result = MeetingUtil.sanitizeWebSocketUrl(url);
|
|
1540
|
+
|
|
1541
|
+
assert.equal(result, 'wss://example.com/path');
|
|
1542
|
+
});
|
|
1543
|
+
|
|
1544
|
+
it('removes authentication from URL', () => {
|
|
1545
|
+
const url = 'wss://user:password@example.com/path?token=secret';
|
|
1546
|
+
const result = MeetingUtil.sanitizeWebSocketUrl(url);
|
|
1547
|
+
|
|
1548
|
+
assert.equal(result, 'wss://example.com/path');
|
|
1549
|
+
});
|
|
1550
|
+
|
|
1551
|
+
it('returns empty string for null or undefined', () => {
|
|
1552
|
+
assert.equal(MeetingUtil.sanitizeWebSocketUrl(null), '');
|
|
1553
|
+
assert.equal(MeetingUtil.sanitizeWebSocketUrl(undefined), '');
|
|
1554
|
+
});
|
|
1555
|
+
|
|
1556
|
+
it('returns empty string for non-string input', () => {
|
|
1557
|
+
assert.equal(MeetingUtil.sanitizeWebSocketUrl(123), '');
|
|
1558
|
+
assert.equal(MeetingUtil.sanitizeWebSocketUrl({}), '');
|
|
1559
|
+
});
|
|
1560
|
+
|
|
1561
|
+
it('returns empty string for invalid URL', () => {
|
|
1562
|
+
const result = MeetingUtil.sanitizeWebSocketUrl('not a valid url');
|
|
1563
|
+
|
|
1564
|
+
assert.equal(result, '');
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1567
|
+
it('handles URL without pathname', () => {
|
|
1568
|
+
const url = 'wss://example.com?query=value';
|
|
1569
|
+
const result = MeetingUtil.sanitizeWebSocketUrl(url);
|
|
1570
|
+
|
|
1571
|
+
assert.equal(result, 'wss://example.com');
|
|
1572
|
+
});
|
|
1573
|
+
});
|
|
1574
|
+
|
|
1575
|
+
describe('#_urlsPartiallyMatch', () => {
|
|
1576
|
+
it('returns true when URLs match exactly (ignoring query and hash)', () => {
|
|
1577
|
+
const url1 = 'wss://example.com:443/path?token=abc#fragment1';
|
|
1578
|
+
const url2 = 'wss://example.com:443/path?token=xyz#fragment2';
|
|
1579
|
+
|
|
1580
|
+
assert.isTrue(MeetingUtil._urlsPartiallyMatch(url1, url2));
|
|
1581
|
+
});
|
|
1582
|
+
|
|
1583
|
+
it('returns true when one URL is proxied and ends with the other', () => {
|
|
1584
|
+
const url1 = 'wss://other.example.com/somepath/mercury.example.com/v1/path';
|
|
1585
|
+
const url2 = 'wss://mercury.example.com/v1/path';
|
|
1586
|
+
|
|
1587
|
+
assert.isTrue(MeetingUtil._urlsPartiallyMatch(url1, url2));
|
|
1588
|
+
});
|
|
1589
|
+
|
|
1590
|
+
it('returns true when the second URL is proxied', () => {
|
|
1591
|
+
const url1 = 'wss://mercury.example.com/v1/path';
|
|
1592
|
+
const url2 = 'wss://other.example.com/somepath/mercury.example.com/v1/path';
|
|
1593
|
+
|
|
1594
|
+
assert.isTrue(MeetingUtil._urlsPartiallyMatch(url1, url2));
|
|
1595
|
+
});
|
|
1596
|
+
|
|
1597
|
+
it('returns false when hosts differ and no partial match', () => {
|
|
1598
|
+
const url1 = 'wss://example1.com/path';
|
|
1599
|
+
const url2 = 'wss://example2.com/path';
|
|
1600
|
+
|
|
1601
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(url1, url2));
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
it('returns false when pathnames differ and no partial match', () => {
|
|
1605
|
+
const url1 = 'wss://example.com/path1';
|
|
1606
|
+
const url2 = 'wss://example.com/path2';
|
|
1607
|
+
|
|
1608
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(url1, url2));
|
|
1609
|
+
});
|
|
1610
|
+
|
|
1611
|
+
it('returns false when either URL is null or undefined', () => {
|
|
1612
|
+
const url = 'wss://example.com/path';
|
|
1613
|
+
|
|
1614
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(null, url));
|
|
1615
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(url, null));
|
|
1616
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(undefined, url));
|
|
1617
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(url, undefined));
|
|
1618
|
+
});
|
|
1619
|
+
|
|
1620
|
+
it('returns false when both URLs are null', () => {
|
|
1621
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(null, null));
|
|
1622
|
+
});
|
|
1623
|
+
|
|
1624
|
+
it('returns false when URL parsing fails', () => {
|
|
1625
|
+
const url1 = 'invalid url';
|
|
1626
|
+
const url2 = 'wss://example.com/path';
|
|
1627
|
+
|
|
1628
|
+
assert.isFalse(MeetingUtil._urlsPartiallyMatch(url1, url2));
|
|
1629
|
+
});
|
|
1630
|
+
});
|
|
1631
|
+
|
|
1632
|
+
describe('#getSocketUrlInfo', () => {
|
|
1633
|
+
it('returns socket URL info when URLs differ', () => {
|
|
1634
|
+
const testWebex = {
|
|
1635
|
+
internal: {
|
|
1636
|
+
mercury: {
|
|
1637
|
+
socket: {
|
|
1638
|
+
url: 'wss://mercury.example.com:443/path?token=abc',
|
|
1639
|
+
},
|
|
1640
|
+
},
|
|
1641
|
+
device: {
|
|
1642
|
+
webSocketUrl: 'wss://device.example.com:443/path?token=xyz',
|
|
1643
|
+
},
|
|
1644
|
+
},
|
|
1645
|
+
};
|
|
1646
|
+
|
|
1647
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1648
|
+
|
|
1649
|
+
assert.isTrue(result.hasMismatchedSocket);
|
|
1650
|
+
assert.equal(result.mercurySocketUrl, 'wss://mercury.example.com:443/path');
|
|
1651
|
+
assert.equal(result.deviceSocketUrl, 'wss://device.example.com:443/path');
|
|
1652
|
+
});
|
|
1653
|
+
|
|
1654
|
+
it('returns socket URL info when URLs match', () => {
|
|
1655
|
+
const testWebex = {
|
|
1656
|
+
internal: {
|
|
1657
|
+
mercury: {
|
|
1658
|
+
socket: {
|
|
1659
|
+
url: 'wss://example.com:443/path?token=abc',
|
|
1660
|
+
},
|
|
1661
|
+
},
|
|
1662
|
+
device: {
|
|
1663
|
+
webSocketUrl: 'wss://example.com:443/path?token=xyz',
|
|
1664
|
+
},
|
|
1665
|
+
},
|
|
1666
|
+
};
|
|
1667
|
+
|
|
1668
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1669
|
+
|
|
1670
|
+
assert.isFalse(result.hasMismatchedSocket);
|
|
1671
|
+
assert.equal(result.mercurySocketUrl, 'wss://example.com:443/path');
|
|
1672
|
+
assert.equal(result.deviceSocketUrl, 'wss://example.com:443/path');
|
|
1673
|
+
});
|
|
1674
|
+
|
|
1675
|
+
it('returns hasMismatchedSocket as false when one URL is proxied (partial match)', () => {
|
|
1676
|
+
const testWebex = {
|
|
1677
|
+
internal: {
|
|
1678
|
+
mercury: {
|
|
1679
|
+
socket: {
|
|
1680
|
+
url: 'wss://other.example.com/somepath/mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages',
|
|
1681
|
+
},
|
|
1682
|
+
},
|
|
1683
|
+
device: {
|
|
1684
|
+
webSocketUrl:
|
|
1685
|
+
'wss://mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages',
|
|
1686
|
+
},
|
|
1687
|
+
},
|
|
1688
|
+
};
|
|
1689
|
+
|
|
1690
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1691
|
+
|
|
1692
|
+
assert.isFalse(result.hasMismatchedSocket);
|
|
1693
|
+
assert.equal(
|
|
1694
|
+
result.mercurySocketUrl,
|
|
1695
|
+
'wss://other.example.com/somepath/mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages'
|
|
1696
|
+
);
|
|
1697
|
+
assert.equal(
|
|
1698
|
+
result.deviceSocketUrl,
|
|
1699
|
+
'wss://mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages'
|
|
1700
|
+
);
|
|
1701
|
+
});
|
|
1702
|
+
|
|
1703
|
+
it('returns false for hasMismatchedSocket when mercury socket URL is missing', () => {
|
|
1704
|
+
const testWebex = {
|
|
1705
|
+
internal: {
|
|
1706
|
+
mercury: {
|
|
1707
|
+
socket: {},
|
|
1708
|
+
},
|
|
1709
|
+
device: {
|
|
1710
|
+
webSocketUrl: 'wss://device.example.com:443/path',
|
|
1711
|
+
},
|
|
1712
|
+
},
|
|
1713
|
+
};
|
|
1714
|
+
|
|
1715
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1716
|
+
|
|
1717
|
+
assert.isFalse(result.hasMismatchedSocket);
|
|
1718
|
+
assert.equal(result.mercurySocketUrl, '');
|
|
1719
|
+
assert.equal(result.deviceSocketUrl, 'wss://device.example.com:443/path');
|
|
1720
|
+
});
|
|
1721
|
+
|
|
1722
|
+
it('returns false for hasMismatchedSocket when device socket URL is missing', () => {
|
|
1723
|
+
const testWebex = {
|
|
1724
|
+
internal: {
|
|
1725
|
+
mercury: {
|
|
1726
|
+
socket: {
|
|
1727
|
+
url: 'wss://mercury.example.com:443/path',
|
|
1728
|
+
},
|
|
1729
|
+
},
|
|
1730
|
+
device: {},
|
|
1731
|
+
},
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1734
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1735
|
+
|
|
1736
|
+
assert.isFalse(result.hasMismatchedSocket);
|
|
1737
|
+
assert.equal(result.mercurySocketUrl, 'wss://mercury.example.com:443/path');
|
|
1738
|
+
assert.equal(result.deviceSocketUrl, '');
|
|
1739
|
+
});
|
|
1740
|
+
|
|
1741
|
+
it('returns default values when webex object is missing properties', () => {
|
|
1742
|
+
const testWebex = {
|
|
1743
|
+
internal: {},
|
|
1744
|
+
};
|
|
1745
|
+
|
|
1746
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1747
|
+
|
|
1748
|
+
assert.isFalse(result.hasMismatchedSocket);
|
|
1749
|
+
assert.equal(result.mercurySocketUrl, '');
|
|
1750
|
+
assert.equal(result.deviceSocketUrl, '');
|
|
1751
|
+
});
|
|
1752
|
+
|
|
1753
|
+
it('handles error gracefully and returns default values', () => {
|
|
1754
|
+
const testWebex = null;
|
|
1755
|
+
|
|
1756
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1757
|
+
|
|
1758
|
+
assert.isFalse(result.hasMismatchedSocket);
|
|
1759
|
+
assert.equal(result.mercurySocketUrl, '');
|
|
1760
|
+
assert.equal(result.deviceSocketUrl, '');
|
|
1761
|
+
});
|
|
1762
|
+
|
|
1763
|
+
it('sanitizes URLs by removing query parameters', () => {
|
|
1764
|
+
const testWebex = {
|
|
1765
|
+
internal: {
|
|
1766
|
+
mercury: {
|
|
1767
|
+
socket: {
|
|
1768
|
+
url: 'wss://mercury.example.com/path?secret=token123&key=value',
|
|
1769
|
+
},
|
|
1770
|
+
},
|
|
1771
|
+
device: {
|
|
1772
|
+
webSocketUrl: 'wss://device.example.com/path?secret=differenttoken&key=value',
|
|
1773
|
+
},
|
|
1774
|
+
},
|
|
1775
|
+
};
|
|
1776
|
+
|
|
1777
|
+
const result = MeetingUtil.getSocketUrlInfo(testWebex);
|
|
1778
|
+
|
|
1779
|
+
assert.notInclude(result.mercurySocketUrl, 'secret');
|
|
1780
|
+
assert.notInclude(result.mercurySocketUrl, 'token123');
|
|
1781
|
+
assert.notInclude(result.deviceSocketUrl, 'secret');
|
|
1782
|
+
assert.notInclude(result.deviceSocketUrl, 'differenttoken');
|
|
1783
|
+
});
|
|
1784
|
+
});
|
|
1513
1785
|
});
|
|
1514
1786
|
});
|