@webex/plugin-meetings 3.6.0-next.9 → 3.7.0-ipv6-multi-turn-urls.1
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 +2 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/common/errors/{webinar-registration-error.js → join-webinar-error.js} +12 -12
- package/dist/common/errors/join-webinar-error.js.map +1 -0
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +50 -7
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +1 -0
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +10 -3
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +12 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +28 -4
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +2 -1
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/index.js +61 -3
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/index.js +29 -1
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +29 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +692 -472
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +2 -6
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/request.js +21 -29
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +95 -59
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +29 -17
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +8 -3
- package/dist/meetings/index.js.map +1 -1
- package/dist/members/index.js +3 -2
- package/dist/members/index.js.map +1 -1
- package/dist/members/util.js +13 -7
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +3 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/remoteMedia.js +30 -15
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/reachability/clusterReachability.js +12 -15
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +433 -136
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachability.types.js +7 -0
- package/dist/reachability/reachability.types.js.map +1 -0
- package/dist/reachability/request.js +23 -9
- package/dist/reachability/request.js.map +1 -1
- package/dist/recording-controller/enums.js +8 -4
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.js +18 -9
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +13 -9
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +5 -7
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +45 -79
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +3 -6
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/types/common/errors/{webinar-registration-error.d.ts → join-webinar-error.d.ts} +2 -2
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +38 -1
- package/dist/types/controls-options-manager/enums.d.ts +2 -1
- package/dist/types/controls-options-manager/index.d.ts +2 -1
- package/dist/types/controls-options-manager/types.d.ts +2 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/locus-info/index.d.ts +9 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +28 -0
- package/dist/types/meeting/index.d.ts +34 -3
- package/dist/types/meeting/locusMediaRequest.d.ts +2 -3
- package/dist/types/meeting/request.d.ts +2 -2
- package/dist/types/meeting/util.d.ts +2 -2
- package/dist/types/meeting-info/meeting-info-v2.d.ts +4 -4
- package/dist/types/meetings/index.d.ts +4 -1
- package/dist/types/members/index.d.ts +2 -1
- package/dist/types/members/util.d.ts +5 -1
- package/dist/types/metrics/constants.d.ts +3 -1
- package/dist/types/reachability/clusterReachability.d.ts +1 -10
- package/dist/types/reachability/index.d.ts +74 -35
- package/dist/types/reachability/reachability.types.d.ts +64 -0
- package/dist/types/reachability/request.d.ts +5 -1
- package/dist/types/recording-controller/enums.d.ts +5 -2
- package/dist/types/recording-controller/index.d.ts +1 -0
- package/dist/types/recording-controller/util.d.ts +2 -1
- package/dist/types/roap/request.d.ts +1 -13
- package/dist/webinar/index.js +382 -19
- package/dist/webinar/index.js.map +1 -1
- package/package.json +22 -22
- package/src/common/errors/join-webinar-error.ts +24 -0
- package/src/config.ts +2 -0
- package/src/constants.ts +49 -3
- package/src/controls-options-manager/enums.ts +1 -0
- package/src/controls-options-manager/index.ts +19 -2
- package/src/controls-options-manager/types.ts +2 -0
- package/src/controls-options-manager/util.ts +12 -0
- package/src/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +46 -2
- package/src/locus-info/fullState.ts +1 -0
- package/src/locus-info/index.ts +60 -0
- package/src/media/index.ts +15 -0
- package/src/meeting/in-meeting-actions.ts +58 -0
- package/src/meeting/index.ts +232 -25
- package/src/meeting/locusMediaRequest.ts +4 -8
- package/src/meeting/request.ts +4 -11
- package/src/meeting/util.ts +25 -4
- package/src/meeting-info/meeting-info-v2.ts +23 -11
- package/src/meetings/index.ts +54 -41
- package/src/members/index.ts +4 -2
- package/src/members/util.ts +4 -1
- package/src/metrics/constants.ts +3 -1
- package/src/multistream/remoteMedia.ts +28 -15
- package/src/reachability/clusterReachability.ts +5 -15
- package/src/reachability/index.ts +285 -77
- package/src/reachability/reachability.types.ts +85 -0
- package/src/reachability/request.ts +55 -30
- package/src/recording-controller/enums.ts +5 -2
- package/src/recording-controller/index.ts +17 -4
- package/src/recording-controller/util.ts +20 -5
- package/src/roap/index.ts +4 -5
- package/src/roap/request.ts +30 -44
- package/src/roap/turnDiscovery.ts +2 -4
- package/src/webinar/index.ts +223 -17
- package/test/unit/spec/controls-options-manager/index.js +56 -32
- package/test/unit/spec/controls-options-manager/util.js +44 -0
- package/test/unit/spec/locus-info/controlsUtils.js +80 -4
- package/test/unit/spec/locus-info/index.js +59 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +31 -1
- package/test/unit/spec/meeting/index.js +369 -103
- package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
- package/test/unit/spec/meeting/request.js +3 -26
- package/test/unit/spec/meeting/utils.js +55 -13
- package/test/unit/spec/meeting-info/meetinginfov2.js +9 -4
- package/test/unit/spec/meetings/index.js +25 -6
- package/test/unit/spec/members/index.js +25 -2
- package/test/unit/spec/members/request.js +37 -3
- package/test/unit/spec/members/utils.js +110 -1
- package/test/unit/spec/multistream/remoteMedia.ts +11 -7
- package/test/unit/spec/reachability/clusterReachability.ts +7 -0
- package/test/unit/spec/reachability/index.ts +265 -1
- package/test/unit/spec/reachability/request.js +56 -15
- package/test/unit/spec/recording-controller/index.js +61 -5
- package/test/unit/spec/recording-controller/util.js +39 -3
- package/test/unit/spec/roap/index.ts +1 -1
- package/test/unit/spec/roap/request.ts +51 -109
- package/test/unit/spec/roap/turnDiscovery.ts +202 -147
- package/test/unit/spec/webinar/index.ts +443 -14
- package/dist/common/errors/webinar-registration-error.js.map +0 -1
- package/src/common/errors/webinar-registration-error.ts +0 -27
|
@@ -1234,7 +1234,7 @@ describe('gatherReachability', () => {
|
|
|
1234
1234
|
assert.equal(receivedEvents['done'], 1);
|
|
1235
1235
|
|
|
1236
1236
|
// and that ip network detection was started
|
|
1237
|
-
assert.calledOnceWithExactly(webex.internal.device.ipNetworkDetector.detect);
|
|
1237
|
+
assert.calledOnceWithExactly(webex.internal.device.ipNetworkDetector.detect, true);
|
|
1238
1238
|
|
|
1239
1239
|
// finally, check the metrics - they should contain values from ipNetworkDetector
|
|
1240
1240
|
assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
|
|
@@ -1664,6 +1664,270 @@ describe('gatherReachability', () => {
|
|
|
1664
1664
|
|
|
1665
1665
|
assert.neverCalledWith(clusterReachabilityCtorStub);
|
|
1666
1666
|
});
|
|
1667
|
+
|
|
1668
|
+
describe('fallback mechanism and multiple calls to getClusters', () => {
|
|
1669
|
+
let receivedEvents;
|
|
1670
|
+
|
|
1671
|
+
const mockGetClustersEmptyResult = {
|
|
1672
|
+
discoveryOptions: {
|
|
1673
|
+
['early-call-min-clusters']: 0,
|
|
1674
|
+
['report-version']: 1,
|
|
1675
|
+
},
|
|
1676
|
+
clusters: {}, // empty cluster list
|
|
1677
|
+
joinCookie: {id: 'cookie'},
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1680
|
+
beforeEach(() => {
|
|
1681
|
+
webex.config.meetings.experimental = {
|
|
1682
|
+
enableTcpReachability: true,
|
|
1683
|
+
enableTlsReachability: true,
|
|
1684
|
+
};
|
|
1685
|
+
|
|
1686
|
+
receivedEvents = {
|
|
1687
|
+
done: 0,
|
|
1688
|
+
};
|
|
1689
|
+
});
|
|
1690
|
+
|
|
1691
|
+
it('keeps retrying if minimum required clusters are not reached', async () => {
|
|
1692
|
+
const reachability = new Reachability(webex);
|
|
1693
|
+
|
|
1694
|
+
reachability.on('reachability:done', () => {
|
|
1695
|
+
receivedEvents.done += 1;
|
|
1696
|
+
});
|
|
1697
|
+
|
|
1698
|
+
const mockGetClustersResult1 = {
|
|
1699
|
+
discoveryOptions: {
|
|
1700
|
+
['early-call-min-clusters']: 2,
|
|
1701
|
+
['report-version']: 1,
|
|
1702
|
+
},
|
|
1703
|
+
clusters: {
|
|
1704
|
+
clusterA0: {
|
|
1705
|
+
udp: ['udp-urlA'],
|
|
1706
|
+
tcp: ['tcp-urlA'],
|
|
1707
|
+
xtls: ['xtls-urlA'],
|
|
1708
|
+
isVideoMesh: false,
|
|
1709
|
+
},
|
|
1710
|
+
clusterB0: {
|
|
1711
|
+
udp: ['udp-urlB'],
|
|
1712
|
+
tcp: ['tcp-urlB'],
|
|
1713
|
+
xtls: ['xtls-urlB'],
|
|
1714
|
+
isVideoMesh: false,
|
|
1715
|
+
},
|
|
1716
|
+
},
|
|
1717
|
+
joinCookie: {id: 'cookie1'},
|
|
1718
|
+
};
|
|
1719
|
+
const mockGetClustersResult2 = {
|
|
1720
|
+
discoveryOptions: {
|
|
1721
|
+
['early-call-min-clusters']: 2,
|
|
1722
|
+
['report-version']: 1,
|
|
1723
|
+
},
|
|
1724
|
+
clusters: {
|
|
1725
|
+
clusterA1: {
|
|
1726
|
+
udp: ['udp-urlA'],
|
|
1727
|
+
tcp: ['tcp-urlA'],
|
|
1728
|
+
xtls: ['xtls-urlA'],
|
|
1729
|
+
isVideoMesh: false,
|
|
1730
|
+
},
|
|
1731
|
+
clusterB1: {
|
|
1732
|
+
udp: ['udp-urlB'],
|
|
1733
|
+
tcp: ['tcp-urlB'],
|
|
1734
|
+
xtls: ['xtls-urlB'],
|
|
1735
|
+
isVideoMesh: false,
|
|
1736
|
+
},
|
|
1737
|
+
},
|
|
1738
|
+
joinCookie: {id: 'cookie2'},
|
|
1739
|
+
};
|
|
1740
|
+
const mockGetClustersResult3 = {
|
|
1741
|
+
discoveryOptions: {
|
|
1742
|
+
['early-call-min-clusters']: 1,
|
|
1743
|
+
['report-version']: 1,
|
|
1744
|
+
},
|
|
1745
|
+
clusters: {
|
|
1746
|
+
clusterA2: {
|
|
1747
|
+
udp: ['udp-urlA'],
|
|
1748
|
+
tcp: ['tcp-urlA'],
|
|
1749
|
+
xtls: ['xtls-urlA'],
|
|
1750
|
+
isVideoMesh: false,
|
|
1751
|
+
},
|
|
1752
|
+
clusterB2: {
|
|
1753
|
+
udp: ['udp-urlB'],
|
|
1754
|
+
tcp: ['tcp-urlB'],
|
|
1755
|
+
xtls: ['xtls-urlB'],
|
|
1756
|
+
isVideoMesh: false,
|
|
1757
|
+
},
|
|
1758
|
+
},
|
|
1759
|
+
joinCookie: {id: 'cookie3'},
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
reachability.reachabilityRequest.getClusters = sinon.stub();
|
|
1763
|
+
reachability.reachabilityRequest.getClusters.onCall(0).returns(mockGetClustersResult1);
|
|
1764
|
+
reachability.reachabilityRequest.getClusters.onCall(1).returns(mockGetClustersResult2);
|
|
1765
|
+
|
|
1766
|
+
reachability.reachabilityRequest.getClusters.onCall(2).returns(mockGetClustersResult3);
|
|
1767
|
+
|
|
1768
|
+
const resultPromise = reachability.gatherReachability('test');
|
|
1769
|
+
|
|
1770
|
+
await testUtils.flushPromises();
|
|
1771
|
+
|
|
1772
|
+
// trigger some mock result events from ClusterReachability instances,
|
|
1773
|
+
// but only from 1 cluster, so not enough to reach the minimum required
|
|
1774
|
+
mockClusterReachabilityInstances['clusterA0'].emitFakeResult('udp', {
|
|
1775
|
+
result: 'reachable',
|
|
1776
|
+
clientMediaIPs: ['1.2.3.4'],
|
|
1777
|
+
latencyInMilliseconds: 11,
|
|
1778
|
+
});
|
|
1779
|
+
|
|
1780
|
+
clock.tick(3000);
|
|
1781
|
+
await resultPromise;
|
|
1782
|
+
await testUtils.flushPromises();
|
|
1783
|
+
|
|
1784
|
+
// because the minimum was not reached, another call to getClusters should be made
|
|
1785
|
+
assert.calledTwice(reachability.reachabilityRequest.getClusters);
|
|
1786
|
+
|
|
1787
|
+
// simulate no results this time
|
|
1788
|
+
|
|
1789
|
+
// check that while the 2nd attempt is in progress, the join cookie is already available from the 2nd call to getClusters
|
|
1790
|
+
const clientMediaPreferences = await reachability.getClientMediaPreferences(
|
|
1791
|
+
true,
|
|
1792
|
+
IP_VERSION.unknown
|
|
1793
|
+
);
|
|
1794
|
+
|
|
1795
|
+
assert.deepEqual(clientMediaPreferences.joinCookie, mockGetClustersResult2.joinCookie);
|
|
1796
|
+
|
|
1797
|
+
clock.tick(3000);
|
|
1798
|
+
await testUtils.flushPromises();
|
|
1799
|
+
|
|
1800
|
+
assert.calledThrice(reachability.reachabilityRequest.getClusters);
|
|
1801
|
+
|
|
1802
|
+
await testUtils.flushPromises();
|
|
1803
|
+
|
|
1804
|
+
// this time 1 result will be enough to reach the minimum
|
|
1805
|
+
mockClusterReachabilityInstances['clusterA2'].emitFakeResult('udp', {
|
|
1806
|
+
result: 'reachable',
|
|
1807
|
+
clientMediaIPs: ['1.2.3.4'],
|
|
1808
|
+
latencyInMilliseconds: 11,
|
|
1809
|
+
});
|
|
1810
|
+
clock.tick(3000);
|
|
1811
|
+
|
|
1812
|
+
// the reachability results should include only results from the last attempt
|
|
1813
|
+
await checkResults(
|
|
1814
|
+
{
|
|
1815
|
+
clusterA2: {
|
|
1816
|
+
udp: {result: 'reachable', clientMediaIPs: ['1.2.3.4'], latencyInMilliseconds: 11},
|
|
1817
|
+
tcp: {result: 'unreachable'},
|
|
1818
|
+
xtls: {result: 'unreachable'},
|
|
1819
|
+
isVideoMesh: false,
|
|
1820
|
+
},
|
|
1821
|
+
clusterB2: {
|
|
1822
|
+
udp: {result: 'unreachable'},
|
|
1823
|
+
tcp: {result: 'unreachable'},
|
|
1824
|
+
xtls: {result: 'unreachable'},
|
|
1825
|
+
isVideoMesh: false,
|
|
1826
|
+
},
|
|
1827
|
+
},
|
|
1828
|
+
mockGetClustersResult3.joinCookie
|
|
1829
|
+
);
|
|
1830
|
+
|
|
1831
|
+
// wait some more time to make sure that there are no timers that fire from one of the previous checks
|
|
1832
|
+
clock.tick(20000);
|
|
1833
|
+
|
|
1834
|
+
// as the first 2 attempts failed and didn't reach the overall timeout, there should be only 1 done event emitted
|
|
1835
|
+
assert.equal(receivedEvents.done, 1);
|
|
1836
|
+
});
|
|
1837
|
+
|
|
1838
|
+
it('handles getClusters() returning empty list on 1st call', async () => {
|
|
1839
|
+
const reachability = new Reachability(webex);
|
|
1840
|
+
|
|
1841
|
+
reachability.on('reachability:done', () => {
|
|
1842
|
+
receivedEvents.done += 1;
|
|
1843
|
+
});
|
|
1844
|
+
|
|
1845
|
+
reachability.reachabilityRequest.getClusters = sinon
|
|
1846
|
+
.stub()
|
|
1847
|
+
.resolves(mockGetClustersEmptyResult);
|
|
1848
|
+
|
|
1849
|
+
const resultPromise = reachability.gatherReachability('test');
|
|
1850
|
+
|
|
1851
|
+
await testUtils.flushPromises();
|
|
1852
|
+
|
|
1853
|
+
clock.tick(3000);
|
|
1854
|
+
await resultPromise;
|
|
1855
|
+
await testUtils.flushPromises();
|
|
1856
|
+
|
|
1857
|
+
assert.calledOnce(reachability.reachabilityRequest.getClusters);
|
|
1858
|
+
reachability.reachabilityRequest.getClusters.resetHistory();
|
|
1859
|
+
|
|
1860
|
+
assert.equal(receivedEvents.done, 1);
|
|
1861
|
+
await checkResults({}, mockGetClustersEmptyResult.joinCookie);
|
|
1862
|
+
|
|
1863
|
+
// because we didn't actually test anything (we got empty cluster list from getClusters()), we should
|
|
1864
|
+
// not say that webex backend is unreachable
|
|
1865
|
+
assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
|
|
1866
|
+
|
|
1867
|
+
// wait to check that there are no other things happening
|
|
1868
|
+
clock.tick(20000);
|
|
1869
|
+
await testUtils.flushPromises();
|
|
1870
|
+
|
|
1871
|
+
assert.notCalled(reachability.reachabilityRequest.getClusters);
|
|
1872
|
+
assert.equal(receivedEvents.done, 1);
|
|
1873
|
+
});
|
|
1874
|
+
|
|
1875
|
+
it('handles getClusters() returning empty list on 2nd call', async () => {
|
|
1876
|
+
const reachability = new Reachability(webex);
|
|
1877
|
+
|
|
1878
|
+
reachability.on('reachability:done', () => {
|
|
1879
|
+
receivedEvents.done += 1;
|
|
1880
|
+
});
|
|
1881
|
+
|
|
1882
|
+
const mockGetClustersResult1 = {
|
|
1883
|
+
discoveryOptions: {
|
|
1884
|
+
['early-call-min-clusters']: 2,
|
|
1885
|
+
['report-version']: 1,
|
|
1886
|
+
},
|
|
1887
|
+
clusters: {
|
|
1888
|
+
clusterA0: {
|
|
1889
|
+
udp: ['udp-urlA'],
|
|
1890
|
+
tcp: ['tcp-urlA'],
|
|
1891
|
+
xtls: ['xtls-urlA'],
|
|
1892
|
+
isVideoMesh: false,
|
|
1893
|
+
},
|
|
1894
|
+
clusterB0: {
|
|
1895
|
+
udp: ['udp-urlB'],
|
|
1896
|
+
tcp: ['tcp-urlB'],
|
|
1897
|
+
xtls: ['xtls-urlB'],
|
|
1898
|
+
isVideoMesh: false,
|
|
1899
|
+
},
|
|
1900
|
+
},
|
|
1901
|
+
joinCookie: {id: 'cookie1'},
|
|
1902
|
+
};
|
|
1903
|
+
|
|
1904
|
+
reachability.reachabilityRequest.getClusters = sinon.stub();
|
|
1905
|
+
reachability.reachabilityRequest.getClusters.onCall(0).returns(mockGetClustersResult1);
|
|
1906
|
+
reachability.reachabilityRequest.getClusters.onCall(1).returns(mockGetClustersEmptyResult);
|
|
1907
|
+
|
|
1908
|
+
const resultPromise = reachability.gatherReachability('test');
|
|
1909
|
+
|
|
1910
|
+
await testUtils.flushPromises();
|
|
1911
|
+
|
|
1912
|
+
clock.tick(3000);
|
|
1913
|
+
await resultPromise;
|
|
1914
|
+
await testUtils.flushPromises();
|
|
1915
|
+
|
|
1916
|
+
// because the minimum was not reached, another call to getClusters should be made
|
|
1917
|
+
assert.calledTwice(reachability.reachabilityRequest.getClusters);
|
|
1918
|
+
|
|
1919
|
+
// the reachability results should include only results from the last attempt
|
|
1920
|
+
await checkResults({}, mockGetClustersEmptyResult.joinCookie);
|
|
1921
|
+
|
|
1922
|
+
// as the first 2 attempts failed and didn't reach the overall timeout, there should be only 1 done event emitted
|
|
1923
|
+
assert.equal(receivedEvents.done, 1);
|
|
1924
|
+
// because we didn't actually test anything (we got empty cluster list from getClusters()), we should
|
|
1925
|
+
// not say that webex backend is unreachable
|
|
1926
|
+
assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
|
|
1927
|
+
});
|
|
1928
|
+
});
|
|
1929
|
+
|
|
1930
|
+
|
|
1667
1931
|
});
|
|
1668
1932
|
|
|
1669
1933
|
describe('getReachabilityResults', () => {
|
|
@@ -35,16 +35,11 @@ describe('plugin-meetings/reachability', () => {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
describe('#getClusters', () => {
|
|
38
|
+
let previousReport;
|
|
38
39
|
|
|
39
40
|
beforeEach(() => {
|
|
40
41
|
sinon.spy(webex.internal.newMetrics.callDiagnosticLatencies, 'measureLatency');
|
|
41
|
-
});
|
|
42
42
|
|
|
43
|
-
afterEach(() => {
|
|
44
|
-
sinon.restore();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('sends a GET request with the correct params', async () => {
|
|
48
43
|
webex.request = sinon.mock().returns(Promise.resolve({
|
|
49
44
|
body: {
|
|
50
45
|
clusterClasses: {
|
|
@@ -57,21 +52,67 @@ describe('plugin-meetings/reachability', () => {
|
|
|
57
52
|
}
|
|
58
53
|
}));
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
const requestParams = webex.request.getCall(0).args[0];
|
|
55
|
+
webex.config.meetings.reachabilityGetClusterTimeout = 3000;
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
previousReport = {
|
|
58
|
+
id: 'fake previous report',
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
afterEach(() => {
|
|
63
|
+
sinon.restore();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('sends a POST request with the correct params when trigger is "startup"', async () => {
|
|
67
|
+
const res = await reachabilityRequest.getClusters('startup', IP_VERSION.only_ipv4, previousReport);
|
|
68
|
+
const requestParams = webex.request.getCall(0).args[0];
|
|
67
69
|
|
|
68
|
-
assert.deepEqual(requestParams
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
assert.deepEqual(requestParams, {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
resource: `clusters`,
|
|
73
|
+
api: 'calliopeDiscovery',
|
|
74
|
+
shouldRefreshAccessToken: false,
|
|
75
|
+
timeout: 3000,
|
|
76
|
+
body: {
|
|
77
|
+
ipver: IP_VERSION.only_ipv4,
|
|
78
|
+
'supported-options': {
|
|
79
|
+
'report-version': 1,
|
|
80
|
+
'early-call-min-clusters': true,
|
|
81
|
+
},
|
|
82
|
+
'previous-report': previousReport,
|
|
83
|
+
trigger: 'startup',
|
|
84
|
+
},
|
|
71
85
|
});
|
|
86
|
+
|
|
72
87
|
assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
|
|
73
88
|
assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
|
|
74
89
|
assert.calledOnceWithExactly(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency, sinon.match.func, 'internal.get.cluster.time');
|
|
75
90
|
});
|
|
91
|
+
|
|
92
|
+
it('sends a POST request with the correct params when trigger is other than "startup"', async () => {
|
|
93
|
+
const res = await reachabilityRequest.getClusters('early-call/no-min-reached', IP_VERSION.only_ipv4, previousReport);
|
|
94
|
+
const requestParams = webex.request.getCall(0).args[0];
|
|
95
|
+
|
|
96
|
+
assert.deepEqual(requestParams, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
resource: `clusters`,
|
|
99
|
+
api: 'calliopeDiscovery',
|
|
100
|
+
shouldRefreshAccessToken: false,
|
|
101
|
+
timeout: 3000,
|
|
102
|
+
body: {
|
|
103
|
+
ipver: IP_VERSION.only_ipv4,
|
|
104
|
+
'supported-options': {
|
|
105
|
+
'report-version': 1,
|
|
106
|
+
'early-call-min-clusters': true,
|
|
107
|
+
},
|
|
108
|
+
'previous-report': previousReport,
|
|
109
|
+
trigger: 'early-call/no-min-reached',
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
|
|
114
|
+
assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
|
|
115
|
+
assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency);
|
|
116
|
+
});
|
|
76
117
|
});
|
|
77
118
|
});
|
|
@@ -221,7 +221,21 @@ describe('plugin-meetings', () => {
|
|
|
221
221
|
|
|
222
222
|
assert.calledWith(request.request, {
|
|
223
223
|
uri: `test/loci/id/recording`,
|
|
224
|
-
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}},
|
|
224
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}, recordingType: 'cloud'},
|
|
225
|
+
method: HTTP_VERBS.PUT,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
assert.deepEqual(result, request.request.firstCall.returnValue);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('can start premise recording when the correct display hint is present', () => {
|
|
232
|
+
controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_START']);
|
|
233
|
+
|
|
234
|
+
const result = controller.startRecording();
|
|
235
|
+
|
|
236
|
+
assert.calledWith(request.request, {
|
|
237
|
+
uri: `test/loci/id/recording`,
|
|
238
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}, recordingType: 'premise'},
|
|
225
239
|
method: HTTP_VERBS.PUT,
|
|
226
240
|
});
|
|
227
241
|
|
|
@@ -238,14 +252,28 @@ describe('plugin-meetings', () => {
|
|
|
238
252
|
assert.isRejected(result);
|
|
239
253
|
});
|
|
240
254
|
|
|
241
|
-
it('can
|
|
255
|
+
it('can stop recording when the correct display hint is present', () => {
|
|
242
256
|
controller.setDisplayHints(['RECORDING_CONTROL_STOP']);
|
|
243
257
|
|
|
244
258
|
const result = controller.stopRecording();
|
|
245
259
|
|
|
246
260
|
assert.calledWith(request.request, {
|
|
247
261
|
uri: `test/loci/id/recording`,
|
|
248
|
-
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}},
|
|
262
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}, recordingType: 'cloud'},
|
|
263
|
+
method: HTTP_VERBS.PUT,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
assert.deepEqual(result, request.request.firstCall.returnValue);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('can stop premise recording when the correct display hint is present', () => {
|
|
270
|
+
controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_STOP']);
|
|
271
|
+
|
|
272
|
+
const result = controller.stopRecording();
|
|
273
|
+
|
|
274
|
+
assert.calledWith(request.request, {
|
|
275
|
+
uri: `test/loci/id/recording`,
|
|
276
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}, recordingType: 'premise'},
|
|
249
277
|
method: HTTP_VERBS.PUT,
|
|
250
278
|
});
|
|
251
279
|
|
|
@@ -269,7 +297,21 @@ describe('plugin-meetings', () => {
|
|
|
269
297
|
|
|
270
298
|
assert.calledWith(request.request, {
|
|
271
299
|
uri: `test/loci/id/recording`,
|
|
272
|
-
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}},
|
|
300
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}, recordingType: 'cloud'},
|
|
301
|
+
method: HTTP_VERBS.PUT,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
assert.deepEqual(result, request.request.firstCall.returnValue);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('can pause premise recording when the correct display hint is present', () => {
|
|
308
|
+
controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_PAUSE']);
|
|
309
|
+
|
|
310
|
+
const result = controller.pauseRecording();
|
|
311
|
+
|
|
312
|
+
assert.calledWith(request.request, {
|
|
313
|
+
uri: `test/loci/id/recording`,
|
|
314
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}, recordingType: 'premise'},
|
|
273
315
|
method: HTTP_VERBS.PUT,
|
|
274
316
|
});
|
|
275
317
|
|
|
@@ -293,7 +335,21 @@ describe('plugin-meetings', () => {
|
|
|
293
335
|
|
|
294
336
|
assert.calledWith(request.request, {
|
|
295
337
|
uri: `test/loci/id/recording`,
|
|
296
|
-
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}},
|
|
338
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}, recordingType: 'cloud'},
|
|
339
|
+
method: HTTP_VERBS.PUT,
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
assert.deepEqual(result, request.request.firstCall.returnValue);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('can resume premise recording when the correct display hint is present', () => {
|
|
346
|
+
controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_RESUME']);
|
|
347
|
+
|
|
348
|
+
const result = controller.resumeRecording();
|
|
349
|
+
|
|
350
|
+
assert.calledWith(request.request, {
|
|
351
|
+
uri: `test/loci/id/recording`,
|
|
352
|
+
body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}, recordingType: 'premise'},
|
|
297
353
|
method: HTTP_VERBS.PUT,
|
|
298
354
|
});
|
|
299
355
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import RecordingUtil from '@webex/plugin-meetings/src/recording-controller/util';
|
|
2
|
-
import RecordingAction from '@webex/plugin-meetings/src/recording-controller/enums';
|
|
2
|
+
import { RecordingAction } from '@webex/plugin-meetings/src/recording-controller/enums';
|
|
3
3
|
import {SELF_POLICY} from '@webex/plugin-meetings/src/constants';
|
|
4
4
|
|
|
5
5
|
import {assert} from 'chai';
|
|
@@ -29,6 +29,15 @@ describe('plugin-meetings', () => {
|
|
|
29
29
|
);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
it('can start premise recording when the correct display hint is present', () => {
|
|
33
|
+
locusInfo.parsedLocus.info.userDisplayHints.push('PREMISE_RECORDING_CONTROL_START');
|
|
34
|
+
|
|
35
|
+
assert.equal(
|
|
36
|
+
RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints),
|
|
37
|
+
true
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
32
41
|
it('can start recording when the correct display hint is present and the policy is true', () => {
|
|
33
42
|
locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
|
|
34
43
|
|
|
@@ -69,6 +78,15 @@ describe('plugin-meetings', () => {
|
|
|
69
78
|
);
|
|
70
79
|
});
|
|
71
80
|
|
|
81
|
+
it('can pause premise recording when the correct display hint is present', () => {
|
|
82
|
+
locusInfo.parsedLocus.info.userDisplayHints.push('PREMISE_RECORDING_CONTROL_PAUSE');
|
|
83
|
+
|
|
84
|
+
assert.equal(
|
|
85
|
+
RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints),
|
|
86
|
+
true
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
72
90
|
it('can pause recording when the correct display hint is present and the policy is true', () => {
|
|
73
91
|
locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
|
|
74
92
|
|
|
@@ -109,6 +127,15 @@ describe('plugin-meetings', () => {
|
|
|
109
127
|
);
|
|
110
128
|
});
|
|
111
129
|
|
|
130
|
+
it('can stop premise recording when the correct display hint is present', () => {
|
|
131
|
+
locusInfo.parsedLocus.info.userDisplayHints.push('PREMISE_RECORDING_CONTROL_STOP');
|
|
132
|
+
|
|
133
|
+
assert.equal(
|
|
134
|
+
RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints),
|
|
135
|
+
true
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
112
139
|
it('can stop recording when the correct display hint is present and the policy is true', () => {
|
|
113
140
|
locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP', {
|
|
114
141
|
[SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: true,
|
|
@@ -142,7 +169,7 @@ describe('plugin-meetings', () => {
|
|
|
142
169
|
});
|
|
143
170
|
|
|
144
171
|
describe('canUserResume', () => {
|
|
145
|
-
it('can
|
|
172
|
+
it('can resume recording when the correct display hint is present', () => {
|
|
146
173
|
locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
|
|
147
174
|
|
|
148
175
|
assert.equal(
|
|
@@ -151,7 +178,16 @@ describe('plugin-meetings', () => {
|
|
|
151
178
|
);
|
|
152
179
|
});
|
|
153
180
|
|
|
154
|
-
it('can
|
|
181
|
+
it('can resume premise recording when the correct display hint is present', () => {
|
|
182
|
+
locusInfo.parsedLocus.info.userDisplayHints.push('PREMISE_RECORDING_CONTROL_RESUME');
|
|
183
|
+
|
|
184
|
+
assert.equal(
|
|
185
|
+
RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints),
|
|
186
|
+
true
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('can resume recording when the correct display hint is present and the policy is true', () => {
|
|
155
191
|
locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
|
|
156
192
|
|
|
157
193
|
assert.equal(
|
|
@@ -161,7 +161,7 @@ describe('Roap', () => {
|
|
|
161
161
|
roapMessage: expectedRoapMessage,
|
|
162
162
|
locusSelfUrl: meeting.selfUrl,
|
|
163
163
|
mediaId: meeting.mediaId,
|
|
164
|
-
|
|
164
|
+
isMultistream: meeting.isMultistream,
|
|
165
165
|
locusMediaRequest: meeting.locusMediaRequest,
|
|
166
166
|
})
|
|
167
167
|
);
|