@webex/plugin-meetings 3.0.0-beta.351 → 3.0.0-beta.352

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.
@@ -13,7 +13,7 @@ import {Credentials, Token, WebexPlugin} from '@webex/webex-core';
13
13
  import Support from '@webex/internal-plugin-support';
14
14
  import MockWebex from '@webex/test-helper-mock-webex';
15
15
  import StaticConfig from '@webex/plugin-meetings/src/common/config';
16
- import { Defer } from '@webex/common';
16
+ import {Defer} from '@webex/common';
17
17
  import {
18
18
  FLOOR_ACTION,
19
19
  SHARE_STATUS,
@@ -44,9 +44,7 @@ import {
44
44
  RemoteTrackType,
45
45
  MediaType,
46
46
  } from '@webex/internal-media-core';
47
- import {
48
- StreamEventNames,
49
- } from '@webex/media-helpers';
47
+ import {StreamEventNames} from '@webex/media-helpers';
50
48
  import * as StatsAnalyzerModule from '@webex/plugin-meetings/src/statsAnalyzer';
51
49
  import EventsScope from '@webex/plugin-meetings/src/common/events/events-scope';
52
50
  import Meetings, {CONSTANTS} from '@webex/plugin-meetings';
@@ -73,7 +71,7 @@ import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
73
71
  import {MediaRequestManager} from '@webex/plugin-meetings/src/multistream/mediaRequestManager';
74
72
  import * as ReceiveSlotManagerModule from '@webex/plugin-meetings/src/multistream/receiveSlotManager';
75
73
  import * as SendSlotManagerModule from '@webex/plugin-meetings/src/multistream/sendSlotManager';
76
- import { CallDiagnosticUtils } from '@webex/internal-plugin-metrics';
74
+ import {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';
77
75
 
78
76
  import CallDiagnosticLatencies from '@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics-latencies';
79
77
  import LLM from '@webex/internal-plugin-llm';
@@ -110,10 +108,9 @@ import {
110
108
  MISSING_ROAP_ANSWER_CLIENT_CODE,
111
109
  } from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
112
110
  import CallDiagnosticMetrics from '@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics';
113
- import { ERROR_DESCRIPTIONS } from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
111
+ import {ERROR_DESCRIPTIONS} from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
114
112
  import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
115
113
 
116
-
117
114
  describe('plugin-meetings', () => {
118
115
  const logger = {
119
116
  info: () => {},
@@ -392,7 +389,7 @@ describe('plugin-meetings', () => {
392
389
  correlationId: uuid4,
393
390
  joinTrigger: 'fake-join-trigger',
394
391
  loginType: 'fake-login-type',
395
- }
392
+ },
396
393
  },
397
394
  {
398
395
  parent: webex,
@@ -495,8 +492,7 @@ describe('plugin-meetings', () => {
495
492
  let mockSendSlotManagerCtor;
496
493
 
497
494
  beforeEach(() => {
498
- mockSendSlotManagerCtor = sinon
499
- .stub(SendSlotManagerModule,'default');
495
+ mockSendSlotManagerCtor = sinon.stub(SendSlotManagerModule, 'default');
500
496
 
501
497
  meeting = new Meeting(
502
498
  {
@@ -868,7 +864,11 @@ describe('plugin-meetings', () => {
868
864
 
869
865
  assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
870
866
  name: 'client.call.initiated',
871
- payload: {trigger: 'user-interaction', isRoapCallEnabled: true, pstnAudioType: 'dial-in'},
867
+ payload: {
868
+ trigger: 'user-interaction',
869
+ isRoapCallEnabled: true,
870
+ pstnAudioType: 'dial-in',
871
+ },
872
872
  options: {meetingId: meeting.id},
873
873
  });
874
874
 
@@ -1034,22 +1034,23 @@ describe('plugin-meetings', () => {
1034
1034
 
1035
1035
  assert.equal(result, joinMeetingResult);
1036
1036
 
1037
- defer.reject(new Error("bad day", {cause: 'bad weather'}));
1037
+ defer.reject(new Error('bad day', {cause: 'bad weather'}));
1038
1038
 
1039
1039
  try {
1040
1040
  await defer.promise;
1041
1041
  } catch (err) {
1042
-
1043
1042
  assert.deepEqual(Metrics.sendBehavioralMetric.getCalls()[0].args, [
1044
- BEHAVIORAL_METRICS.JOIN_SUCCESS, {correlation_id: meeting.correlationId}
1045
- ])
1043
+ BEHAVIORAL_METRICS.JOIN_SUCCESS,
1044
+ {correlation_id: meeting.correlationId},
1045
+ ]);
1046
1046
 
1047
1047
  assert.deepEqual(Metrics.sendBehavioralMetric.getCalls()[1].args, [
1048
- BEHAVIORAL_METRICS.LLM_CONNECTION_AFTER_JOIN_FAILURE, {
1048
+ BEHAVIORAL_METRICS.LLM_CONNECTION_AFTER_JOIN_FAILURE,
1049
+ {
1049
1050
  correlation_id: meeting.correlationId,
1050
1051
  reason: err.message,
1051
1052
  stack: err.stack,
1052
- }
1053
+ },
1053
1054
  ]);
1054
1055
  }
1055
1056
  });
@@ -1087,25 +1088,27 @@ describe('plugin-meetings', () => {
1087
1088
 
1088
1089
  assert.equal(result, joinMeetingResult);
1089
1090
 
1090
- defer.reject(new Error("bad day", {cause: 'bad weather'}));
1091
+ defer.reject(new Error('bad day', {cause: 'bad weather'}));
1091
1092
 
1092
1093
  try {
1093
1094
  await defer.promise;
1094
1095
  } catch (err) {
1095
1096
  assert.deepEqual(Metrics.sendBehavioralMetric.getCalls()[0].args, [
1096
- BEHAVIORAL_METRICS.JOIN_SUCCESS, {correlation_id: meeting.correlationId}
1097
- ])
1097
+ BEHAVIORAL_METRICS.JOIN_SUCCESS,
1098
+ {correlation_id: meeting.correlationId},
1099
+ ]);
1098
1100
 
1099
1101
  assert.deepEqual(Metrics.sendBehavioralMetric.getCalls()[1].args, [
1100
- BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_AFTER_JOIN_FAILURE, {
1102
+ BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_AFTER_JOIN_FAILURE,
1103
+ {
1101
1104
  correlation_id: meeting.correlationId,
1102
1105
  reason: err.message,
1103
1106
  stack: err.stack,
1104
- }
1107
+ },
1105
1108
  ]);
1106
1109
  }
1107
- })
1108
- })
1110
+ });
1111
+ });
1109
1112
 
1110
1113
  describe('refreshPermissionToken', () => {
1111
1114
  it('should continue if permissionTokenRefresh fails with a generic error', async () => {
@@ -1116,14 +1119,20 @@ describe('plugin-meetings', () => {
1116
1119
  const result = await meeting.join();
1117
1120
  assert.notCalled(stateMachineFailSpy);
1118
1121
  assert.equal(result, joinMeetingResult);
1119
- assert.calledOnceWithExactly(meeting.checkAndRefreshPermissionToken, 30, 'ttl-join');
1122
+ assert.calledOnceWithExactly(
1123
+ meeting.checkAndRefreshPermissionToken,
1124
+ 30,
1125
+ 'ttl-join'
1126
+ );
1120
1127
  } catch (error) {
1121
1128
  assert.fail('join should not throw an Error');
1122
1129
  }
1123
- })
1130
+ });
1124
1131
 
1125
1132
  it('should throw if permissionTokenRefresh fails with a captcha error', async () => {
1126
- meeting.checkAndRefreshPermissionToken = sinon.stub().rejects(new CaptchaError('bad captcha'));
1133
+ meeting.checkAndRefreshPermissionToken = sinon
1134
+ .stub()
1135
+ .rejects(new CaptchaError('bad captcha'));
1127
1136
  const stateMachineFailSpy = sinon.spy(meeting.meetingFiniteStateMachine, 'fail');
1128
1137
  const joinMeetingOptionsSpy = sinon.spy(MeetingUtil, 'joinMeetingOptions');
1129
1138
 
@@ -1132,16 +1141,22 @@ describe('plugin-meetings', () => {
1132
1141
  assert.fail('join should have thrown a Captcha Error.');
1133
1142
  } catch (error) {
1134
1143
  assert.calledOnce(stateMachineFailSpy);
1135
- assert.calledOnceWithExactly(meeting.checkAndRefreshPermissionToken, 30, 'ttl-join');
1144
+ assert.calledOnceWithExactly(
1145
+ meeting.checkAndRefreshPermissionToken,
1146
+ 30,
1147
+ 'ttl-join'
1148
+ );
1136
1149
  assert.instanceOf(error, CaptchaError);
1137
1150
  assert.equal(error.message, 'bad captcha');
1138
1151
  // should not get to the end promise chain, which does do the join
1139
1152
  assert.notCalled(joinMeetingOptionsSpy);
1140
1153
  }
1141
- })
1154
+ });
1142
1155
 
1143
1156
  it('should throw if permissionTokenRefresh fails with a password error', async () => {
1144
- meeting.checkAndRefreshPermissionToken = sinon.stub().rejects(new PasswordError('bad password'));
1157
+ meeting.checkAndRefreshPermissionToken = sinon
1158
+ .stub()
1159
+ .rejects(new PasswordError('bad password'));
1145
1160
  const stateMachineFailSpy = sinon.spy(meeting.meetingFiniteStateMachine, 'fail');
1146
1161
  const joinMeetingOptionsSpy = sinon.spy(MeetingUtil.joinMeetingOptions);
1147
1162
 
@@ -1150,16 +1165,22 @@ describe('plugin-meetings', () => {
1150
1165
  assert.fail('join should have thrown a Password Error.');
1151
1166
  } catch (error) {
1152
1167
  assert.calledOnce(stateMachineFailSpy);
1153
- assert.calledOnceWithExactly(meeting.checkAndRefreshPermissionToken, 30, 'ttl-join');
1168
+ assert.calledOnceWithExactly(
1169
+ meeting.checkAndRefreshPermissionToken,
1170
+ 30,
1171
+ 'ttl-join'
1172
+ );
1154
1173
  assert.instanceOf(error, PasswordError);
1155
1174
  assert.equal(error.message, 'bad password');
1156
1175
  // should not get to the end promise chain, which does do the join
1157
1176
  assert.notCalled(joinMeetingOptionsSpy);
1158
1177
  }
1159
- })
1178
+ });
1160
1179
 
1161
1180
  it('should throw if permissionTokenRefresh fails with a permission error', async () => {
1162
- meeting.checkAndRefreshPermissionToken = sinon.stub().rejects(new PermissionError('bad permission'));
1181
+ meeting.checkAndRefreshPermissionToken = sinon
1182
+ .stub()
1183
+ .rejects(new PermissionError('bad permission'));
1163
1184
  const stateMachineFailSpy = sinon.spy(meeting.meetingFiniteStateMachine, 'fail');
1164
1185
  const joinMeetingOptionsSpy = sinon.spy(MeetingUtil.joinMeetingOptions);
1165
1186
 
@@ -1168,15 +1189,19 @@ describe('plugin-meetings', () => {
1168
1189
  assert.fail('join should have thrown a Permission Error.');
1169
1190
  } catch (error) {
1170
1191
  assert.calledOnce(stateMachineFailSpy);
1171
- assert.calledOnceWithExactly(meeting.checkAndRefreshPermissionToken, 30, 'ttl-join');
1192
+ assert.calledOnceWithExactly(
1193
+ meeting.checkAndRefreshPermissionToken,
1194
+ 30,
1195
+ 'ttl-join'
1196
+ );
1172
1197
  assert.instanceOf(error, PermissionError);
1173
1198
  assert.equal(error.message, 'bad permission');
1174
1199
  // should not get to the end promise chain, which does do the join
1175
1200
  assert.notCalled(joinMeetingOptionsSpy);
1176
1201
  }
1177
- })
1178
- })
1179
- })
1202
+ });
1203
+ });
1204
+ });
1180
1205
  });
1181
1206
 
1182
1207
  describe('#addMedia', () => {
@@ -1246,7 +1271,7 @@ describe('plugin-meetings', () => {
1246
1271
  meeting.webex.meetings.reachability = {
1247
1272
  getReachabilityMetrics: sinon.stub().resolves({
1248
1273
  someReachabilityMetric1: 'some value1',
1249
- someReachabilityMetric2: 'some value2'
1274
+ someReachabilityMetric2: 'some value2',
1250
1275
  }),
1251
1276
  };
1252
1277
 
@@ -1706,9 +1731,9 @@ describe('plugin-meetings', () => {
1706
1731
 
1707
1732
  it('should reject if waitForMediaConnectionConnected() rejects after turn server retry', async () => {
1708
1733
  const FAKE_ERROR = {fatal: true};
1709
- const getErrorPayloadForClientErrorCodeStub = webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode = sinon
1710
- .stub()
1711
- .returns(FAKE_ERROR);
1734
+ const getErrorPayloadForClientErrorCodeStub =
1735
+ (webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode =
1736
+ sinon.stub().returns(FAKE_ERROR));
1712
1737
  const MOCK_CLIENT_ERROR_CODE = 2004;
1713
1738
  const generateClientErrorCodeForIceFailureStub = sinon
1714
1739
  .stub(CallDiagnosticUtils, 'generateClientErrorCodeForIceFailure')
@@ -1719,17 +1744,22 @@ describe('plugin-meetings', () => {
1719
1744
  let errorThrown = undefined;
1720
1745
 
1721
1746
  // Stub doTurnDiscovery so that on the first call we skip turn discovery
1722
- meeting.roap.doTurnDiscovery = sinon.stub().onFirstCall().returns({
1723
- turnServerInfo: undefined,
1724
- turnDiscoverySkippedReason: 'reachability',
1725
- }).onSecondCall().returns({
1726
- turnServerInfo: {
1727
- url: FAKE_TURN_URL,
1728
- username: FAKE_TURN_USER,
1729
- password: FAKE_TURN_PASSWORD,
1730
- },
1731
- turnDiscoverySkippedReason: undefined,
1732
- });
1747
+ meeting.roap.doTurnDiscovery = sinon
1748
+ .stub()
1749
+ .onFirstCall()
1750
+ .returns({
1751
+ turnServerInfo: undefined,
1752
+ turnDiscoverySkippedReason: 'reachability',
1753
+ })
1754
+ .onSecondCall()
1755
+ .returns({
1756
+ turnServerInfo: {
1757
+ url: FAKE_TURN_URL,
1758
+ username: FAKE_TURN_USER,
1759
+ password: FAKE_TURN_PASSWORD,
1760
+ },
1761
+ turnDiscoverySkippedReason: undefined,
1762
+ });
1733
1763
  meeting.meetingState = 'ACTIVE';
1734
1764
  meeting.mediaProperties.waitForMediaConnectionConnected.rejects(new Error('fake error'));
1735
1765
 
@@ -1757,18 +1787,20 @@ describe('plugin-meetings', () => {
1757
1787
  signalingState: 'unknown',
1758
1788
  iceConnectionState: 'unknown',
1759
1789
  turnServerUsed: false,
1760
- })
1790
+ });
1761
1791
  assert.calledWith(generateClientErrorCodeForIceFailureStub, {
1762
1792
  signalingState: 'unknown',
1763
1793
  iceConnectionState: 'unknown',
1764
1794
  turnServerUsed: true,
1765
- })
1795
+ });
1766
1796
 
1767
1797
  assert.calledTwice(getErrorPayloadForClientErrorCodeStub);
1768
- assert.alwaysCalledWithExactly(getErrorPayloadForClientErrorCodeStub, {clientErrorCode: MOCK_CLIENT_ERROR_CODE});
1798
+ assert.alwaysCalledWithExactly(getErrorPayloadForClientErrorCodeStub, {
1799
+ clientErrorCode: MOCK_CLIENT_ERROR_CODE,
1800
+ });
1769
1801
 
1770
1802
  assert.calledThrice(webex.internal.newMetrics.submitClientEvent);
1771
- assert.calledWith(webex.internal.newMetrics.submitClientEvent.firstCall, {
1803
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent.firstCall, {
1772
1804
  name: 'client.media.capabilities',
1773
1805
  payload: {
1774
1806
  mediaCapabilities: {
@@ -1818,18 +1850,26 @@ describe('plugin-meetings', () => {
1818
1850
  // Turn discovery internal events are sent twice this time as we go through establishMediaConnection a second time on the retry
1819
1851
  const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
1820
1852
  assert.equal(submitInternalEventCalls.length, 4);
1821
- assert.deepEqual(submitInternalEventCalls[0].args, [{
1822
- name: 'internal.client.add-media.turn-discovery.start',
1823
- }]);
1824
- assert.deepEqual(submitInternalEventCalls[1].args, [{
1825
- name: 'internal.client.add-media.turn-discovery.end',
1826
- }]);
1827
- assert.deepEqual(submitInternalEventCalls[2].args, [{
1828
- name: 'internal.client.add-media.turn-discovery.start',
1829
- }]);
1830
- assert.deepEqual(submitInternalEventCalls[3].args, [{
1831
- name: 'internal.client.add-media.turn-discovery.end',
1832
- }]);
1853
+ assert.deepEqual(submitInternalEventCalls[0].args, [
1854
+ {
1855
+ name: 'internal.client.add-media.turn-discovery.start',
1856
+ },
1857
+ ]);
1858
+ assert.deepEqual(submitInternalEventCalls[1].args, [
1859
+ {
1860
+ name: 'internal.client.add-media.turn-discovery.end',
1861
+ },
1862
+ ]);
1863
+ assert.deepEqual(submitInternalEventCalls[2].args, [
1864
+ {
1865
+ name: 'internal.client.add-media.turn-discovery.start',
1866
+ },
1867
+ ]);
1868
+ assert.deepEqual(submitInternalEventCalls[3].args, [
1869
+ {
1870
+ name: 'internal.client.add-media.turn-discovery.end',
1871
+ },
1872
+ ]);
1833
1873
 
1834
1874
  const sendBehavioralMetricCalls = Metrics.sendBehavioralMetric.getCalls();
1835
1875
  assert.equal(sendBehavioralMetricCalls.length, 3);
@@ -1872,16 +1912,8 @@ describe('plugin-meetings', () => {
1872
1912
  // Check that doTurnDiscovery is called with th4 correct value of isForced
1873
1913
  const doTurnDiscoveryCalls = meeting.roap.doTurnDiscovery.getCalls();
1874
1914
  assert.equal(doTurnDiscoveryCalls.length, 2);
1875
- assert.deepEqual(doTurnDiscoveryCalls[0].args, [
1876
- meeting,
1877
- false,
1878
- false
1879
- ]);
1880
- assert.deepEqual(doTurnDiscoveryCalls[1].args, [
1881
- meeting,
1882
- true,
1883
- true
1884
- ]);
1915
+ assert.deepEqual(doTurnDiscoveryCalls[0].args, [meeting, false, false]);
1916
+ assert.deepEqual(doTurnDiscoveryCalls[1].args, [meeting, true, true]);
1885
1917
 
1886
1918
  // Some clean up steps happens twice
1887
1919
  assert.calledTwice(forceRtcMetricsSend);
@@ -1893,9 +1925,9 @@ describe('plugin-meetings', () => {
1893
1925
 
1894
1926
  it('should resolve if waitForMediaConnectionConnected() rejects the first time but resolves the second time', async () => {
1895
1927
  const FAKE_ERROR = {fatal: true};
1896
- const getErrorPayloadForClientErrorCodeStub = webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode = sinon
1897
- .stub()
1898
- .returns(FAKE_ERROR);
1928
+ const getErrorPayloadForClientErrorCodeStub =
1929
+ (webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode =
1930
+ sinon.stub().returns(FAKE_ERROR));
1899
1931
  const MOCK_CLIENT_ERROR_CODE = 2004;
1900
1932
  const generateClientErrorCodeForIceFailureStub = sinon
1901
1933
  .stub(CallDiagnosticUtils, 'generateClientErrorCodeForIceFailure')
@@ -1906,18 +1938,28 @@ describe('plugin-meetings', () => {
1906
1938
  let errorThrown = undefined;
1907
1939
 
1908
1940
  meeting.meetingState = 'ACTIVE';
1909
- meeting.roap.doTurnDiscovery = sinon.stub().onFirstCall().returns({
1910
- turnServerInfo: undefined,
1911
- turnDiscoverySkippedReason: 'reachability',
1912
- }).onSecondCall().returns({
1913
- turnServerInfo: {
1914
- url: FAKE_TURN_URL,
1915
- username: FAKE_TURN_USER,
1916
- password: FAKE_TURN_PASSWORD,
1917
- },
1918
- turnDiscoverySkippedReason: undefined,
1919
- });
1920
- meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().onFirstCall().rejects().onSecondCall().resolves();
1941
+ meeting.roap.doTurnDiscovery = sinon
1942
+ .stub()
1943
+ .onFirstCall()
1944
+ .returns({
1945
+ turnServerInfo: undefined,
1946
+ turnDiscoverySkippedReason: 'reachability',
1947
+ })
1948
+ .onSecondCall()
1949
+ .returns({
1950
+ turnServerInfo: {
1951
+ url: FAKE_TURN_URL,
1952
+ username: FAKE_TURN_USER,
1953
+ password: FAKE_TURN_PASSWORD,
1954
+ },
1955
+ turnDiscoverySkippedReason: undefined,
1956
+ });
1957
+ meeting.mediaProperties.waitForMediaConnectionConnected = sinon
1958
+ .stub()
1959
+ .onFirstCall()
1960
+ .rejects()
1961
+ .onSecondCall()
1962
+ .resolves();
1921
1963
 
1922
1964
  const forceRtcMetricsSend = sinon.stub().resolves();
1923
1965
  const closeMediaConnectionStub = sinon.stub();
@@ -1942,10 +1984,12 @@ describe('plugin-meetings', () => {
1942
1984
  signalingState: 'unknown',
1943
1985
  iceConnectionState: 'unknown',
1944
1986
  turnServerUsed: false,
1945
- })
1987
+ });
1946
1988
 
1947
1989
  assert.calledOnce(getErrorPayloadForClientErrorCodeStub);
1948
- assert.calledWith(getErrorPayloadForClientErrorCodeStub, {clientErrorCode: MOCK_CLIENT_ERROR_CODE});
1990
+ assert.calledWith(getErrorPayloadForClientErrorCodeStub, {
1991
+ clientErrorCode: MOCK_CLIENT_ERROR_CODE,
1992
+ });
1949
1993
 
1950
1994
  assert.calledThrice(webex.internal.newMetrics.submitClientEvent);
1951
1995
  assert.calledWith(webex.internal.newMetrics.submitClientEvent.firstCall, {
@@ -1993,18 +2037,26 @@ describe('plugin-meetings', () => {
1993
2037
  // Turn discovery internal events are sent twice this time as we go through establishMediaConnection a second time on the retry
1994
2038
  const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
1995
2039
  assert.equal(submitInternalEventCalls.length, 4);
1996
- assert.deepEqual(submitInternalEventCalls[0].args, [{
1997
- name: 'internal.client.add-media.turn-discovery.start',
1998
- }]);
1999
- assert.deepEqual(submitInternalEventCalls[1].args, [{
2000
- name: 'internal.client.add-media.turn-discovery.end',
2001
- }]);
2002
- assert.deepEqual(submitInternalEventCalls[2].args, [{
2003
- name: 'internal.client.add-media.turn-discovery.start',
2004
- }]);
2005
- assert.deepEqual(submitInternalEventCalls[3].args, [{
2006
- name: 'internal.client.add-media.turn-discovery.end',
2007
- }]);
2040
+ assert.deepEqual(submitInternalEventCalls[0].args, [
2041
+ {
2042
+ name: 'internal.client.add-media.turn-discovery.start',
2043
+ },
2044
+ ]);
2045
+ assert.deepEqual(submitInternalEventCalls[1].args, [
2046
+ {
2047
+ name: 'internal.client.add-media.turn-discovery.end',
2048
+ },
2049
+ ]);
2050
+ assert.deepEqual(submitInternalEventCalls[2].args, [
2051
+ {
2052
+ name: 'internal.client.add-media.turn-discovery.start',
2053
+ },
2054
+ ]);
2055
+ assert.deepEqual(submitInternalEventCalls[3].args, [
2056
+ {
2057
+ name: 'internal.client.add-media.turn-discovery.end',
2058
+ },
2059
+ ]);
2008
2060
 
2009
2061
  const sendBehavioralMetricCalls = Metrics.sendBehavioralMetric.getCalls();
2010
2062
  assert.equal(sendBehavioralMetricCalls.length, 3);
@@ -2036,21 +2088,13 @@ describe('plugin-meetings', () => {
2036
2088
  retriedWithTurnServer: true,
2037
2089
  },
2038
2090
  ]);
2039
- meeting.roap.doTurnDiscovery
2091
+ meeting.roap.doTurnDiscovery;
2040
2092
 
2041
2093
  // Check that doTurnDiscovery is called with th4 correct value of isForced
2042
2094
  const doTurnDiscoveryCalls = meeting.roap.doTurnDiscovery.getCalls();
2043
2095
  assert.equal(doTurnDiscoveryCalls.length, 2);
2044
- assert.deepEqual(doTurnDiscoveryCalls[0].args, [
2045
- meeting,
2046
- false,
2047
- false
2048
- ]);
2049
- assert.deepEqual(doTurnDiscoveryCalls[1].args, [
2050
- meeting,
2051
- true,
2052
- true
2053
- ]);
2096
+ assert.deepEqual(doTurnDiscoveryCalls[0].args, [meeting, false, false]);
2097
+ assert.deepEqual(doTurnDiscoveryCalls[1].args, [meeting, true, true]);
2054
2098
 
2055
2099
  assert.calledOnce(forceRtcMetricsSend);
2056
2100
  assert.calledOnce(closeMediaConnectionStub);
@@ -2066,18 +2110,28 @@ describe('plugin-meetings', () => {
2066
2110
 
2067
2111
  meeting.meetingState = 'ACTIVE';
2068
2112
  meeting.state = 'LEFT';
2069
- meeting.roap.doTurnDiscovery = sinon.stub().onFirstCall().returns({
2070
- turnServerInfo: undefined,
2071
- turnDiscoverySkippedReason: 'reachability',
2072
- }).onSecondCall().returns({
2073
- turnServerInfo: {
2074
- url: FAKE_TURN_URL,
2075
- username: FAKE_TURN_USER,
2076
- password: FAKE_TURN_PASSWORD,
2077
- },
2078
- turnDiscoverySkippedReason: undefined,
2079
- });
2080
- meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().onFirstCall().rejects().onSecondCall().resolves();
2113
+ meeting.roap.doTurnDiscovery = sinon
2114
+ .stub()
2115
+ .onFirstCall()
2116
+ .returns({
2117
+ turnServerInfo: undefined,
2118
+ turnDiscoverySkippedReason: 'reachability',
2119
+ })
2120
+ .onSecondCall()
2121
+ .returns({
2122
+ turnServerInfo: {
2123
+ url: FAKE_TURN_URL,
2124
+ username: FAKE_TURN_USER,
2125
+ password: FAKE_TURN_PASSWORD,
2126
+ },
2127
+ turnDiscoverySkippedReason: undefined,
2128
+ });
2129
+ meeting.mediaProperties.waitForMediaConnectionConnected = sinon
2130
+ .stub()
2131
+ .onFirstCall()
2132
+ .rejects()
2133
+ .onSecondCall()
2134
+ .resolves();
2081
2135
  meeting.join = sinon.stub().resolves();
2082
2136
 
2083
2137
  const closeMediaConnectionStub = sinon.stub();
@@ -2108,18 +2162,28 @@ describe('plugin-meetings', () => {
2108
2162
 
2109
2163
  meeting.meetingState = 'ACTIVE';
2110
2164
  meeting.state = 'LEFT';
2111
- meeting.roap.doTurnDiscovery = sinon.stub().onFirstCall().returns({
2112
- turnServerInfo: undefined,
2113
- turnDiscoverySkippedReason: 'reachability',
2114
- }).onSecondCall().returns({
2115
- turnServerInfo: {
2116
- url: FAKE_TURN_URL,
2117
- username: FAKE_TURN_USER,
2118
- password: FAKE_TURN_PASSWORD,
2119
- },
2120
- turnDiscoverySkippedReason: undefined,
2121
- });
2122
- meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().onFirstCall().rejects().onSecondCall().resolves();
2165
+ meeting.roap.doTurnDiscovery = sinon
2166
+ .stub()
2167
+ .onFirstCall()
2168
+ .returns({
2169
+ turnServerInfo: undefined,
2170
+ turnDiscoverySkippedReason: 'reachability',
2171
+ })
2172
+ .onSecondCall()
2173
+ .returns({
2174
+ turnServerInfo: {
2175
+ url: FAKE_TURN_URL,
2176
+ username: FAKE_TURN_USER,
2177
+ password: FAKE_TURN_PASSWORD,
2178
+ },
2179
+ turnDiscoverySkippedReason: undefined,
2180
+ });
2181
+ meeting.mediaProperties.waitForMediaConnectionConnected = sinon
2182
+ .stub()
2183
+ .onFirstCall()
2184
+ .rejects()
2185
+ .onSecondCall()
2186
+ .resolves();
2123
2187
  meeting.join = sinon.stub().rejects();
2124
2188
 
2125
2189
  const closeMediaConnectionStub = sinon.stub();
@@ -2147,7 +2211,7 @@ describe('plugin-meetings', () => {
2147
2211
  meeting.webex.meetings.reachability = {
2148
2212
  getReachabilityMetrics: sinon.stub().resolves({
2149
2213
  someReachabilityMetric1: 'some value1',
2150
- someReachabilityMetric2: 'some value2'
2214
+ someReachabilityMetric2: 'some value2',
2151
2215
  }),
2152
2216
  };
2153
2217
  await meeting.addMedia({
@@ -2209,7 +2273,8 @@ describe('plugin-meetings', () => {
2209
2273
  });
2210
2274
 
2211
2275
  // Check that the only metric sent is ADD_MEDIA_FAILURE
2212
- assert.calledOnceWithExactly(Metrics.sendBehavioralMetric,
2276
+ assert.calledOnceWithExactly(
2277
+ Metrics.sendBehavioralMetric,
2213
2278
  BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE,
2214
2279
  {
2215
2280
  correlation_id: meeting.correlationId,
@@ -2549,550 +2614,609 @@ describe('plugin-meetings', () => {
2549
2614
  to @webex/internal-media-core when addMedia, updateMedia, publishTracks, unpublishTracks are called
2550
2615
  in various combinations.
2551
2616
  */
2552
- [true,false].forEach((isMultistream) =>
2553
- describe(`addMedia/updateMedia semi-integration tests (${isMultistream ? 'multistream' : 'transcoded'})`, () => {
2554
- let fakeMicrophoneStream;
2555
- let fakeRoapMediaConnection;
2556
- let fakeMultistreamRoapMediaConnection;
2557
- let roapMediaConnectionConstructorStub;
2558
- let multistreamRoapMediaConnectionConstructorStub;
2559
- let locusMediaRequestStub; // stub for /media requests to Locus
2617
+ [true, false].forEach((isMultistream) =>
2618
+ describe(`addMedia/updateMedia semi-integration tests (${
2619
+ isMultistream ? 'multistream' : 'transcoded'
2620
+ })`, () => {
2621
+ let fakeMicrophoneStream;
2622
+ let fakeRoapMediaConnection;
2623
+ let fakeMultistreamRoapMediaConnection;
2624
+ let roapMediaConnectionConstructorStub;
2625
+ let multistreamRoapMediaConnectionConstructorStub;
2626
+ let locusMediaRequestStub; // stub for /media requests to Locus
2560
2627
 
2561
- const roapOfferMessage = {messageType: 'OFFER', sdp: 'sdp', seq: '1', tieBreaker: '123'};
2562
- const roapOKMessage = {messageType: 'OK', seq: '1'};
2628
+ const roapOfferMessage = {messageType: 'OFFER', sdp: 'sdp', seq: '1', tieBreaker: '123'};
2629
+ const roapOKMessage = {messageType: 'OK', seq: '1'};
2563
2630
 
2564
- let expectedMediaConnectionConfig;
2565
- let expectedDebugId;
2631
+ let expectedMediaConnectionConfig;
2632
+ let expectedDebugId;
2566
2633
 
2567
- let clock;
2634
+ let clock;
2568
2635
 
2569
- beforeEach(() => {
2570
- clock = sinon.useFakeTimers();
2636
+ beforeEach(() => {
2637
+ clock = sinon.useFakeTimers();
2571
2638
 
2572
- sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
2639
+ sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
2573
2640
 
2574
- meeting.deviceUrl = 'deviceUrl';
2575
- meeting.config.deviceType = 'web';
2576
- meeting.isMultistream = isMultistream;
2577
- meeting.meetingState = 'ACTIVE';
2578
- meeting.mediaId = 'fake media id';
2579
- meeting.selfUrl = 'selfUrl';
2580
- meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().resolves();
2581
- meeting.mediaProperties.getCurrentConnectionType = sinon.stub().resolves('udp');
2582
- meeting.setMercuryListener = sinon.stub();
2583
- meeting.locusInfo.onFullLocus = sinon.stub();
2584
- meeting.webex.meetings.geoHintInfo = {regionCode: 'EU', countryCode: 'UK'};
2585
- meeting.roap.doTurnDiscovery = sinon
2586
- .stub()
2587
- .resolves({turnServerInfo: {}, turnDiscoverySkippedReason: 'reachability'});
2588
- meeting.deferSDPAnswer = new Defer();
2589
- meeting.deferSDPAnswer.resolve();
2590
- meeting.webex.meetings.meetingCollection = new MeetingCollection();
2591
- meeting.webex.meetings.meetingCollection.set(meeting);
2592
-
2593
- StaticConfig.set({bandwidth: {audio: 1234, video: 5678, startBitrate: 9876}});
2594
-
2595
- // setup things that are expected to be the same across all the tests and are actually irrelevant for these tests
2596
- expectedDebugId = `MC-${meeting.id.substring(0, 4)}`;
2597
- expectedMediaConnectionConfig = {
2598
- iceServers: [{urls: undefined, username: '', credential: ''}],
2599
- skipInactiveTransceivers: false,
2600
- requireH264: true,
2601
- sdpMunging: {
2602
- convertPort9to0: false,
2603
- addContentSlides: true,
2604
- bandwidthLimits: {
2605
- audio: StaticConfig.meetings.bandwidth.audio,
2606
- video: StaticConfig.meetings.bandwidth.video,
2641
+ meeting.deviceUrl = 'deviceUrl';
2642
+ meeting.config.deviceType = 'web';
2643
+ meeting.isMultistream = isMultistream;
2644
+ meeting.meetingState = 'ACTIVE';
2645
+ meeting.mediaId = 'fake media id';
2646
+ meeting.selfUrl = 'selfUrl';
2647
+ meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().resolves();
2648
+ meeting.mediaProperties.getCurrentConnectionType = sinon.stub().resolves('udp');
2649
+ meeting.setMercuryListener = sinon.stub();
2650
+ meeting.locusInfo.onFullLocus = sinon.stub();
2651
+ meeting.webex.meetings.geoHintInfo = {regionCode: 'EU', countryCode: 'UK'};
2652
+ meeting.roap.doTurnDiscovery = sinon
2653
+ .stub()
2654
+ .resolves({turnServerInfo: {}, turnDiscoverySkippedReason: 'reachability'});
2655
+ meeting.deferSDPAnswer = new Defer();
2656
+ meeting.deferSDPAnswer.resolve();
2657
+ meeting.webex.meetings.meetingCollection = new MeetingCollection();
2658
+ meeting.webex.meetings.meetingCollection.set(meeting);
2659
+
2660
+ StaticConfig.set({bandwidth: {audio: 1234, video: 5678, startBitrate: 9876}});
2661
+
2662
+ // setup things that are expected to be the same across all the tests and are actually irrelevant for these tests
2663
+ expectedDebugId = `MC-${meeting.id.substring(0, 4)}`;
2664
+ expectedMediaConnectionConfig = {
2665
+ iceServers: [{urls: undefined, username: '', credential: ''}],
2666
+ skipInactiveTransceivers: false,
2667
+ requireH264: true,
2668
+ sdpMunging: {
2669
+ convertPort9to0: false,
2670
+ addContentSlides: true,
2671
+ bandwidthLimits: {
2672
+ audio: StaticConfig.meetings.bandwidth.audio,
2673
+ video: StaticConfig.meetings.bandwidth.video,
2674
+ },
2675
+ startBitrate: StaticConfig.meetings.bandwidth.startBitrate,
2676
+ periodicKeyframes: 20,
2677
+ disableExtmap: !meeting.config.enableExtmap,
2678
+ disableRtx: !meeting.config.enableRtx,
2607
2679
  },
2608
- startBitrate: StaticConfig.meetings.bandwidth.startBitrate,
2609
- periodicKeyframes: 20,
2610
- disableExtmap: !meeting.config.enableExtmap,
2611
- disableRtx: !meeting.config.enableRtx,
2612
- },
2613
- };
2680
+ };
2614
2681
 
2615
- // setup stubs
2616
- fakeMicrophoneStream = {
2617
- on: sinon.stub(),
2618
- off: sinon.stub(),
2619
- getSettings: sinon.stub().returns({
2620
- deviceId: 'some device id'
2621
- }),
2622
- muted: false,
2623
- setUnmuteAllowed: sinon.stub(),
2624
- setMuted: sinon.stub(),
2625
- setServerMuted: sinon.stub(),
2626
- outputStream: {
2627
- getTracks: () => {
2628
- return [{
2629
- id: 'fake mic'
2630
- }];
2631
- }
2632
- }
2633
- }
2682
+ // setup stubs
2683
+ fakeMicrophoneStream = {
2684
+ on: sinon.stub(),
2685
+ off: sinon.stub(),
2686
+ getSettings: sinon.stub().returns({
2687
+ deviceId: 'some device id',
2688
+ }),
2689
+ muted: false,
2690
+ setUnmuteAllowed: sinon.stub(),
2691
+ setMuted: sinon.stub(),
2692
+ setServerMuted: sinon.stub(),
2693
+ outputStream: {
2694
+ getTracks: () => {
2695
+ return [
2696
+ {
2697
+ id: 'fake mic',
2698
+ },
2699
+ ];
2700
+ },
2701
+ },
2702
+ };
2634
2703
 
2635
- fakeRoapMediaConnection = {
2636
- id: 'roap media connection',
2637
- close: sinon.stub(),
2638
- getConnectionState: sinon.stub().returns(ConnectionState.Connected),
2639
- initiateOffer: sinon.stub().resolves({}),
2640
- update: sinon.stub().resolves({}),
2641
- on: sinon.stub(),
2642
- };
2704
+ fakeRoapMediaConnection = {
2705
+ id: 'roap media connection',
2706
+ close: sinon.stub(),
2707
+ getConnectionState: sinon.stub().returns(ConnectionState.Connected),
2708
+ initiateOffer: sinon.stub().resolves({}),
2709
+ update: sinon.stub().resolves({}),
2710
+ on: sinon.stub(),
2711
+ };
2643
2712
 
2644
- fakeMultistreamRoapMediaConnection = {
2645
- id: 'multistream roap media connection',
2646
- close: sinon.stub(),
2647
- getConnectionState: sinon.stub().returns(ConnectionState.Connected),
2648
- initiateOffer: sinon.stub().resolves({}),
2649
- on: sinon.stub(),
2650
- requestMedia: sinon.stub(),
2651
- createReceiveSlot: sinon.stub().resolves({on: sinon.stub()}),
2652
- createSendSlot: sinon.stub().returns({
2653
- publishStream: sinon.stub(),
2654
- unpublishStream: sinon.stub(),
2655
- }),
2656
- enableMultistreamAudio: sinon.stub(),
2657
- };
2713
+ fakeMultistreamRoapMediaConnection = {
2714
+ id: 'multistream roap media connection',
2715
+ close: sinon.stub(),
2716
+ getConnectionState: sinon.stub().returns(ConnectionState.Connected),
2717
+ initiateOffer: sinon.stub().resolves({}),
2718
+ on: sinon.stub(),
2719
+ requestMedia: sinon.stub(),
2720
+ createReceiveSlot: sinon.stub().resolves({on: sinon.stub()}),
2721
+ createSendSlot: sinon.stub().returns({
2722
+ publishStream: sinon.stub(),
2723
+ unpublishStream: sinon.stub(),
2724
+ }),
2725
+ enableMultistreamAudio: sinon.stub(),
2726
+ };
2658
2727
 
2659
- roapMediaConnectionConstructorStub = sinon
2660
- .stub(internalMediaModule, 'RoapMediaConnection')
2661
- .returns(fakeRoapMediaConnection);
2728
+ roapMediaConnectionConstructorStub = sinon
2729
+ .stub(internalMediaModule, 'RoapMediaConnection')
2730
+ .returns(fakeRoapMediaConnection);
2662
2731
 
2663
- multistreamRoapMediaConnectionConstructorStub = sinon
2664
- .stub(internalMediaModule, 'MultistreamRoapMediaConnection')
2665
- .returns(fakeMultistreamRoapMediaConnection);
2732
+ multistreamRoapMediaConnectionConstructorStub = sinon
2733
+ .stub(internalMediaModule, 'MultistreamRoapMediaConnection')
2734
+ .returns(fakeMultistreamRoapMediaConnection);
2666
2735
 
2667
- locusMediaRequestStub = sinon.stub(WebexPlugin.prototype, 'request').resolves({body: {locus: { fullState: {}}}});
2668
- });
2736
+ locusMediaRequestStub = sinon
2737
+ .stub(WebexPlugin.prototype, 'request')
2738
+ .resolves({body: {locus: {fullState: {}}}});
2739
+ });
2669
2740
 
2670
- afterEach(() => {
2671
- clock.restore();
2672
- sinon.restore();
2673
- });
2741
+ afterEach(() => {
2742
+ clock.restore();
2743
+ sinon.restore();
2744
+ });
2674
2745
 
2675
- // helper function that waits until all promises are resolved and any queued up /media requests to Locus are sent out
2676
- const stableState = async () => {
2677
- await testUtils.flushPromises();
2678
- clock.tick(1); // needed because LocusMediaRequest uses Lodash.defer()
2679
- }
2746
+ // helper function that waits until all promises are resolved and any queued up /media requests to Locus are sent out
2747
+ const stableState = async () => {
2748
+ await testUtils.flushPromises();
2749
+ clock.tick(1); // needed because LocusMediaRequest uses Lodash.defer()
2750
+ };
2680
2751
 
2681
- const resetHistory = () => {
2682
- locusMediaRequestStub.resetHistory();
2683
- fakeRoapMediaConnection.update.resetHistory();
2684
- try{
2685
- meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream.resetHistory();
2686
- }
2687
- catch(e){}
2688
- };
2752
+ const resetHistory = () => {
2753
+ locusMediaRequestStub.resetHistory();
2754
+ fakeRoapMediaConnection.update.resetHistory();
2755
+ try {
2756
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream.resetHistory();
2757
+ } catch (e) {}
2758
+ };
2689
2759
 
2690
- const getRoapListener = () => {
2691
- const roapMediaConnectionToCheck = isMultistream ? fakeMultistreamRoapMediaConnection : fakeRoapMediaConnection;
2760
+ const getRoapListener = () => {
2761
+ const roapMediaConnectionToCheck = isMultistream
2762
+ ? fakeMultistreamRoapMediaConnection
2763
+ : fakeRoapMediaConnection;
2692
2764
 
2693
- for(let idx = 0; idx < roapMediaConnectionToCheck.on.callCount; idx+= 1) {
2694
- if (roapMediaConnectionToCheck.on.getCall(idx).args[0] === Event.ROAP_MESSAGE_TO_SEND) {
2695
- return roapMediaConnectionToCheck.on.getCall(idx).args[1];
2765
+ for (let idx = 0; idx < roapMediaConnectionToCheck.on.callCount; idx += 1) {
2766
+ if (
2767
+ roapMediaConnectionToCheck.on.getCall(idx).args[0] === Event.ROAP_MESSAGE_TO_SEND
2768
+ ) {
2769
+ return roapMediaConnectionToCheck.on.getCall(idx).args[1];
2770
+ }
2696
2771
  }
2772
+ assert.fail(
2773
+ 'listener for "roap:messageToSend" (Event.ROAP_MESSAGE_TO_SEND) was not registered'
2774
+ );
2697
2775
  };
2698
- assert.fail(
2699
- 'listener for "roap:messageToSend" (Event.ROAP_MESSAGE_TO_SEND) was not registered'
2700
- );
2701
- };
2702
2776
 
2703
- // simulates a Roap offer being generated by the RoapMediaConnection
2704
- const simulateRoapOffer = async () => {
2705
- meeting.deferSDPAnswer = {resolve: sinon.stub()};
2706
- const roapListener = getRoapListener();
2777
+ // simulates a Roap offer being generated by the RoapMediaConnection
2778
+ const simulateRoapOffer = async () => {
2779
+ meeting.deferSDPAnswer = {resolve: sinon.stub()};
2780
+ const roapListener = getRoapListener();
2707
2781
 
2708
- await roapListener({roapMessage: roapOfferMessage});
2709
- await stableState();
2710
- };
2782
+ await roapListener({roapMessage: roapOfferMessage});
2783
+ await stableState();
2784
+ };
2711
2785
 
2712
- // simulates a Roap OK being sent
2713
- const simulateRoapOk = async () => {
2714
- const roapListener = getRoapListener();
2786
+ // simulates a Roap OK being sent
2787
+ const simulateRoapOk = async () => {
2788
+ const roapListener = getRoapListener();
2715
2789
 
2716
- await roapListener({roapMessage: roapOKMessage});
2717
- await stableState();
2718
- };
2790
+ await roapListener({roapMessage: roapOKMessage});
2791
+ await stableState();
2792
+ };
2719
2793
 
2720
- const checkSdpOfferSent = ({audioMuted, videoMuted}) => {
2721
- const {sdp, seq, tieBreaker} = roapOfferMessage;
2722
-
2723
- assert.calledWith(locusMediaRequestStub, {
2724
- method: 'PUT',
2725
- uri: `${meeting.selfUrl}/media`,
2726
- body: {
2727
- device: {
2728
- url: meeting.deviceUrl,
2729
- deviceType: meeting.config.deviceType,
2730
- regionCode: 'EU',
2731
- countryCode: 'UK',
2732
- },
2733
- correlationId: meeting.correlationId,
2734
- localMedias: [
2735
- {
2736
- localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OFFER","sdps":["${sdp}"],"version":"2","seq":"${seq}","tieBreaker":"${tieBreaker}","headers":["includeAnswerInHttpResponse","noOkInTransaction"]}}`,
2737
- mediaId: 'fake media id',
2794
+ const checkSdpOfferSent = ({audioMuted, videoMuted}) => {
2795
+ const {sdp, seq, tieBreaker} = roapOfferMessage;
2796
+
2797
+ assert.calledWith(locusMediaRequestStub, {
2798
+ method: 'PUT',
2799
+ uri: `${meeting.selfUrl}/media`,
2800
+ body: {
2801
+ device: {
2802
+ url: meeting.deviceUrl,
2803
+ deviceType: meeting.config.deviceType,
2804
+ regionCode: 'EU',
2805
+ countryCode: 'UK',
2806
+ },
2807
+ correlationId: meeting.correlationId,
2808
+ localMedias: [
2809
+ {
2810
+ localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OFFER","sdps":["${sdp}"],"version":"2","seq":"${seq}","tieBreaker":"${tieBreaker}","headers":["includeAnswerInHttpResponse","noOkInTransaction"]}}`,
2811
+ mediaId: 'fake media id',
2812
+ },
2813
+ ],
2814
+ clientMediaPreferences: {
2815
+ preferTranscoding: !meeting.isMultistream,
2816
+ joinCookie: undefined,
2817
+ ipver: 0,
2738
2818
  },
2739
- ],
2740
- clientMediaPreferences: {
2741
- preferTranscoding: !meeting.isMultistream,
2742
- joinCookie: undefined,
2743
- ipver: 0,
2744
2819
  },
2745
- },
2746
- });
2747
- };
2820
+ });
2821
+ };
2748
2822
 
2749
- const checkOkSent = ({audioMuted, videoMuted}) => {
2750
- const {seq} = roapOKMessage;
2751
-
2752
- assert.calledWith(locusMediaRequestStub, {
2753
- method: 'PUT',
2754
- uri: `${meeting.selfUrl}/media`,
2755
- body: {
2756
- device: {
2757
- url: meeting.deviceUrl,
2758
- deviceType: meeting.config.deviceType,
2759
- countryCode: 'UK',
2760
- regionCode: 'EU'
2761
- },
2762
- correlationId: meeting.correlationId,
2763
- clientMediaPreferences: {
2764
- preferTranscoding: !meeting.isMultistream,
2765
- ipver: undefined,
2766
- joinCookie: undefined
2767
- },
2768
- localMedias: [
2769
- {
2770
- localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OK","version":"2","seq":"${seq}"}}`,
2771
- mediaId: 'fake media id'
2823
+ const checkOkSent = ({audioMuted, videoMuted}) => {
2824
+ const {seq} = roapOKMessage;
2825
+
2826
+ assert.calledWith(locusMediaRequestStub, {
2827
+ method: 'PUT',
2828
+ uri: `${meeting.selfUrl}/media`,
2829
+ body: {
2830
+ device: {
2831
+ url: meeting.deviceUrl,
2832
+ deviceType: meeting.config.deviceType,
2833
+ countryCode: 'UK',
2834
+ regionCode: 'EU',
2772
2835
  },
2773
- ],
2774
- },
2775
- });
2776
- };
2836
+ correlationId: meeting.correlationId,
2837
+ clientMediaPreferences: {
2838
+ preferTranscoding: !meeting.isMultistream,
2839
+ ipver: undefined,
2840
+ joinCookie: undefined,
2841
+ },
2842
+ localMedias: [
2843
+ {
2844
+ localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OK","version":"2","seq":"${seq}"}}`,
2845
+ mediaId: 'fake media id',
2846
+ },
2847
+ ],
2848
+ },
2849
+ });
2850
+ };
2777
2851
 
2778
- const checkLocalMuteSentToLocus = ({audioMuted, videoMuted}) => {
2779
- assert.calledWith(locusMediaRequestStub, {
2780
- method: 'PUT',
2781
- uri: `${meeting.selfUrl}/media`,
2782
- body: {
2783
- device: {
2784
- url: meeting.deviceUrl,
2785
- deviceType: meeting.config.deviceType,
2786
- regionCode: 'EU',
2787
- countryCode: 'UK',
2852
+ const checkLocalMuteSentToLocus = ({audioMuted, videoMuted}) => {
2853
+ assert.calledWith(locusMediaRequestStub, {
2854
+ method: 'PUT',
2855
+ uri: `${meeting.selfUrl}/media`,
2856
+ body: {
2857
+ device: {
2858
+ url: meeting.deviceUrl,
2859
+ deviceType: meeting.config.deviceType,
2860
+ regionCode: 'EU',
2861
+ countryCode: 'UK',
2862
+ },
2863
+ correlationId: meeting.correlationId,
2864
+ localMedias: [
2865
+ {
2866
+ localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted}}`,
2867
+ mediaId: 'fake media id',
2868
+ },
2869
+ ],
2870
+ clientMediaPreferences: {
2871
+ preferTranscoding: !meeting.isMultistream,
2872
+ ipver: undefined,
2873
+ },
2874
+ respOnlySdp: true,
2875
+ usingResource: null,
2788
2876
  },
2789
- correlationId: meeting.correlationId,
2790
- localMedias: [
2877
+ });
2878
+ };
2879
+
2880
+ const checkMediaConnectionCreated = ({
2881
+ mediaConnectionConfig,
2882
+ localStreams,
2883
+ direction,
2884
+ remoteQualityLevel,
2885
+ expectedDebugId,
2886
+ meetingId,
2887
+ }) => {
2888
+ if (isMultistream) {
2889
+ const {iceServers} = mediaConnectionConfig;
2890
+
2891
+ assert.calledOnceWithMatch(
2892
+ multistreamRoapMediaConnectionConstructorStub,
2791
2893
  {
2792
- localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted}}`,
2793
- mediaId: 'fake media id',
2894
+ iceServers,
2794
2895
  },
2795
- ],
2796
- clientMediaPreferences: {
2797
- preferTranscoding: !meeting.isMultistream,
2798
- ipver: undefined
2799
- },
2800
- respOnlySdp: true,
2801
- usingResource: null,
2802
- },
2803
- });
2804
- };
2896
+ meetingId
2897
+ );
2898
+
2899
+ assert.calledWith(
2900
+ fakeMultistreamRoapMediaConnection.createSendSlot,
2901
+ MediaType.AudioMain,
2902
+ direction.audio !== 'inactive'
2903
+ );
2904
+ assert.calledWith(
2905
+ fakeMultistreamRoapMediaConnection.createSendSlot,
2906
+ MediaType.VideoMain,
2907
+ direction.video !== 'inactive'
2908
+ );
2909
+ assert.calledWith(
2910
+ fakeMultistreamRoapMediaConnection.createSendSlot,
2911
+ MediaType.AudioSlides,
2912
+ direction.screenShare !== 'inactive'
2913
+ );
2914
+ assert.calledWith(
2915
+ fakeMultistreamRoapMediaConnection.createSendSlot,
2916
+ MediaType.VideoSlides,
2917
+ direction.screenShare !== 'inactive'
2918
+ );
2805
2919
 
2806
- const checkMediaConnectionCreated = ({mediaConnectionConfig, localStreams, direction, remoteQualityLevel, expectedDebugId, meetingId}) => {
2807
- if (isMultistream) {
2808
- const {iceServers} = mediaConnectionConfig;
2809
-
2810
- assert.calledOnceWithMatch(multistreamRoapMediaConnectionConstructorStub, {
2811
- iceServers,
2812
- }, meetingId);
2813
-
2814
- assert.calledWith(fakeMultistreamRoapMediaConnection.createSendSlot, MediaType.AudioMain, direction.audio !== 'inactive');
2815
- assert.calledWith(fakeMultistreamRoapMediaConnection.createSendSlot, MediaType.VideoMain, direction.video !== 'inactive');
2816
- assert.calledWith(fakeMultistreamRoapMediaConnection.createSendSlot, MediaType.AudioSlides, direction.screenShare !== 'inactive');
2817
- assert.calledWith(fakeMultistreamRoapMediaConnection.createSendSlot, MediaType.VideoSlides, direction.screenShare !== 'inactive');
2818
-
2819
- for(let type in localStreams){
2820
- const stream = localStreams[type];
2821
- if(stream !== undefined){
2822
- switch(type){
2823
- case 'audio':
2824
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream, stream);
2825
- break;
2826
- case 'video':
2827
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.VideoMain).publishStream, stream);
2828
- break;
2829
- case 'screenShareAudio':
2830
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream, stream);
2831
- break;
2832
- case 'screenShareVideo':
2833
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream, stream);
2834
- break;
2920
+ for (let type in localStreams) {
2921
+ const stream = localStreams[type];
2922
+ if (stream !== undefined) {
2923
+ switch (type) {
2924
+ case 'audio':
2925
+ assert.calledOnceWithExactly(
2926
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream,
2927
+ stream
2928
+ );
2929
+ break;
2930
+ case 'video':
2931
+ assert.calledOnceWithExactly(
2932
+ meeting.sendSlotManager.getSlot(MediaType.VideoMain).publishStream,
2933
+ stream
2934
+ );
2935
+ break;
2936
+ case 'screenShareAudio':
2937
+ assert.calledOnceWithExactly(
2938
+ meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream,
2939
+ stream
2940
+ );
2941
+ break;
2942
+ case 'screenShareVideo':
2943
+ assert.calledOnceWithExactly(
2944
+ meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream,
2945
+ stream
2946
+ );
2947
+ break;
2948
+ }
2835
2949
  }
2836
2950
  }
2837
- }
2838
- } else {
2839
- assert.calledOnceWithExactly(roapMediaConnectionConstructorStub, mediaConnectionConfig,
2840
- {
2841
- localTracks: {
2842
- audio: localStreams.audio?.outputStream?.getTracks()[0],
2843
- video: localStreams.video?.outputStream?.getTracks()[0],
2844
- screenShareVideo: localStreams.screenShareVideo?.outputStream?.getTracks()[0],
2845
- screenShareAudio: localStreams.screenShareAudio?.outputStream?.getTracks()[0],
2951
+ } else {
2952
+ assert.calledOnceWithExactly(
2953
+ roapMediaConnectionConstructorStub,
2954
+ mediaConnectionConfig,
2955
+ {
2956
+ localTracks: {
2957
+ audio: localStreams.audio?.outputStream?.getTracks()[0],
2958
+ video: localStreams.video?.outputStream?.getTracks()[0],
2959
+ screenShareVideo: localStreams.screenShareVideo?.outputStream?.getTracks()[0],
2960
+ screenShareAudio: localStreams.screenShareAudio?.outputStream?.getTracks()[0],
2961
+ },
2962
+ direction: {
2963
+ audio: direction.audio,
2964
+ video: direction.video,
2965
+ screenShareVideo: direction.screenShare,
2966
+ },
2967
+ remoteQualityLevel,
2846
2968
  },
2847
- direction: {audio: direction.audio, video: direction.video, screenShareVideo: direction.screenShare},
2848
- remoteQualityLevel,
2969
+ expectedDebugId
2970
+ );
2971
+ }
2972
+ };
2973
+
2974
+ it('addMedia() works correctly when media is enabled without tracks to publish', async () => {
2975
+ await meeting.addMedia();
2976
+ await simulateRoapOffer();
2977
+ await simulateRoapOk();
2978
+
2979
+ // check RoapMediaConnection was created correctly
2980
+ checkMediaConnectionCreated({
2981
+ mediaConnectionConfig: expectedMediaConnectionConfig,
2982
+ localStreams: {
2983
+ audio: undefined,
2984
+ video: undefined,
2985
+ screenShareVideo: undefined,
2986
+ screenShareAudio: undefined,
2849
2987
  },
2850
- expectedDebugId
2851
- );
2852
- }
2853
- };
2988
+ direction: {
2989
+ audio: 'sendrecv',
2990
+ video: 'sendrecv',
2991
+ screenShare: 'recvonly',
2992
+ },
2993
+ remoteQualityLevel: 'HIGH',
2994
+ expectedDebugId,
2995
+ meetingId: meeting.id,
2996
+ });
2854
2997
 
2855
- it('addMedia() works correctly when media is enabled without tracks to publish', async () => {
2856
- await meeting.addMedia();
2857
- await simulateRoapOffer();
2858
- await simulateRoapOk();
2859
-
2860
- // check RoapMediaConnection was created correctly
2861
- checkMediaConnectionCreated({
2862
- mediaConnectionConfig: expectedMediaConnectionConfig,
2863
- localStreams: {
2864
- audio: undefined,
2865
- video: undefined,
2866
- screenShareVideo: undefined,
2867
- screenShareAudio: undefined,
2868
- },
2869
- direction: {
2870
- audio: 'sendrecv',
2871
- video: 'sendrecv',
2872
- screenShare: 'recvonly',
2873
- },
2874
- remoteQualityLevel: 'HIGH',
2875
- expectedDebugId,
2876
- meetingId: meeting.id
2998
+ // and SDP offer was sent with the right audioMuted/videoMuted values
2999
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3000
+ // check OK was sent with the right audioMuted/videoMuted values
3001
+ checkOkSent({audioMuted: true, videoMuted: true});
3002
+
3003
+ // and that these were the only /media requests that were sent
3004
+ assert.calledTwice(locusMediaRequestStub);
2877
3005
  });
2878
3006
 
2879
- // and SDP offer was sent with the right audioMuted/videoMuted values
2880
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
2881
- // check OK was sent with the right audioMuted/videoMuted values
2882
- checkOkSent({audioMuted: true, videoMuted: true});
3007
+ it('addMedia() works correctly when media is enabled with streams to publish', async () => {
3008
+ await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
3009
+ await simulateRoapOffer();
3010
+ await simulateRoapOk();
2883
3011
 
2884
- // and that these were the only /media requests that were sent
2885
- assert.calledTwice(locusMediaRequestStub);
2886
- });
3012
+ // check RoapMediaConnection was created correctly
3013
+ checkMediaConnectionCreated({
3014
+ mediaConnectionConfig: expectedMediaConnectionConfig,
3015
+ localStreams: {
3016
+ audio: fakeMicrophoneStream,
3017
+ video: undefined,
3018
+ screenShareVideo: undefined,
3019
+ screenShareAudio: undefined,
3020
+ },
3021
+ direction: {
3022
+ audio: 'sendrecv',
3023
+ video: 'sendrecv',
3024
+ screenShare: 'recvonly',
3025
+ },
3026
+ remoteQualityLevel: 'HIGH',
3027
+ expectedDebugId,
3028
+ meetingId: meeting.id,
3029
+ });
2887
3030
 
2888
- it('addMedia() works correctly when media is enabled with streams to publish', async () => {
2889
- await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
2890
- await simulateRoapOffer();
2891
- await simulateRoapOk();
3031
+ // and SDP offer was sent with the right audioMuted/videoMuted values
3032
+ checkSdpOfferSent({audioMuted: false, videoMuted: true});
3033
+ // check OK was sent with the right audioMuted/videoMuted values
3034
+ checkOkSent({audioMuted: false, videoMuted: true});
2892
3035
 
2893
- // check RoapMediaConnection was created correctly
2894
- checkMediaConnectionCreated({
2895
- mediaConnectionConfig: expectedMediaConnectionConfig,
2896
- localStreams: {
2897
- audio: fakeMicrophoneStream,
2898
- video: undefined,
2899
- screenShareVideo: undefined,
2900
- screenShareAudio: undefined,
2901
- },
2902
- direction: {
2903
- audio: 'sendrecv',
2904
- video: 'sendrecv',
2905
- screenShare: 'recvonly',
2906
- },
2907
- remoteQualityLevel: 'HIGH',
2908
- expectedDebugId,
2909
- meetingId: meeting.id
3036
+ // and that these were the only /media requests that were sent
3037
+ assert.calledTwice(locusMediaRequestStub);
2910
3038
  });
2911
3039
 
2912
- // and SDP offer was sent with the right audioMuted/videoMuted values
2913
- checkSdpOfferSent({audioMuted: false, videoMuted: true});
2914
- // check OK was sent with the right audioMuted/videoMuted values
2915
- checkOkSent({audioMuted: false, videoMuted: true});
3040
+ it('addMedia() works correctly when media is enabled with tracks to publish and track is muted', async () => {
3041
+ fakeMicrophoneStream.muted = true;
2916
3042
 
2917
- // and that these were the only /media requests that were sent
2918
- assert.calledTwice(locusMediaRequestStub);
2919
- });
2920
-
2921
- it('addMedia() works correctly when media is enabled with tracks to publish and track is muted', async () => {
2922
- fakeMicrophoneStream.muted = true;
3043
+ await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
3044
+ await simulateRoapOffer();
3045
+ await simulateRoapOk();
2923
3046
 
2924
- await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
2925
- await simulateRoapOffer();
2926
- await simulateRoapOk();
3047
+ // check RoapMediaConnection was created correctly
3048
+ checkMediaConnectionCreated({
3049
+ mediaConnectionConfig: expectedMediaConnectionConfig,
3050
+ localStreams: {
3051
+ audio: fakeMicrophoneStream,
3052
+ video: undefined,
3053
+ screenShareVideo: undefined,
3054
+ screenShareAudio: undefined,
3055
+ },
3056
+ direction: {
3057
+ audio: 'sendrecv',
3058
+ video: 'sendrecv',
3059
+ screenShare: 'recvonly',
3060
+ },
3061
+ remoteQualityLevel: 'HIGH',
3062
+ expectedDebugId,
3063
+ meetingId: meeting.id,
3064
+ });
3065
+ // and SDP offer was sent with the right audioMuted/videoMuted values
3066
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3067
+ // check OK was sent with the right audioMuted/videoMuted values
3068
+ checkOkSent({audioMuted: true, videoMuted: true});
2927
3069
 
2928
- // check RoapMediaConnection was created correctly
2929
- checkMediaConnectionCreated({
2930
- mediaConnectionConfig: expectedMediaConnectionConfig,
2931
- localStreams: {
2932
- audio: fakeMicrophoneStream,
2933
- video: undefined,
2934
- screenShareVideo: undefined,
2935
- screenShareAudio: undefined,
2936
- },
2937
- direction: {
2938
- audio: 'sendrecv',
2939
- video: 'sendrecv',
2940
- screenShare: 'recvonly',
2941
- },
2942
- remoteQualityLevel: 'HIGH',
2943
- expectedDebugId,
2944
- meetingId: meeting.id
2945
- });
2946
- // and SDP offer was sent with the right audioMuted/videoMuted values
2947
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
2948
- // check OK was sent with the right audioMuted/videoMuted values
2949
- checkOkSent({audioMuted: true, videoMuted: true});
2950
-
2951
- // and that these were the only /media requests that were sent
2952
- assert.calledTwice(locusMediaRequestStub);
2953
- });
2954
-
2955
- it('addMedia() works correctly when media is disabled with tracks to publish', async () => {
2956
- await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}, audioEnabled: false});
2957
- await simulateRoapOffer();
2958
- await simulateRoapOk();
2959
-
2960
- // check RoapMediaConnection was created correctly
2961
- checkMediaConnectionCreated({
2962
- mediaConnectionConfig: expectedMediaConnectionConfig,
2963
- localStreams: {
2964
- audio: fakeMicrophoneStream,
2965
- video: undefined,
2966
- screenShareVideo: undefined,
2967
- screenShareAudio: undefined,
2968
- },
2969
- direction: {
2970
- audio: 'inactive',
2971
- video: 'sendrecv',
2972
- screenShare: 'recvonly',
2973
- },
2974
- remoteQualityLevel: 'HIGH',
2975
- expectedDebugId,
2976
- meetingId: meeting.id
3070
+ // and that these were the only /media requests that were sent
3071
+ assert.calledTwice(locusMediaRequestStub);
2977
3072
  });
2978
3073
 
2979
- // and SDP offer was sent with the right audioMuted/videoMuted values
2980
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
2981
- // check OK was sent with the right audioMuted/videoMuted values
2982
- checkOkSent({audioMuted: true, videoMuted: true});
3074
+ it('addMedia() works correctly when media is disabled with tracks to publish', async () => {
3075
+ await meeting.addMedia({
3076
+ localStreams: {microphone: fakeMicrophoneStream},
3077
+ audioEnabled: false,
3078
+ });
3079
+ await simulateRoapOffer();
3080
+ await simulateRoapOk();
2983
3081
 
2984
- // and that these were the only /media requests that were sent
2985
- assert.calledTwice(locusMediaRequestStub);
2986
- });
3082
+ // check RoapMediaConnection was created correctly
3083
+ checkMediaConnectionCreated({
3084
+ mediaConnectionConfig: expectedMediaConnectionConfig,
3085
+ localStreams: {
3086
+ audio: fakeMicrophoneStream,
3087
+ video: undefined,
3088
+ screenShareVideo: undefined,
3089
+ screenShareAudio: undefined,
3090
+ },
3091
+ direction: {
3092
+ audio: 'inactive',
3093
+ video: 'sendrecv',
3094
+ screenShare: 'recvonly',
3095
+ },
3096
+ remoteQualityLevel: 'HIGH',
3097
+ expectedDebugId,
3098
+ meetingId: meeting.id,
3099
+ });
2987
3100
 
2988
- it('addMedia() works correctly when media is disabled with no tracks to publish', async () => {
2989
- await meeting.addMedia({audioEnabled: false});
2990
- await simulateRoapOffer();
2991
- await simulateRoapOk();
3101
+ // and SDP offer was sent with the right audioMuted/videoMuted values
3102
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3103
+ // check OK was sent with the right audioMuted/videoMuted values
3104
+ checkOkSent({audioMuted: true, videoMuted: true});
2992
3105
 
2993
- // check RoapMediaConnection was created correctly
2994
- checkMediaConnectionCreated({
2995
- mediaConnectionConfig: expectedMediaConnectionConfig,
2996
- localStreams: {
2997
- audio: undefined,
2998
- video: undefined,
2999
- screenShareVideo: undefined,
3000
- screenShareAudio: undefined,
3001
- },
3002
- direction: {
3003
- audio: 'inactive',
3004
- video: 'sendrecv',
3005
- screenShare: 'recvonly',
3006
- },
3007
- remoteQualityLevel: 'HIGH',
3008
- expectedDebugId,
3009
- meetingId: meeting.id
3106
+ // and that these were the only /media requests that were sent
3107
+ assert.calledTwice(locusMediaRequestStub);
3010
3108
  });
3011
3109
 
3012
- // and SDP offer was sent with the right audioMuted/videoMuted values
3013
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
3014
- // check OK was sent with the right audioMuted/videoMuted values
3015
- checkOkSent({audioMuted: true, videoMuted: true});
3016
-
3017
- // and that these were the only /media requests that were sent
3018
- assert.calledTwice(locusMediaRequestStub);
3019
- });
3110
+ it('addMedia() works correctly when media is disabled with no tracks to publish', async () => {
3111
+ await meeting.addMedia({audioEnabled: false});
3112
+ await simulateRoapOffer();
3113
+ await simulateRoapOk();
3020
3114
 
3115
+ // check RoapMediaConnection was created correctly
3116
+ checkMediaConnectionCreated({
3117
+ mediaConnectionConfig: expectedMediaConnectionConfig,
3118
+ localStreams: {
3119
+ audio: undefined,
3120
+ video: undefined,
3121
+ screenShareVideo: undefined,
3122
+ screenShareAudio: undefined,
3123
+ },
3124
+ direction: {
3125
+ audio: 'inactive',
3126
+ video: 'sendrecv',
3127
+ screenShare: 'recvonly',
3128
+ },
3129
+ remoteQualityLevel: 'HIGH',
3130
+ expectedDebugId,
3131
+ meetingId: meeting.id,
3132
+ });
3021
3133
 
3022
- it('addMedia() works correctly when video is disabled with no tracks to publish', async () => {
3023
- await meeting.addMedia({videoEnabled: false});
3024
- await simulateRoapOffer();
3025
- await simulateRoapOk();
3134
+ // and SDP offer was sent with the right audioMuted/videoMuted values
3135
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3136
+ // check OK was sent with the right audioMuted/videoMuted values
3137
+ checkOkSent({audioMuted: true, videoMuted: true});
3026
3138
 
3027
- // check RoapMediaConnection was created correctly
3028
- checkMediaConnectionCreated({
3029
- mediaConnectionConfig: expectedMediaConnectionConfig,
3030
- localStreams: {
3031
- audio: undefined,
3032
- video: undefined,
3033
- screenShareVideo: undefined,
3034
- screenShareAudio: undefined,
3035
- },
3036
- direction: {
3037
- audio: 'sendrecv',
3038
- video: 'inactive',
3039
- screenShare: 'recvonly',
3040
- },
3041
- remoteQualityLevel: 'HIGH',
3042
- expectedDebugId,
3043
- meetingId: meeting.id
3139
+ // and that these were the only /media requests that were sent
3140
+ assert.calledTwice(locusMediaRequestStub);
3044
3141
  });
3045
3142
 
3046
- // and SDP offer was sent with the right audioMuted/videoMuted values
3047
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
3048
- // check OK was sent with the right audioMuted/videoMuted values
3049
- checkOkSent({audioMuted: true, videoMuted: true});
3050
-
3051
- // and that these were the only /media requests that were sent
3052
- assert.calledTwice(locusMediaRequestStub);
3053
- });
3143
+ it('addMedia() works correctly when video is disabled with no tracks to publish', async () => {
3144
+ await meeting.addMedia({videoEnabled: false});
3145
+ await simulateRoapOffer();
3146
+ await simulateRoapOk();
3054
3147
 
3055
- it('addMedia() works correctly when screen share is disabled with no tracks to publish', async () => {
3056
- await meeting.addMedia({shareAudioEnabled: false, shareVideoEnabled: false});
3057
- await simulateRoapOffer();
3058
- await simulateRoapOk();
3148
+ // check RoapMediaConnection was created correctly
3149
+ checkMediaConnectionCreated({
3150
+ mediaConnectionConfig: expectedMediaConnectionConfig,
3151
+ localStreams: {
3152
+ audio: undefined,
3153
+ video: undefined,
3154
+ screenShareVideo: undefined,
3155
+ screenShareAudio: undefined,
3156
+ },
3157
+ direction: {
3158
+ audio: 'sendrecv',
3159
+ video: 'inactive',
3160
+ screenShare: 'recvonly',
3161
+ },
3162
+ remoteQualityLevel: 'HIGH',
3163
+ expectedDebugId,
3164
+ meetingId: meeting.id,
3165
+ });
3059
3166
 
3167
+ // and SDP offer was sent with the right audioMuted/videoMuted values
3168
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3169
+ // check OK was sent with the right audioMuted/videoMuted values
3170
+ checkOkSent({audioMuted: true, videoMuted: true});
3060
3171
 
3061
- // check RoapMediaConnection was created correctly
3062
- checkMediaConnectionCreated({
3063
- mediaConnectionConfig: expectedMediaConnectionConfig,
3064
- localStreams: {
3065
- audio: undefined,
3066
- video: undefined,
3067
- screenShareVideo: undefined,
3068
- screenShareAudio: undefined,
3069
- },
3070
- direction: {
3071
- audio: 'sendrecv',
3072
- video: 'sendrecv',
3073
- screenShare: 'inactive',
3074
- },
3075
- remoteQualityLevel: 'HIGH',
3076
- expectedDebugId,
3077
- meetingId: meeting.id
3172
+ // and that these were the only /media requests that were sent
3173
+ assert.calledTwice(locusMediaRequestStub);
3078
3174
  });
3079
3175
 
3080
- // and SDP offer was sent with the right audioMuted/videoMuted values
3081
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
3082
- // check OK was sent with the right audioMuted/videoMuted values
3083
- checkOkSent({audioMuted: true, videoMuted: true});
3176
+ it('addMedia() works correctly when screen share is disabled with no tracks to publish', async () => {
3177
+ await meeting.addMedia({shareAudioEnabled: false, shareVideoEnabled: false});
3178
+ await simulateRoapOffer();
3179
+ await simulateRoapOk();
3084
3180
 
3085
- // and that these were the only /media requests that were sent
3086
- assert.calledTwice(locusMediaRequestStub);
3087
- });
3181
+ // check RoapMediaConnection was created correctly
3182
+ checkMediaConnectionCreated({
3183
+ mediaConnectionConfig: expectedMediaConnectionConfig,
3184
+ localStreams: {
3185
+ audio: undefined,
3186
+ video: undefined,
3187
+ screenShareVideo: undefined,
3188
+ screenShareAudio: undefined,
3189
+ },
3190
+ direction: {
3191
+ audio: 'sendrecv',
3192
+ video: 'sendrecv',
3193
+ screenShare: 'inactive',
3194
+ },
3195
+ remoteQualityLevel: 'HIGH',
3196
+ expectedDebugId,
3197
+ meetingId: meeting.id,
3198
+ });
3088
3199
 
3089
- describe('publishStreams()/unpublishStreams() calls', () => {
3090
- [
3091
- {mediaEnabled: true, expected: {direction: 'sendrecv', localMuteSentValue: false}},
3092
- {mediaEnabled: false, expected: {direction: 'inactive', localMuteSentValue: undefined}}
3093
- ]
3094
- .forEach(({mediaEnabled, expected}) => {
3095
- it(`first publishStreams() call while media is ${mediaEnabled ? 'enabled' : 'disabled'}`, async () => {
3200
+ // and SDP offer was sent with the right audioMuted/videoMuted values
3201
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3202
+ // check OK was sent with the right audioMuted/videoMuted values
3203
+ checkOkSent({audioMuted: true, videoMuted: true});
3204
+
3205
+ // and that these were the only /media requests that were sent
3206
+ assert.calledTwice(locusMediaRequestStub);
3207
+ });
3208
+
3209
+ describe('publishStreams()/unpublishStreams() calls', () => {
3210
+ [
3211
+ {mediaEnabled: true, expected: {direction: 'sendrecv', localMuteSentValue: false}},
3212
+ {
3213
+ mediaEnabled: false,
3214
+ expected: {direction: 'inactive', localMuteSentValue: undefined},
3215
+ },
3216
+ ].forEach(({mediaEnabled, expected}) => {
3217
+ it(`first publishStreams() call while media is ${
3218
+ mediaEnabled ? 'enabled' : 'disabled'
3219
+ }`, async () => {
3096
3220
  await meeting.addMedia({audioEnabled: mediaEnabled});
3097
3221
  await simulateRoapOffer();
3098
3222
  await simulateRoapOk();
@@ -3114,10 +3238,18 @@ describe('plugin-meetings', () => {
3114
3238
  }
3115
3239
 
3116
3240
  if (isMultistream) {
3117
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream, fakeMicrophoneStream);
3241
+ assert.calledOnceWithExactly(
3242
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream,
3243
+ fakeMicrophoneStream
3244
+ );
3118
3245
  } else {
3119
3246
  assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
3120
- localTracks: { audio: fakeMicrophoneStream.outputStream.getTracks()[0], video: null, screenShareVideo: null, screenShareAudio: null },
3247
+ localTracks: {
3248
+ audio: fakeMicrophoneStream.outputStream.getTracks()[0],
3249
+ video: null,
3250
+ screenShareVideo: null,
3251
+ screenShareAudio: null,
3252
+ },
3121
3253
  direction: {
3122
3254
  audio: expected.direction,
3123
3255
  video: 'sendrecv',
@@ -3128,7 +3260,9 @@ describe('plugin-meetings', () => {
3128
3260
  }
3129
3261
  });
3130
3262
 
3131
- it(`second publishStreams() call while media is ${mediaEnabled ? 'enabled' : 'disabled'}`, async () => {
3263
+ it(`second publishStreams() call while media is ${
3264
+ mediaEnabled ? 'enabled' : 'disabled'
3265
+ }`, async () => {
3132
3266
  await meeting.addMedia({audioEnabled: mediaEnabled});
3133
3267
  await simulateRoapOffer();
3134
3268
  await simulateRoapOk();
@@ -3145,22 +3279,32 @@ describe('plugin-meetings', () => {
3145
3279
  setMuted: sinon.stub(),
3146
3280
  outputStream: {
3147
3281
  getTracks: () => {
3148
- return [{
3149
- id: 'fake mic 2',
3150
- }];
3151
- }
3152
- }
3153
- }
3282
+ return [
3283
+ {
3284
+ id: 'fake mic 2',
3285
+ },
3286
+ ];
3287
+ },
3288
+ },
3289
+ };
3154
3290
 
3155
3291
  await meeting.publishStreams({microphone: fakeMicrophoneStream2});
3156
3292
  await stableState();
3157
3293
 
3158
3294
  // only the roap media connection should be updated
3159
3295
  if (isMultistream) {
3160
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream, fakeMicrophoneStream2);
3296
+ assert.calledOnceWithExactly(
3297
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream,
3298
+ fakeMicrophoneStream2
3299
+ );
3161
3300
  } else {
3162
3301
  assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
3163
- localTracks: { audio: fakeMicrophoneStream2.outputStream.getTracks()[0], video: null, screenShareVideo: null, screenShareAudio: null },
3302
+ localTracks: {
3303
+ audio: fakeMicrophoneStream2.outputStream.getTracks()[0],
3304
+ video: null,
3305
+ screenShareVideo: null,
3306
+ screenShareAudio: null,
3307
+ },
3164
3308
  direction: {
3165
3309
  audio: expected.direction,
3166
3310
  video: 'sendrecv',
@@ -3174,7 +3318,9 @@ describe('plugin-meetings', () => {
3174
3318
  assert.notCalled(locusMediaRequestStub);
3175
3319
  });
3176
3320
 
3177
- it(`unpublishStreams() call while media is ${mediaEnabled ? 'enabled' : 'disabled'}`, async () => {
3321
+ it(`unpublishStreams() call while media is ${
3322
+ mediaEnabled ? 'enabled' : 'disabled'
3323
+ }`, async () => {
3178
3324
  await meeting.addMedia({audioEnabled: mediaEnabled});
3179
3325
  await simulateRoapOffer();
3180
3326
  await simulateRoapOk();
@@ -3188,10 +3334,17 @@ describe('plugin-meetings', () => {
3188
3334
 
3189
3335
  // the roap media connection should be updated
3190
3336
  if (isMultistream) {
3191
- assert.calledOnce(meeting.sendSlotManager.getSlot(MediaType.AudioMain).unpublishStream);
3337
+ assert.calledOnce(
3338
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).unpublishStream
3339
+ );
3192
3340
  } else {
3193
3341
  assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
3194
- localTracks: { audio: null, video: null, screenShareVideo: null, screenShareAudio: null },
3342
+ localTracks: {
3343
+ audio: null,
3344
+ video: null,
3345
+ screenShareVideo: null,
3346
+ screenShareAudio: null,
3347
+ },
3195
3348
  direction: {
3196
3349
  audio: expected.direction,
3197
3350
  video: 'sendrecv',
@@ -3214,180 +3367,194 @@ describe('plugin-meetings', () => {
3214
3367
  }
3215
3368
  });
3216
3369
  });
3217
- });
3218
-
3219
- describe('updateMedia()', () => {
3370
+ });
3220
3371
 
3221
- const addMedia = async (enableMedia, stream) => {
3222
- await meeting.addMedia({audioEnabled: enableMedia, localStreams: {microphone: stream}});
3223
- await simulateRoapOffer();
3224
- await simulateRoapOk();
3372
+ describe('updateMedia()', () => {
3373
+ const addMedia = async (enableMedia, stream) => {
3374
+ await meeting.addMedia({
3375
+ audioEnabled: enableMedia,
3376
+ localStreams: {microphone: stream},
3377
+ });
3378
+ await simulateRoapOffer();
3379
+ await simulateRoapOk();
3225
3380
 
3226
- resetHistory();
3227
- }
3381
+ resetHistory();
3382
+ };
3228
3383
 
3229
- const checkAudioEnabled = (expectedStream, expectedDirection) => {
3230
- if (isMultistream) {
3231
- assert.equal(meeting.sendSlotManager.getSlot(MediaType.AudioMain).active, expectedDirection !== 'inactive');
3232
- } else {
3233
- assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
3234
- localTracks: { audio: expectedStream?.outputStream.getTracks()[0] ?? null, video: null, screenShareVideo: null, screenShareAudio: null },
3235
- direction: {
3236
- audio: expectedDirection,
3237
- video: 'sendrecv',
3238
- screenShareVideo: 'recvonly',
3239
- },
3240
- remoteQualityLevel: 'HIGH'
3241
- });
3242
- }
3243
- }
3384
+ const checkAudioEnabled = (expectedStream, expectedDirection) => {
3385
+ if (isMultistream) {
3386
+ assert.equal(
3387
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).active,
3388
+ expectedDirection !== 'inactive'
3389
+ );
3390
+ } else {
3391
+ assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
3392
+ localTracks: {
3393
+ audio: expectedStream?.outputStream.getTracks()[0] ?? null,
3394
+ video: null,
3395
+ screenShareVideo: null,
3396
+ screenShareAudio: null,
3397
+ },
3398
+ direction: {
3399
+ audio: expectedDirection,
3400
+ video: 'sendrecv',
3401
+ screenShareVideo: 'recvonly',
3402
+ },
3403
+ remoteQualityLevel: 'HIGH',
3404
+ });
3405
+ }
3406
+ };
3244
3407
 
3245
- it('updateMedia() disables media when nothing is published', async () => {
3246
- await addMedia(true);
3408
+ it('updateMedia() disables media when nothing is published', async () => {
3409
+ await addMedia(true);
3247
3410
 
3248
- await meeting.updateMedia({audioEnabled: false});
3411
+ await meeting.updateMedia({audioEnabled: false});
3249
3412
 
3250
- // the roap media connection should be updated
3251
- checkAudioEnabled(null, 'inactive');
3413
+ // the roap media connection should be updated
3414
+ checkAudioEnabled(null, 'inactive');
3252
3415
 
3253
- // and that would trigger a new offer so we simulate it happening
3254
- await simulateRoapOffer();
3416
+ // and that would trigger a new offer so we simulate it happening
3417
+ await simulateRoapOffer();
3255
3418
 
3256
- // check SDP offer was sent with the right audioMuted/videoMuted values
3257
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
3419
+ // check SDP offer was sent with the right audioMuted/videoMuted values
3420
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3258
3421
 
3259
- // simulate OK being sent in response to remote answer being received
3260
- await simulateRoapOk();
3422
+ // simulate OK being sent in response to remote answer being received
3423
+ await simulateRoapOk();
3261
3424
 
3262
- // check OK was sent with the right audioMuted/videoMuted values
3263
- checkOkSent({audioMuted: true, videoMuted: true});
3425
+ // check OK was sent with the right audioMuted/videoMuted values
3426
+ checkOkSent({audioMuted: true, videoMuted: true});
3264
3427
 
3265
- // and no other local mute requests were sent to Locus
3266
- assert.calledTwice(locusMediaRequestStub);
3267
- });
3428
+ // and no other local mute requests were sent to Locus
3429
+ assert.calledTwice(locusMediaRequestStub);
3430
+ });
3268
3431
 
3269
- it('updateMedia() enables media when nothing is published', async () => {
3270
- await addMedia(false);
3432
+ it('updateMedia() enables media when nothing is published', async () => {
3433
+ await addMedia(false);
3271
3434
 
3272
- await meeting.updateMedia({audioEnabled: true});
3435
+ await meeting.updateMedia({audioEnabled: true});
3273
3436
 
3274
- // the roap media connection should be updated
3275
- checkAudioEnabled(null, 'sendrecv');
3437
+ // the roap media connection should be updated
3438
+ checkAudioEnabled(null, 'sendrecv');
3276
3439
 
3277
- // and that would trigger a new offer so we simulate it happening
3278
- await simulateRoapOffer();
3440
+ // and that would trigger a new offer so we simulate it happening
3441
+ await simulateRoapOffer();
3279
3442
 
3280
- // check SDP offer was sent with the right audioMuted/videoMuted values
3281
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
3443
+ // check SDP offer was sent with the right audioMuted/videoMuted values
3444
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3282
3445
 
3283
- // simulate OK being sent in response to remote answer being received
3284
- await simulateRoapOk();
3446
+ // simulate OK being sent in response to remote answer being received
3447
+ await simulateRoapOk();
3285
3448
 
3286
- // check OK was sent with the right audioMuted/videoMuted values
3287
- checkOkSent({audioMuted: true, videoMuted: true});
3449
+ // check OK was sent with the right audioMuted/videoMuted values
3450
+ checkOkSent({audioMuted: true, videoMuted: true});
3288
3451
 
3289
- // and no other local mute requests were sent to Locus
3290
- assert.calledTwice(locusMediaRequestStub);
3291
- });
3452
+ // and no other local mute requests were sent to Locus
3453
+ assert.calledTwice(locusMediaRequestStub);
3454
+ });
3292
3455
 
3293
- it('updateMedia() disables media when stream is published', async () => {
3294
- await addMedia(true, fakeMicrophoneStream);
3456
+ it('updateMedia() disables media when stream is published', async () => {
3457
+ await addMedia(true, fakeMicrophoneStream);
3295
3458
 
3296
- await meeting.updateMedia({audioEnabled: false});
3297
- await stableState();
3459
+ await meeting.updateMedia({audioEnabled: false});
3460
+ await stableState();
3298
3461
 
3299
- // the roap media connection should be updated
3300
- checkAudioEnabled(fakeMicrophoneStream, 'inactive');
3462
+ // the roap media connection should be updated
3463
+ checkAudioEnabled(fakeMicrophoneStream, 'inactive');
3301
3464
 
3302
- checkLocalMuteSentToLocus({audioMuted: true, videoMuted: true});
3465
+ checkLocalMuteSentToLocus({audioMuted: true, videoMuted: true});
3303
3466
 
3304
- locusMediaRequestStub.resetHistory();
3467
+ locusMediaRequestStub.resetHistory();
3305
3468
 
3306
- // and that would trigger a new offer so we simulate it happening
3307
- await simulateRoapOffer();
3469
+ // and that would trigger a new offer so we simulate it happening
3470
+ await simulateRoapOffer();
3308
3471
 
3309
- // check SDP offer was sent with the right audioMuted/videoMuted values
3310
- checkSdpOfferSent({audioMuted: true, videoMuted: true});
3472
+ // check SDP offer was sent with the right audioMuted/videoMuted values
3473
+ checkSdpOfferSent({audioMuted: true, videoMuted: true});
3311
3474
 
3312
- // simulate OK being sent in response to remote answer being received
3313
- await simulateRoapOk();
3475
+ // simulate OK being sent in response to remote answer being received
3476
+ await simulateRoapOk();
3314
3477
 
3315
- // check OK was sent with the right audioMuted/videoMuted values
3316
- checkOkSent({audioMuted: true, videoMuted: true});
3478
+ // check OK was sent with the right audioMuted/videoMuted values
3479
+ checkOkSent({audioMuted: true, videoMuted: true});
3317
3480
 
3318
- // and no other local mute requests were sent to Locus
3319
- assert.calledTwice(locusMediaRequestStub);
3320
- });
3481
+ // and no other local mute requests were sent to Locus
3482
+ assert.calledTwice(locusMediaRequestStub);
3483
+ });
3321
3484
 
3322
- it('updateMedia() enables media when stream is published', async () => {
3323
- await addMedia(false, fakeMicrophoneStream);
3485
+ it('updateMedia() enables media when stream is published', async () => {
3486
+ await addMedia(false, fakeMicrophoneStream);
3324
3487
 
3325
- await meeting.updateMedia({audioEnabled: true});
3326
- await stableState();
3488
+ await meeting.updateMedia({audioEnabled: true});
3489
+ await stableState();
3327
3490
 
3328
- // the roap media connection should be updated
3329
- checkAudioEnabled(fakeMicrophoneStream, 'sendrecv');
3491
+ // the roap media connection should be updated
3492
+ checkAudioEnabled(fakeMicrophoneStream, 'sendrecv');
3330
3493
 
3331
- checkLocalMuteSentToLocus({audioMuted: false, videoMuted: true});
3494
+ checkLocalMuteSentToLocus({audioMuted: false, videoMuted: true});
3332
3495
 
3333
- locusMediaRequestStub.resetHistory();
3496
+ locusMediaRequestStub.resetHistory();
3334
3497
 
3335
- // and that would trigger a new offer so we simulate it happening
3336
- await simulateRoapOffer();
3498
+ // and that would trigger a new offer so we simulate it happening
3499
+ await simulateRoapOffer();
3337
3500
 
3338
- // check SDP offer was sent with the right audioMuted/videoMuted values
3339
- checkSdpOfferSent({audioMuted: false, videoMuted: true});
3501
+ // check SDP offer was sent with the right audioMuted/videoMuted values
3502
+ checkSdpOfferSent({audioMuted: false, videoMuted: true});
3340
3503
 
3341
- // simulate OK being sent in response to remote answer being received
3342
- await simulateRoapOk();
3504
+ // simulate OK being sent in response to remote answer being received
3505
+ await simulateRoapOk();
3343
3506
 
3344
- // check OK was sent with the right audioMuted/videoMuted values
3345
- checkOkSent({audioMuted: false, videoMuted: true});
3507
+ // check OK was sent with the right audioMuted/videoMuted values
3508
+ checkOkSent({audioMuted: false, videoMuted: true});
3346
3509
 
3347
- // and no other local mute requests were sent to Locus
3348
- assert.calledTwice(locusMediaRequestStub);
3510
+ // and no other local mute requests were sent to Locus
3511
+ assert.calledTwice(locusMediaRequestStub);
3512
+ });
3349
3513
  });
3350
- });
3351
3514
 
3352
- [
3353
- {mute: true, title: 'muting a track before confluence is created'},
3354
- {mute: false, title: 'unmuting a track before confluence is created'}
3355
- ].forEach(({mute, title}) =>
3356
- it(title, async () => {
3357
- // initialize the microphone mute state to opposite of what we do in the test
3358
- fakeMicrophoneStream.muted = !mute;
3515
+ [
3516
+ {mute: true, title: 'muting a track before confluence is created'},
3517
+ {mute: false, title: 'unmuting a track before confluence is created'},
3518
+ ].forEach(({mute, title}) =>
3519
+ it(title, async () => {
3520
+ // initialize the microphone mute state to opposite of what we do in the test
3521
+ fakeMicrophoneStream.muted = !mute;
3359
3522
 
3360
- await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
3361
- await stableState();
3523
+ await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
3524
+ await stableState();
3362
3525
 
3363
- resetHistory();
3526
+ resetHistory();
3364
3527
 
3365
- assert.equal(fakeMicrophoneStream.on.getCall(0).args[0], StreamEventNames.MuteStateChange);
3366
- const mutedListener = fakeMicrophoneStream.on.getCall(0).args[1];
3367
- // simulate track being muted
3368
- mutedListener(mute);
3528
+ assert.equal(
3529
+ fakeMicrophoneStream.on.getCall(0).args[0],
3530
+ StreamEventNames.MuteStateChange
3531
+ );
3532
+ const mutedListener = fakeMicrophoneStream.on.getCall(0).args[1];
3533
+ // simulate track being muted
3534
+ mutedListener(mute);
3369
3535
 
3370
- await stableState();
3536
+ await stableState();
3371
3537
 
3372
- // nothing should happen
3373
- assert.notCalled(locusMediaRequestStub);
3374
- assert.notCalled(fakeRoapMediaConnection.update);
3538
+ // nothing should happen
3539
+ assert.notCalled(locusMediaRequestStub);
3540
+ assert.notCalled(fakeRoapMediaConnection.update);
3375
3541
 
3376
- // now simulate roap offer and ok
3377
- await simulateRoapOffer();
3378
- await simulateRoapOk();
3542
+ // now simulate roap offer and ok
3543
+ await simulateRoapOffer();
3544
+ await simulateRoapOk();
3379
3545
 
3380
- // it should be sent with the right mute status
3381
- checkSdpOfferSent({audioMuted: mute, videoMuted: true});
3382
- // check OK was sent with the right audioMuted/videoMuted values
3383
- checkOkSent({audioMuted: mute, videoMuted: true});
3546
+ // it should be sent with the right mute status
3547
+ checkSdpOfferSent({audioMuted: mute, videoMuted: true});
3548
+ // check OK was sent with the right audioMuted/videoMuted values
3549
+ checkOkSent({audioMuted: mute, videoMuted: true});
3384
3550
 
3385
- // nothing else should happen
3386
- assert.calledTwice(locusMediaRequestStub);
3387
- assert.notCalled(fakeRoapMediaConnection.update);
3388
- })
3389
- );
3390
- }));
3551
+ // nothing else should happen
3552
+ assert.calledTwice(locusMediaRequestStub);
3553
+ assert.notCalled(fakeRoapMediaConnection.update);
3554
+ })
3555
+ );
3556
+ })
3557
+ );
3391
3558
 
3392
3559
  describe('#acknowledge', () => {
3393
3560
  it('should have #acknowledge', () => {
@@ -3684,13 +3851,13 @@ describe('plugin-meetings', () => {
3684
3851
  outputStream: {
3685
3852
  getTracks: () => {
3686
3853
  return [{id: 'fake underlying track'}];
3687
- }
3688
- }
3854
+ },
3855
+ },
3689
3856
  });
3690
3857
  beforeEach(() => {
3691
3858
  sandbox = sinon.createSandbox();
3692
- meeting.audio = { enable: sinon.stub()};
3693
- meeting.video = { enable: sinon.stub()};
3859
+ meeting.audio = {enable: sinon.stub()};
3860
+ meeting.video = {enable: sinon.stub()};
3694
3861
  meeting.mediaProperties.audioStream = createFakeLocalStream();
3695
3862
  meeting.mediaProperties.videoStream = createFakeLocalStream();
3696
3863
  meeting.mediaProperties.shareVideoStream = createFakeLocalStream();
@@ -3702,12 +3869,15 @@ describe('plugin-meetings', () => {
3702
3869
  receiveAudio: true,
3703
3870
  receiveVideo: true,
3704
3871
  receiveShare: true,
3705
- }
3872
+ };
3706
3873
  const fakeMultistreamRoapMediaConnection = {
3707
- createSendSlot: () => {}
3874
+ createSendSlot: () => {},
3708
3875
  };
3709
- sinon.stub(fakeMultistreamRoapMediaConnection,'createSendSlot').returns({active: true});
3710
- meeting.sendSlotManager.createSlot(fakeMultistreamRoapMediaConnection,MediaType.AudioMain);
3876
+ sinon.stub(fakeMultistreamRoapMediaConnection, 'createSendSlot').returns({active: true});
3877
+ meeting.sendSlotManager.createSlot(
3878
+ fakeMultistreamRoapMediaConnection,
3879
+ MediaType.AudioMain
3880
+ );
3711
3881
  });
3712
3882
 
3713
3883
  afterEach(() => {
@@ -3764,23 +3934,22 @@ describe('plugin-meetings', () => {
3764
3934
  // and check that update is called with the original args
3765
3935
  assert.calledOnce(meeting.mediaProperties.webrtcMediaConnection.update);
3766
3936
 
3767
- assert.calledWith(
3768
- meeting.mediaProperties.webrtcMediaConnection.update,
3769
- {
3770
- localTracks: {
3771
- audio: meeting.mediaProperties.audioStream.outputStream.getTracks()[0],
3772
- video: meeting.mediaProperties.videoStream.outputStream.getTracks()[0],
3773
- screenShareVideo: meeting.mediaProperties.shareVideoStream.outputStream.getTracks()[0],
3774
- screenShareAudio: meeting.mediaProperties.shareVideoStream.outputStream.getTracks()[0],
3775
- },
3776
- direction: {
3777
- audio: 'inactive',
3778
- video: 'inactive',
3779
- screenShareVideo: 'sendrecv',
3780
- },
3781
- remoteQualityLevel: 'HIGH',
3782
- }
3783
- );
3937
+ assert.calledWith(meeting.mediaProperties.webrtcMediaConnection.update, {
3938
+ localTracks: {
3939
+ audio: meeting.mediaProperties.audioStream.outputStream.getTracks()[0],
3940
+ video: meeting.mediaProperties.videoStream.outputStream.getTracks()[0],
3941
+ screenShareVideo:
3942
+ meeting.mediaProperties.shareVideoStream.outputStream.getTracks()[0],
3943
+ screenShareAudio:
3944
+ meeting.mediaProperties.shareVideoStream.outputStream.getTracks()[0],
3945
+ },
3946
+ direction: {
3947
+ audio: 'inactive',
3948
+ video: 'inactive',
3949
+ screenShareVideo: 'sendrecv',
3950
+ },
3951
+ remoteQualityLevel: 'HIGH',
3952
+ });
3784
3953
  assert.isTrue(myPromiseResolved);
3785
3954
  });
3786
3955
  });
@@ -3798,15 +3967,13 @@ describe('plugin-meetings', () => {
3798
3967
  receiveVideo: true,
3799
3968
  };
3800
3969
  meeting.mediaProperties.mediaDirection = mediaDirection;
3801
- meeting.mediaProperties.remoteVideoStream = sinon
3802
- .stub()
3803
- .returns({
3804
- outputStream: {
3805
- getTracks: () => {
3806
- id: 'some mock id'
3807
- }
3808
- }
3809
- });
3970
+ meeting.mediaProperties.remoteVideoStream = sinon.stub().returns({
3971
+ outputStream: {
3972
+ getTracks: () => {
3973
+ id: 'some mock id';
3974
+ },
3975
+ },
3976
+ });
3810
3977
 
3811
3978
  meeting.meetingRequest.changeVideoLayoutDebounced = sinon
3812
3979
  .stub()
@@ -3883,7 +4050,9 @@ describe('plugin-meetings', () => {
3883
4050
  });
3884
4051
 
3885
4052
  meeting.mediaProperties.mediaDirection.receiveShare = true;
3886
- meeting.mediaProperties.remoteShareStream = sinon.stub().returns({mockTrack: 'mockTrack'});
4053
+ meeting.mediaProperties.remoteShareStream = sinon
4054
+ .stub()
4055
+ .returns({mockTrack: 'mockTrack'});
3887
4056
 
3888
4057
  // now call it again with just content
3889
4058
  await meeting.changeVideoLayout(layoutTypeSingle, {content: {width: 500, height: 600}});
@@ -3952,7 +4121,9 @@ describe('plugin-meetings', () => {
3952
4121
 
3953
4122
  it('does not call changeVideoLayoutDebounced if renderInfo content changes only very slightly', async () => {
3954
4123
  meeting.mediaProperties.mediaDirection.receiveShare = true;
3955
- meeting.mediaProperties.remoteShareStream = sinon.stub().returns({mockTrack: 'mockTrack'});
4124
+ meeting.mediaProperties.remoteShareStream = sinon
4125
+ .stub()
4126
+ .returns({mockTrack: 'mockTrack'});
3956
4127
 
3957
4128
  await meeting.changeVideoLayout(layoutTypeSingle, {
3958
4129
  main: {width: 500, height: 510},
@@ -3992,7 +4163,9 @@ describe('plugin-meetings', () => {
3992
4163
 
3993
4164
  it('rounds the width and height values to nearest integers', async () => {
3994
4165
  meeting.mediaProperties.mediaDirection.receiveShare = true;
3995
- meeting.mediaProperties.remoteShareStream = sinon.stub().returns({mockTrack: 'mockTrack'});
4166
+ meeting.mediaProperties.remoteShareStream = sinon
4167
+ .stub()
4168
+ .returns({mockTrack: 'mockTrack'});
3996
4169
 
3997
4170
  await meeting.changeVideoLayout(layoutTypeSingle, {
3998
4171
  main: {width: 500.5, height: 510.09},
@@ -4258,11 +4431,7 @@ describe('plugin-meetings', () => {
4258
4431
  FAKE_OPTIONS
4259
4432
  );
4260
4433
 
4261
- assert.calledWith(
4262
- meeting.parseMeetingInfo,
4263
- {body: FAKE_MEETING_INFO, url: FAKE_MEETING_INFO_LOOKUP_URL},
4264
- FAKE_DESTINATION
4265
- );
4434
+ assert.calledWith(meeting.parseMeetingInfo, FAKE_MEETING_INFO, FAKE_DESTINATION);
4266
4435
  assert.deepEqual(meeting.meetingInfo, {
4267
4436
  ...FAKE_MEETING_INFO,
4268
4437
  meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
@@ -4315,12 +4484,8 @@ describe('plugin-meetings', () => {
4315
4484
  {meetingId: meeting.id, sendCAevents: false}
4316
4485
  );
4317
4486
 
4318
- // parseMeeting info
4319
- assert.calledWith(
4320
- meeting.parseMeetingInfo,
4321
- {body: FAKE_MEETING_INFO, url: FAKE_MEETING_INFO_LOOKUP_URL},
4322
- FAKE_DESTINATION
4323
- );
4487
+ // parseMeeting info
4488
+ assert.calledWith(meeting.parseMeetingInfo, FAKE_MEETING_INFO, FAKE_DESTINATION);
4324
4489
 
4325
4490
  assert.deepEqual(meeting.meetingInfo, {
4326
4491
  ...FAKE_MEETING_INFO,
@@ -4456,7 +4621,7 @@ describe('plugin-meetings', () => {
4456
4621
  await assert.isRejected(
4457
4622
  meeting.fetchMeetingInfo({
4458
4623
  password: 'aaa',
4459
- sendCAevents: true
4624
+ sendCAevents: true,
4460
4625
  }),
4461
4626
  CaptchaError
4462
4627
  );
@@ -4621,6 +4786,166 @@ describe('plugin-meetings', () => {
4621
4786
  });
4622
4787
  });
4623
4788
 
4789
+ describe('#injectMeetingInfo', () => {
4790
+ const FAKE_PASSWORD = '123456';
4791
+ const FAKE_CAPTCHA_CODE = '654321';
4792
+ const FAKE_DESTINATION = 'something@somecompany.com';
4793
+ const FAKE_TYPE = _SIP_URI_;
4794
+ const FAKE_INSTALLED_ORG_ID = '123456';
4795
+ const FAKE_MEETING_INFO_LOOKUP_URL = 'meetingLookupUrl';
4796
+
4797
+ const FAKE_SDK_CAPTCHA_INFO = {};
4798
+ const FAKE_MEETING_INFO = {
4799
+ conversationUrl: 'some_convo_url',
4800
+ locusUrl: 'some_locus_url',
4801
+ sipUrl: 'some_sip_url', // or sipMeetingUri
4802
+ meetingNumber: '123456', // this.config.experimental.enableUnifiedMeetings
4803
+ hostId: 'some_host_id', // this.owner;
4804
+ };
4805
+
4806
+ [
4807
+ {
4808
+ input: {
4809
+ meetingInfo: FAKE_MEETING_INFO,
4810
+ meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
4811
+ },
4812
+ expected: {
4813
+ meetingInfo: {
4814
+ ...FAKE_MEETING_INFO,
4815
+ meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
4816
+ },
4817
+ },
4818
+ },
4819
+ {
4820
+ input: {
4821
+ meetingInfo: undefined,
4822
+ meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
4823
+ },
4824
+ expected: {meetingInfo: null},
4825
+ },
4826
+ ,
4827
+ {
4828
+ input: {
4829
+ meetingInfo: FAKE_MEETING_INFO,
4830
+ meetingLookupUrl: undefined,
4831
+ },
4832
+ expected: {
4833
+ meetingInfo: {
4834
+ ...FAKE_MEETING_INFO,
4835
+ meetingLookupUrl: undefined,
4836
+ },
4837
+ },
4838
+ },
4839
+ ,
4840
+ {
4841
+ input: {
4842
+ meetingInfo: undefined,
4843
+ meetingLookupUrl: undefined,
4844
+ },
4845
+ expected: {meetingInfo: null},
4846
+ },
4847
+ ].forEach(({input, expected}) => {
4848
+ it(`calls meetingInfoProvider with all the right parameters and parses the result when ${JSON.stringify(
4849
+ input
4850
+ )}`, async () => {
4851
+ meeting.requiredCaptcha = FAKE_SDK_CAPTCHA_INFO;
4852
+ meeting.destination = FAKE_DESTINATION;
4853
+ meeting.destinationType = FAKE_TYPE;
4854
+ meeting.config.installedOrgID = FAKE_INSTALLED_ORG_ID;
4855
+ meeting.parseMeetingInfo = sinon.stub().returns(undefined);
4856
+ meeting.updateMeetingActions = sinon.stub().returns(undefined);
4857
+
4858
+ await meeting.injectMeetingInfo(
4859
+ input.meetingInfo,
4860
+ {sendCAevents: true},
4861
+ input.meetingLookupUrl
4862
+ );
4863
+
4864
+ assert.calledWith(meeting.parseMeetingInfo, input.meetingInfo, FAKE_DESTINATION);
4865
+ assert.deepEqual(meeting.meetingInfo, expected.meetingInfo);
4866
+ assert.equal(meeting.passwordStatus, PASSWORD_STATUS.NOT_REQUIRED);
4867
+ assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.NONE);
4868
+ assert.equal(meeting.requiredCaptcha, null);
4869
+ assert.calledThrice(TriggerProxy.trigger);
4870
+ assert.calledWith(
4871
+ TriggerProxy.trigger,
4872
+ meeting,
4873
+ {file: 'meetings', function: 'fetchMeetingInfo'},
4874
+ 'meeting:meetingInfoAvailable'
4875
+ );
4876
+ assert.calledWith(meeting.updateMeetingActions);
4877
+ });
4878
+ });
4879
+
4880
+ it('fails if captchaCode is provided when captcha not needed', async () => {
4881
+ meeting.attrs.meetingInfoProvider = {
4882
+ fetchMeetingInfo: sinon.stub().resolves(),
4883
+ };
4884
+ meeting.requiredCaptcha = null;
4885
+ meeting.destination = FAKE_DESTINATION;
4886
+ meeting.destinationType = FAKE_TYPE;
4887
+
4888
+ await assert.isRejected(
4889
+ meeting.injectMeetingInfo(
4890
+ {},
4891
+ {
4892
+ captchaCode: FAKE_CAPTCHA_CODE,
4893
+ }
4894
+ ),
4895
+ Error,
4896
+ 'injectMeetingInfo() called with captchaCode when captcha was not required'
4897
+ );
4898
+
4899
+ assert.notCalled(meeting.attrs.meetingInfoProvider.fetchMeetingInfo);
4900
+ assert.calledTwice(TriggerProxy.trigger); //meetingInfoAvailable event not triggered
4901
+ assert.neverCalledWith(
4902
+ TriggerProxy.trigger,
4903
+ meeting,
4904
+ {file: 'meetings', function: 'fetchMeetingInfo'},
4905
+ 'meeting:meetingInfoAvailable'
4906
+ );
4907
+ });
4908
+
4909
+ it('fails if password is provided when not required', async () => {
4910
+ meeting.attrs.meetingInfoProvider = {
4911
+ fetchMeetingInfo: sinon.stub().resolves(),
4912
+ };
4913
+ meeting.passwordStatus = PASSWORD_STATUS.NOT_REQUIRED;
4914
+ meeting.destination = FAKE_DESTINATION;
4915
+ meeting.destinationType = FAKE_TYPE;
4916
+
4917
+ await assert.isRejected(
4918
+ meeting.injectMeetingInfo(
4919
+ {},
4920
+ {
4921
+ password: FAKE_PASSWORD,
4922
+ }
4923
+ ),
4924
+ Error,
4925
+ 'injectMeetingInfo() called with password when password was not required'
4926
+ );
4927
+
4928
+ assert.notCalled(meeting.attrs.meetingInfoProvider.fetchMeetingInfo);
4929
+ assert.calledTwice(TriggerProxy.trigger); //meetingInfoAvailable event not triggered
4930
+ assert.neverCalledWith(
4931
+ TriggerProxy.trigger,
4932
+ meeting,
4933
+ {file: 'meetings', function: 'fetchMeetingInfo'},
4934
+ 'meeting:meetingInfoAvailable'
4935
+ );
4936
+ });
4937
+
4938
+ it('should clean the fetch meeting info timeout', async () => {
4939
+ meeting.fetchMeetingInfoTimeoutId = 42; // pending delayed request
4940
+
4941
+ await meeting.injectMeetingInfo(FAKE_MEETING_INFO, {
4942
+ sendCAevents: true,
4943
+ });
4944
+
4945
+ assert.equal(meeting.fetchMeetingInfoTimeoutId, undefined);
4946
+ });
4947
+ });
4948
+
4624
4949
  describe('#refreshPermissionToken', () => {
4625
4950
  const FAKE_MEETING_INFO = {
4626
4951
  conversationUrl: 'some_convo_url',
@@ -4641,9 +4966,9 @@ describe('plugin-meetings', () => {
4641
4966
  meeting.destination = 'meeting-destination';
4642
4967
  meeting.destinationType = 'meeting-destination-type';
4643
4968
  meeting.updateMeetingActions = sinon.stub().returns(undefined);
4644
-
4969
+
4645
4970
  meeting.meetingInfoExtraParams = {
4646
- extraParam1: 'value1'
4971
+ extraParam1: 'value1',
4647
4972
  };
4648
4973
  meeting.attrs.meetingInfoProvider = {
4649
4974
  fetchMeetingInfo: sinon
@@ -4678,7 +5003,7 @@ describe('plugin-meetings', () => {
4678
5003
  );
4679
5004
  assert.deepEqual(meeting.meetingInfo, {
4680
5005
  ...FAKE_MEETING_INFO,
4681
- meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL
5006
+ meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
4682
5007
  });
4683
5008
  assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.NONE);
4684
5009
  assert.equal(meeting.requiredCaptcha, null);
@@ -4693,7 +5018,9 @@ describe('plugin-meetings', () => {
4693
5018
  assert.calledWith(meeting.updateMeetingActions);
4694
5019
 
4695
5020
  assert.calledWith(
4696
- Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
5021
+ Metrics.sendBehavioralMetric,
5022
+ BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH,
5023
+ {
4697
5024
  correlationId: meeting.correlationId,
4698
5025
  timeLeft: FAKE_TIMESTAMPS.timeLeft,
4699
5026
  expiryTime: FAKE_TIMESTAMPS.expiryTime,
@@ -4721,7 +5048,7 @@ describe('plugin-meetings', () => {
4721
5048
  );
4722
5049
  assert.deepEqual(meeting.meetingInfo, {
4723
5050
  ...FAKE_MEETING_INFO,
4724
- meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL
5051
+ meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
4725
5052
  });
4726
5053
  assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.NONE);
4727
5054
  assert.equal(meeting.requiredCaptcha, null);
@@ -4736,7 +5063,9 @@ describe('plugin-meetings', () => {
4736
5063
  assert.calledWith(meeting.updateMeetingActions);
4737
5064
 
4738
5065
  assert.calledWith(
4739
- Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
5066
+ Metrics.sendBehavioralMetric,
5067
+ BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH,
5068
+ {
4740
5069
  correlationId: meeting.correlationId,
4741
5070
  timeLeft: undefined,
4742
5071
  expiryTime: undefined,
@@ -4767,13 +5096,13 @@ describe('plugin-meetings', () => {
4767
5096
  'locus-id',
4768
5097
  {
4769
5098
  extraParam1: 'value1',
4770
- permissionToken: FAKE_PERMISSION_TOKEN
5099
+ permissionToken: FAKE_PERMISSION_TOKEN,
4771
5100
  },
4772
5101
  {meetingId: meeting.id, sendCAevents: true}
4773
5102
  );
4774
5103
  assert.deepEqual(meeting.meetingInfo, {
4775
5104
  ...FAKE_MEETING_INFO,
4776
- meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL
5105
+ meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL,
4777
5106
  });
4778
5107
  assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.NONE);
4779
5108
  assert.equal(meeting.requiredCaptcha, null);
@@ -4788,7 +5117,9 @@ describe('plugin-meetings', () => {
4788
5117
  assert.calledWith(meeting.updateMeetingActions);
4789
5118
 
4790
5119
  assert.calledWith(
4791
- Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
5120
+ Metrics.sendBehavioralMetric,
5121
+ BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH,
5122
+ {
4792
5123
  correlationId: meeting.correlationId,
4793
5124
  timeLeft: FAKE_TIMESTAMPS.timeLeft,
4794
5125
  expiryTime: FAKE_TIMESTAMPS.expiryTime,
@@ -4817,9 +5148,12 @@ describe('plugin-meetings', () => {
4817
5148
  assert.calledWith(meeting.updateMeetingActions);
4818
5149
 
4819
5150
  assert.calledWith(
4820
- Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH_ERROR, {
5151
+ Metrics.sendBehavioralMetric,
5152
+ BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH_ERROR,
5153
+ {
4821
5154
  correlationId: meeting.correlationId,
4822
- reason: 'Not allowed to execute the function, some properties on server, or local client state do not allow you to complete this action.',
5155
+ reason:
5156
+ 'Not allowed to execute the function, some properties on server, or local client state do not allow you to complete this action.',
4823
5157
  stack: sinon.match.any,
4824
5158
  }
4825
5159
  );
@@ -4838,13 +5172,18 @@ describe('plugin-meetings', () => {
4838
5172
  assert.deepEqual(meeting.meetingInfo, {
4839
5173
  ...FAKE_MEETING_INFO,
4840
5174
  });
4841
- assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD);
5175
+ assert.equal(
5176
+ meeting.meetingInfoFailureReason,
5177
+ MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD
5178
+ );
4842
5179
  assert.equal(meeting.requiredCaptcha, null);
4843
5180
  assert.equal(meeting.passwordStatus, PASSWORD_STATUS.REQUIRED);
4844
5181
  assert.calledWith(meeting.updateMeetingActions);
4845
5182
 
4846
5183
  assert.calledWith(
4847
- Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH_ERROR, {
5184
+ Metrics.sendBehavioralMetric,
5185
+ BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH_ERROR,
5186
+ {
4848
5187
  correlationId: meeting.correlationId,
4849
5188
  reason: 'Password is required, please use verifyPassword()',
4850
5189
  stack: sinon.match.any,
@@ -4868,13 +5207,18 @@ describe('plugin-meetings', () => {
4868
5207
  await assert.isRejected(meeting.refreshPermissionToken());
4869
5208
 
4870
5209
  assert.calledOnce(meeting.attrs.meetingInfoProvider.fetchMeetingInfo);
4871
- assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD);
5210
+ assert.equal(
5211
+ meeting.meetingInfoFailureReason,
5212
+ MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD
5213
+ );
4872
5214
  assert.equal(meeting.requiredCaptcha, FAKE_SDK_CAPTCHA_INFO);
4873
5215
  assert.equal(meeting.passwordStatus, PASSWORD_STATUS.REQUIRED);
4874
5216
  assert.calledWith(meeting.updateMeetingActions);
4875
5217
 
4876
5218
  assert.calledWith(
4877
- Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH_ERROR, {
5219
+ Metrics.sendBehavioralMetric,
5220
+ BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH_ERROR,
5221
+ {
4878
5222
  correlationId: meeting.correlationId,
4879
5223
  reason: 'Captcha is required.',
4880
5224
  stack: sinon.match.any,
@@ -5299,14 +5643,26 @@ describe('plugin-meetings', () => {
5299
5643
  describe('#updateCallStateForMetrics', () => {
5300
5644
  it('should update the callState, overriding existing values', () => {
5301
5645
  assert.deepEqual(meeting.callStateForMetrics, {correlationId});
5302
- meeting.updateCallStateForMetrics({correlationId: uuid1, joinTrigger: 'jt', loginType: 'lt'});
5303
- assert.deepEqual(meeting.callStateForMetrics, {correlationId: uuid1, joinTrigger: 'jt', loginType: 'lt'});
5646
+ meeting.updateCallStateForMetrics({
5647
+ correlationId: uuid1,
5648
+ joinTrigger: 'jt',
5649
+ loginType: 'lt',
5650
+ });
5651
+ assert.deepEqual(meeting.callStateForMetrics, {
5652
+ correlationId: uuid1,
5653
+ joinTrigger: 'jt',
5654
+ loginType: 'lt',
5655
+ });
5304
5656
  });
5305
5657
 
5306
5658
  it('should update the callState, keeping non-supplied values', () => {
5307
5659
  assert.deepEqual(meeting.callStateForMetrics, {correlationId});
5308
5660
  meeting.updateCallStateForMetrics({joinTrigger: 'jt', loginType: 'lt'});
5309
- assert.deepEqual(meeting.callStateForMetrics, {correlationId, joinTrigger: 'jt', loginType: 'lt'});
5661
+ assert.deepEqual(meeting.callStateForMetrics, {
5662
+ correlationId,
5663
+ joinTrigger: 'jt',
5664
+ loginType: 'lt',
5665
+ });
5310
5666
  });
5311
5667
  });
5312
5668
 
@@ -5320,35 +5676,35 @@ describe('plugin-meetings', () => {
5320
5676
  beforeEach(() => {
5321
5677
  audioStream = {
5322
5678
  getSettings: sinon.stub().returns({
5323
- deviceId: 'some device id'
5679
+ deviceId: 'some device id',
5324
5680
  }),
5325
5681
  on: sinon.stub(),
5326
5682
  off: sinon.stub(),
5327
- }
5683
+ };
5328
5684
 
5329
5685
  videoStream = {
5330
5686
  getSettings: sinon.stub().returns({
5331
- deviceId: 'some device id'
5687
+ deviceId: 'some device id',
5332
5688
  }),
5333
5689
  on: sinon.stub(),
5334
5690
  off: sinon.stub(),
5335
- }
5691
+ };
5336
5692
 
5337
5693
  audioShareStream = {
5338
5694
  on: sinon.stub(),
5339
5695
  off: sinon.stub(),
5340
5696
  getSettings: sinon.stub().returns({
5341
- deviceId: 'some device id'
5697
+ deviceId: 'some device id',
5342
5698
  }),
5343
- }
5699
+ };
5344
5700
 
5345
5701
  videoShareStream = {
5346
5702
  on: sinon.stub(),
5347
5703
  off: sinon.stub(),
5348
5704
  getSettings: sinon.stub().returns({
5349
- deviceId: 'some device id'
5705
+ deviceId: 'some device id',
5350
5706
  }),
5351
- }
5707
+ };
5352
5708
 
5353
5709
  meeting.requestScreenShareFloor = sinon.stub().resolves({});
5354
5710
  meeting.releaseScreenShareFloor = sinon.stub().resolves({});
@@ -5359,20 +5715,32 @@ describe('plugin-meetings', () => {
5359
5715
  };
5360
5716
  meeting.isMultistream = true;
5361
5717
  meeting.mediaProperties.webrtcMediaConnection = {};
5362
- meeting.audio = { handleLocalStreamChange: sinon.stub()};
5363
- meeting.video = { handleLocalStreamChange: sinon.stub()};
5718
+ meeting.audio = {handleLocalStreamChange: sinon.stub()};
5719
+ meeting.video = {handleLocalStreamChange: sinon.stub()};
5364
5720
  fakeMultistreamRoapMediaConnection = {
5365
5721
  createSendSlot: () => {
5366
5722
  return {
5367
5723
  publishStream: sinon.stub(),
5368
5724
  unpublishStream: sinon.stub(),
5369
- }
5370
- }
5371
- }
5372
- meeting.sendSlotManager.createSlot(fakeMultistreamRoapMediaConnection, MediaType.VideoSlides);
5373
- meeting.sendSlotManager.createSlot(fakeMultistreamRoapMediaConnection, MediaType.AudioSlides);
5374
- meeting.sendSlotManager.createSlot(fakeMultistreamRoapMediaConnection, MediaType.AudioMain);
5375
- meeting.sendSlotManager.createSlot(fakeMultistreamRoapMediaConnection, MediaType.VideoMain);
5725
+ };
5726
+ },
5727
+ };
5728
+ meeting.sendSlotManager.createSlot(
5729
+ fakeMultistreamRoapMediaConnection,
5730
+ MediaType.VideoSlides
5731
+ );
5732
+ meeting.sendSlotManager.createSlot(
5733
+ fakeMultistreamRoapMediaConnection,
5734
+ MediaType.AudioSlides
5735
+ );
5736
+ meeting.sendSlotManager.createSlot(
5737
+ fakeMultistreamRoapMediaConnection,
5738
+ MediaType.AudioMain
5739
+ );
5740
+ meeting.sendSlotManager.createSlot(
5741
+ fakeMultistreamRoapMediaConnection,
5742
+ MediaType.VideoMain
5743
+ );
5376
5744
  });
5377
5745
  afterEach(() => {
5378
5746
  sinon.restore();
@@ -5496,18 +5864,14 @@ describe('plugin-meetings', () => {
5496
5864
  });
5497
5865
 
5498
5866
  const checkAudioUnpublished = () => {
5499
- assert.calledOnce(
5500
- meeting.sendSlotManager.getSlot(MediaType.AudioMain).unpublishStream
5501
- );
5867
+ assert.calledOnce(meeting.sendSlotManager.getSlot(MediaType.AudioMain).unpublishStream);
5502
5868
 
5503
5869
  assert.equal(meeting.mediaProperties.audioStream, null);
5504
5870
  assert.equal(meeting.mediaProperties.mediaDirection.sendAudio, 'fake value');
5505
5871
  };
5506
5872
 
5507
5873
  const checkVideoUnpublished = () => {
5508
- assert.calledOnce(
5509
- meeting.sendSlotManager.getSlot(MediaType.VideoMain).unpublishStream
5510
- );
5874
+ assert.calledOnce(meeting.sendSlotManager.getSlot(MediaType.VideoMain).unpublishStream);
5511
5875
 
5512
5876
  assert.equal(meeting.mediaProperties.videoStream, null);
5513
5877
  assert.equal(meeting.mediaProperties.mediaDirection.sendVideo, 'fake value');
@@ -5540,12 +5904,22 @@ describe('plugin-meetings', () => {
5540
5904
  it('fails if there is no media connection', async () => {
5541
5905
  meeting.mediaProperties.webrtcMediaConnection = undefined;
5542
5906
  await assert.isRejected(
5543
- meeting.unpublishStreams([audioStream, videoStream, videoShareStream, audioShareStream])
5907
+ meeting.unpublishStreams([
5908
+ audioStream,
5909
+ videoStream,
5910
+ videoShareStream,
5911
+ audioShareStream,
5912
+ ])
5544
5913
  );
5545
5914
  });
5546
5915
 
5547
5916
  it('un-publishes the streams correctly (all 4 together)', async () => {
5548
- await meeting.unpublishStreams([audioStream, videoStream, videoShareStream, audioShareStream]);
5917
+ await meeting.unpublishStreams([
5918
+ audioStream,
5919
+ videoStream,
5920
+ videoShareStream,
5921
+ audioShareStream,
5922
+ ]);
5549
5923
 
5550
5924
  checkAudioUnpublished();
5551
5925
  checkVideoUnpublished();
@@ -5605,40 +5979,48 @@ describe('plugin-meetings', () => {
5605
5979
  return {
5606
5980
  setCodecParameters: sinon.stub().resolves(),
5607
5981
  deleteCodecParameters: sinon.stub().resolves(),
5608
- }
5609
- }
5982
+ };
5983
+ },
5610
5984
  };
5611
- meeting.sendSlotManager.createSlot(fakeMultistreamRoapMediaConnection, MediaType.AudioMain, false);
5985
+ meeting.sendSlotManager.createSlot(
5986
+ fakeMultistreamRoapMediaConnection,
5987
+ MediaType.AudioMain,
5988
+ false
5989
+ );
5612
5990
  meeting.mediaProperties.webrtcMediaConnection = {};
5613
5991
  });
5614
5992
  afterEach(() => {
5615
5993
  sinon.restore();
5616
5994
  });
5617
- [
5618
- {shouldEnableMusicMode: true},
5619
- {shouldEnableMusicMode: false},
5620
- ].forEach(({shouldEnableMusicMode}) => {
5621
- it(`fails if there is no media connection for shouldEnableMusicMode: ${shouldEnableMusicMode}`, async () => {
5622
- meeting.mediaProperties.webrtcMediaConnection = undefined;
5623
- await assert.isRejected(meeting.enableMusicMode(shouldEnableMusicMode));
5624
- });
5625
- });
5995
+ [{shouldEnableMusicMode: true}, {shouldEnableMusicMode: false}].forEach(
5996
+ ({shouldEnableMusicMode}) => {
5997
+ it(`fails if there is no media connection for shouldEnableMusicMode: ${shouldEnableMusicMode}`, async () => {
5998
+ meeting.mediaProperties.webrtcMediaConnection = undefined;
5999
+ await assert.isRejected(meeting.enableMusicMode(shouldEnableMusicMode));
6000
+ });
6001
+ }
6002
+ );
5626
6003
 
5627
6004
  it('should set the codec parameters when shouldEnableMusicMode is true', async () => {
5628
6005
  await meeting.enableMusicMode(true);
5629
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).setCodecParameters, {
5630
- maxaveragebitrate: '64000',
5631
- maxplaybackrate: '48000',
5632
- });
5633
- assert.notCalled(meeting.sendSlotManager.getSlot(MediaType.AudioMain).deleteCodecParameters);
6006
+ assert.calledOnceWithExactly(
6007
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).setCodecParameters,
6008
+ {
6009
+ maxaveragebitrate: '64000',
6010
+ maxplaybackrate: '48000',
6011
+ }
6012
+ );
6013
+ assert.notCalled(
6014
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).deleteCodecParameters
6015
+ );
5634
6016
  });
5635
6017
 
5636
6018
  it('should set the codec parameters when shouldEnableMusicMode is false', async () => {
5637
6019
  await meeting.enableMusicMode(false);
5638
- assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).deleteCodecParameters, [
5639
- 'maxaveragebitrate',
5640
- 'maxplaybackrate',
5641
- ]);
6020
+ assert.calledOnceWithExactly(
6021
+ meeting.sendSlotManager.getSlot(MediaType.AudioMain).deleteCodecParameters,
6022
+ ['maxaveragebitrate', 'maxplaybackrate']
6023
+ );
5642
6024
  assert.notCalled(meeting.sendSlotManager.getSlot(MediaType.AudioMain).setCodecParameters);
5643
6025
  });
5644
6026
  });
@@ -5649,8 +6031,8 @@ describe('plugin-meetings', () => {
5649
6031
  beforeEach(() => {
5650
6032
  const fakeMediaStream = () => {
5651
6033
  return {
5652
- id: 'fake stream'
5653
- }
6034
+ id: 'fake stream',
6035
+ };
5654
6036
  };
5655
6037
 
5656
6038
  sandbox = sinon.createSandbox();
@@ -5717,7 +6099,7 @@ describe('plugin-meetings', () => {
5717
6099
  } catch (err) {
5718
6100
  assert.fail('reconnect should not error after clean up');
5719
6101
  }
5720
- })
6102
+ });
5721
6103
 
5722
6104
  it('should trigger reconnection success and send CA metric', async () => {
5723
6105
  await meeting.reconnect();
@@ -5737,7 +6119,10 @@ describe('plugin-meetings', () => {
5737
6119
  meetingId: meeting.id,
5738
6120
  },
5739
6121
  });
5740
- assert.calledOnceWithExactly(meeting.reconnectionManager.setStatus, RECONNECTION.STATE.COMPLETE);
6122
+ assert.calledOnceWithExactly(
6123
+ meeting.reconnectionManager.setStatus,
6124
+ RECONNECTION.STATE.COMPLETE
6125
+ );
5741
6126
  });
5742
6127
 
5743
6128
  it('should reset after reconnection success', async () => {
@@ -5832,7 +6217,7 @@ describe('plugin-meetings', () => {
5832
6217
  let eventListeners;
5833
6218
  const fakeStream = {
5834
6219
  id: 'stream',
5835
- getTracks: () => [{ id: 'track', addEventListener: sinon.stub() }]
6220
+ getTracks: () => [{id: 'track', addEventListener: sinon.stub()}],
5836
6221
  };
5837
6222
 
5838
6223
  beforeEach(() => {
@@ -5899,7 +6284,7 @@ describe('plugin-meetings', () => {
5899
6284
  });
5900
6285
 
5901
6286
  assert.notCalled(webex.internal.newMetrics.submitClientEvent);
5902
- })
6287
+ });
5903
6288
 
5904
6289
  it('sends client.ice.start correctly when hasMediaConnectionConnectedAtLeastOnce = false', () => {
5905
6290
  meeting.hasMediaConnectionConnectedAtLeastOnce = false;
@@ -5915,7 +6300,7 @@ describe('plugin-meetings', () => {
5915
6300
  meetingId: meeting.id,
5916
6301
  },
5917
6302
  });
5918
- })
6303
+ });
5919
6304
  });
5920
6305
 
5921
6306
  describe('submitClientEvent on connectionSuccess', () => {
@@ -6043,22 +6428,17 @@ describe('plugin-meetings', () => {
6043
6428
 
6044
6429
  const checkBehavioralMetricSent = (hasMediaConnectionConnectedAtLeastOnce = false) => {
6045
6430
  assert.calledOnce(Metrics.sendBehavioralMetric);
6046
- assert.calledWith(
6047
- Metrics.sendBehavioralMetric,
6048
- BEHAVIORAL_METRICS.CONNECTION_FAILURE,
6049
- {
6050
- correlation_id: meeting.correlationId,
6051
- locus_id: meeting.locusUrl.split('/').pop(),
6052
- networkStatus: meeting.networkStatus,
6053
- hasMediaConnectionConnectedAtLeastOnce,
6054
- },
6055
- );
6431
+ assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.CONNECTION_FAILURE, {
6432
+ correlation_id: meeting.correlationId,
6433
+ locus_id: meeting.locusUrl.split('/').pop(),
6434
+ networkStatus: meeting.networkStatus,
6435
+ hasMediaConnectionConnectedAtLeastOnce,
6436
+ });
6056
6437
  };
6057
6438
 
6058
6439
  it('handles "Disconnected" state correctly when waitForIceReconnect resolves', async () => {
6059
6440
  meeting.reconnectionManager.waitForIceReconnect = sinon.stub().resolves();
6060
6441
 
6061
-
6062
6442
  mockDisconnectedEvent();
6063
6443
 
6064
6444
  await testUtils.flushPromises();
@@ -6072,14 +6452,13 @@ describe('plugin-meetings', () => {
6072
6452
 
6073
6453
  it('handles "Disconnected" state correctly when waitForIceReconnect rejects and hasMediaConnectionConnectedAtLeastOnce = true', async () => {
6074
6454
  const FAKE_ERROR = {fatal: true};
6075
- const getErrorPayloadForClientErrorCodeStub = webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode = sinon
6076
- .stub()
6077
- .returns(FAKE_ERROR);
6455
+ const getErrorPayloadForClientErrorCodeStub =
6456
+ (webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode =
6457
+ sinon.stub().returns(FAKE_ERROR));
6078
6458
  meeting.waitForMediaConnectionConnected = sinon.stub().resolves();
6079
6459
  meeting.reconnectionManager.waitForIceReconnect = sinon.stub().rejects();
6080
6460
  meeting.hasMediaConnectionConnectedAtLeastOnce = true;
6081
6461
 
6082
-
6083
6462
  mockDisconnectedEvent();
6084
6463
 
6085
6464
  await testUtils.flushPromises();
@@ -6094,7 +6473,6 @@ describe('plugin-meetings', () => {
6094
6473
  it('handles "Disconnected" state correctly when waitForIceReconnect rejects and hasMediaConnectionConnectedAtLeastOnce = false', async () => {
6095
6474
  meeting.reconnectionManager.waitForIceReconnect = sinon.stub().rejects();
6096
6475
 
6097
-
6098
6476
  mockDisconnectedEvent();
6099
6477
 
6100
6478
  await testUtils.flushPromises();
@@ -6108,7 +6486,6 @@ describe('plugin-meetings', () => {
6108
6486
  });
6109
6487
 
6110
6488
  describe('CONNECTION_STATE_CHANGED event when state = "Failed"', () => {
6111
-
6112
6489
  const mockFailedEvent = () => {
6113
6490
  meeting.setupMediaConnectionListeners();
6114
6491
  eventListeners[Event.CONNECTION_STATE_CHANGED]({
@@ -6118,16 +6495,12 @@ describe('plugin-meetings', () => {
6118
6495
 
6119
6496
  const checkBehavioralMetricSent = (hasMediaConnectionConnectedAtLeastOnce = false) => {
6120
6497
  assert.calledOnce(Metrics.sendBehavioralMetric);
6121
- assert.calledWith(
6122
- Metrics.sendBehavioralMetric,
6123
- BEHAVIORAL_METRICS.CONNECTION_FAILURE,
6124
- {
6125
- correlation_id: meeting.correlationId,
6126
- locus_id: meeting.locusUrl.split('/').pop(),
6127
- networkStatus: meeting.networkStatus,
6128
- hasMediaConnectionConnectedAtLeastOnce,
6129
- },
6130
- );
6498
+ assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.CONNECTION_FAILURE, {
6499
+ correlation_id: meeting.correlationId,
6500
+ locus_id: meeting.locusUrl.split('/').pop(),
6501
+ networkStatus: meeting.networkStatus,
6502
+ hasMediaConnectionConnectedAtLeastOnce,
6503
+ });
6131
6504
  };
6132
6505
 
6133
6506
  it('handles "Failed" state correctly when hasMediaConnectionConnectedAtLeastOnce = false', async () => {
@@ -6426,7 +6799,7 @@ describe('plugin-meetings', () => {
6426
6799
 
6427
6800
  it('handles OFFER message correctly when request fails', async () => {
6428
6801
  const clock = sinon.useFakeTimers();
6429
- sinon.spy(clock, "clearTimeout");
6802
+ sinon.spy(clock, 'clearTimeout');
6430
6803
  meeting.deferSDPAnswer = {reject: sinon.stub()};
6431
6804
  meeting.sdpResponseTimer = '1234';
6432
6805
  sendRoapMediaRequestStub.rejects();
@@ -7121,8 +7494,8 @@ describe('plugin-meetings', () => {
7121
7494
  newLocusServices.services.webcast.url
7122
7495
  );
7123
7496
  assert.calledWith(
7124
- meeting.webinar.webinarAttendeesSearchingUrlUpdate,
7125
- newLocusServices.services.webinarAttendeesSearching.url
7497
+ meeting.webinar.webinarAttendeesSearchingUrlUpdate,
7498
+ newLocusServices.services.webinarAttendeesSearching.url
7126
7499
  );
7127
7500
  assert.calledOnce(meeting.recordingController.setSessionId);
7128
7501
  done();
@@ -7298,20 +7671,19 @@ describe('plugin-meetings', () => {
7298
7671
  });
7299
7672
 
7300
7673
  describe('#setPermissionTokenPayload', () => {
7301
-
7302
7674
  let now;
7303
7675
  let clock;
7304
-
7676
+
7305
7677
  beforeEach(() => {
7306
7678
  now = Date.now();
7307
-
7679
+
7308
7680
  // mock `new Date()` with constant `now`
7309
7681
  clock = sinon.useFakeTimers(now);
7310
7682
  });
7311
-
7683
+
7312
7684
  afterEach(() => {
7313
7685
  clock.restore();
7314
- })
7686
+ });
7315
7687
  it('sets correctly', () => {
7316
7688
  assert.notOk(meeting.permissionTokenPayload);
7317
7689
 
@@ -7333,10 +7705,12 @@ describe('plugin-meetings', () => {
7333
7705
 
7334
7706
  const testUrl = 'https://example.com';
7335
7707
 
7336
- const policyData = {permission: {
7337
- userPolicies: {a: true},
7338
- enforceVBGImagesURL: testUrl
7339
- }};
7708
+ const policyData = {
7709
+ permission: {
7710
+ userPolicies: {a: true},
7711
+ enforceVBGImagesURL: testUrl,
7712
+ },
7713
+ };
7340
7714
  meeting.permissionTokenPayload = policyData;
7341
7715
 
7342
7716
  meeting.setSelfUserPolicies();
@@ -7437,8 +7811,11 @@ describe('plugin-meetings', () => {
7437
7811
  assert.equal(meeting.permissionToken, expectedInfoToParse.permissionToken);
7438
7812
  assert.deepEqual(meeting.selfUserPolicies, expectedInfoToParse.selfUserPolicies);
7439
7813
 
7440
- if(expectedInfoToParse.permissionTokenPayload) {
7441
- assert.deepEqual(meeting.permissionTokenPayload, expectedInfoToParse.permissionTokenPayload);
7814
+ if (expectedInfoToParse.permissionTokenPayload) {
7815
+ assert.deepEqual(
7816
+ meeting.permissionTokenPayload,
7817
+ expectedInfoToParse.permissionTokenPayload
7818
+ );
7442
7819
  }
7443
7820
  };
7444
7821
 
@@ -7447,12 +7824,12 @@ describe('plugin-meetings', () => {
7447
7824
  meeting.config.experimental.enableUnifiedMeetings = true;
7448
7825
 
7449
7826
  const expectedPermissionTokenPayload = {
7450
- exp: "123456",
7827
+ exp: '123456',
7451
7828
  permission: {
7452
7829
  userPolicies: {
7453
- a: true
7454
- }
7455
- }
7830
+ a: true,
7831
+ },
7832
+ },
7456
7833
  };
7457
7834
 
7458
7835
  // generated permissionToken with secret `secret` and
@@ -7461,16 +7838,14 @@ describe('plugin-meetings', () => {
7461
7838
  'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0';
7462
7839
 
7463
7840
  const FAKE_MEETING_INFO = {
7464
- body: {
7465
- conversationUrl: uuid1,
7466
- locusUrl: url1,
7467
- meetingJoinUrl: url2,
7468
- meetingNumber: '12345',
7469
- permissionToken,
7470
- sipMeetingUri: test1,
7471
- sipUrl: test1,
7472
- owner: test2,
7473
- },
7841
+ conversationUrl: uuid1,
7842
+ locusUrl: url1,
7843
+ meetingJoinUrl: url2,
7844
+ meetingNumber: '12345',
7845
+ permissionToken,
7846
+ sipMeetingUri: test1,
7847
+ sipUrl: test1,
7848
+ owner: test2,
7474
7849
  };
7475
7850
 
7476
7851
  meeting.parseMeetingInfo(FAKE_MEETING_INFO);
@@ -7484,7 +7859,7 @@ describe('plugin-meetings', () => {
7484
7859
  owner: test2,
7485
7860
  selfUserPolicies: {a: true},
7486
7861
  permissionToken,
7487
- permissionTokenPayload: expectedPermissionTokenPayload
7862
+ permissionTokenPayload: expectedPermissionTokenPayload,
7488
7863
  };
7489
7864
 
7490
7865
  checkParseMeetingInfo(expectedInfoToParse);
@@ -7502,16 +7877,14 @@ describe('plugin-meetings', () => {
7502
7877
  },
7503
7878
  };
7504
7879
  const FAKE_MEETING_INFO = {
7505
- body: {
7506
- conversationUrl: uuid1,
7507
- locusUrl: url1,
7508
- meetingJoinUrl: url2,
7509
- meetingNumber: '12345',
7510
- permissionToken: 'abc',
7511
- sipMeetingUri: test1,
7512
- sipUrl: test1,
7513
- owner: test2,
7514
- },
7880
+ conversationUrl: uuid1,
7881
+ locusUrl: url1,
7882
+ meetingJoinUrl: url2,
7883
+ meetingNumber: '12345',
7884
+ permissionToken: 'abc',
7885
+ sipMeetingUri: test1,
7886
+ sipUrl: test1,
7887
+ owner: test2,
7515
7888
  };
7516
7889
 
7517
7890
  meeting.parseMeetingInfo(FAKE_MEETING_INFO, FAKE_LOCUS_MEETING);
@@ -7531,16 +7904,14 @@ describe('plugin-meetings', () => {
7531
7904
  meeting.config.experimental = {enableMediaNegotiatedEvent: true};
7532
7905
  meeting.config.experimental.enableUnifiedMeetings = true;
7533
7906
  const FAKE_MEETING_INFO = {
7534
- body: {
7535
- conversationUrl: uuid1,
7536
- locusUrl: url1,
7537
- meetingJoinUrl: url2,
7538
- meetingNumber: '12345',
7539
- permissionToken: 'abc',
7540
- sipMeetingUri: test1,
7541
- sipUrl: test1,
7542
- owner: test2,
7543
- },
7907
+ conversationUrl: uuid1,
7908
+ locusUrl: url1,
7909
+ meetingJoinUrl: url2,
7910
+ meetingNumber: '12345',
7911
+ permissionToken: 'abc',
7912
+ sipMeetingUri: test1,
7913
+ sipUrl: test1,
7914
+ owner: test2,
7544
7915
  };
7545
7916
 
7546
7917
  meeting.parseMeetingInfo(FAKE_MEETING_INFO);
@@ -7561,16 +7932,14 @@ describe('plugin-meetings', () => {
7561
7932
  meeting.config.experimental.enableUnifiedMeetings = true;
7562
7933
  const FAKE_STRING_DESTINATION = 'sipUrl';
7563
7934
  const FAKE_MEETING_INFO = {
7564
- body: {
7565
- conversationUrl: uuid1,
7566
- locusUrl: url1,
7567
- meetingJoinUrl: url2,
7568
- meetingNumber: '12345',
7569
- permissionToken: 'abc',
7570
- sipMeetingUri: test1,
7571
- sipUrl: test1,
7572
- owner: test2,
7573
- },
7935
+ conversationUrl: uuid1,
7936
+ locusUrl: url1,
7937
+ meetingJoinUrl: url2,
7938
+ meetingNumber: '12345',
7939
+ permissionToken: 'abc',
7940
+ sipMeetingUri: test1,
7941
+ sipUrl: test1,
7942
+ owner: test2,
7574
7943
  };
7575
7944
 
7576
7945
  meeting.parseMeetingInfo(FAKE_MEETING_INFO, FAKE_STRING_DESTINATION);
@@ -7589,24 +7958,42 @@ describe('plugin-meetings', () => {
7589
7958
  it('should parse interpretation info correctly', () => {
7590
7959
  const parseInterpretationInfo = sinon.spy(MeetingUtil, 'parseInterpretationInfo');
7591
7960
  const mockToggleOnData = {
7592
- body: {
7593
- meetingSiteSetting: {
7594
- enableHostInterpreterControlSI: true,
7595
- },
7596
- turnOnSimultaneousInterpretation: true,
7597
- simultaneousInterpretation: {
7598
- currentSIInterpreter: false,
7599
- siLanguages: [
7600
- {
7601
- languageCode: 'ar',
7602
- languageGroupId: 4,
7603
- },
7604
- ],
7605
- },
7961
+ meetingSiteSetting: {
7962
+ enableHostInterpreterControlSI: true,
7963
+ },
7964
+ turnOnSimultaneousInterpretation: true,
7965
+ simultaneousInterpretation: {
7966
+ currentSIInterpreter: false,
7967
+ siLanguages: [
7968
+ {
7969
+ languageCode: 'ar',
7970
+ languageGroupId: 4,
7971
+ },
7972
+ ],
7606
7973
  },
7607
7974
  };
7608
7975
  meeting.parseMeetingInfo(mockToggleOnData);
7609
- assert.calledOnceWithExactly(parseInterpretationInfo, meeting, mockToggleOnData.body);
7976
+ assert.calledOnceWithExactly(parseInterpretationInfo, meeting, mockToggleOnData);
7977
+ });
7978
+
7979
+ it('should handle error', () => {
7980
+ const parseInterpretationInfo = sinon.spy(MeetingUtil, 'parseInterpretationInfo');
7981
+ const FAKE_MEETING_INFO = {
7982
+ conversationUrl: uuid1,
7983
+ locusUrl: url1,
7984
+ meetingJoinUrl: url2,
7985
+ meetingNumber: '12345',
7986
+ permissionToken: 'abc',
7987
+ sipMeetingUri: test1,
7988
+ sipUrl: test1,
7989
+ owner: test2,
7990
+ };
7991
+ meeting.parseMeetingInfo(FAKE_MEETING_INFO, undefined, 'Error');
7992
+
7993
+ checkParseMeetingInfo({
7994
+ locusUrl: meeting.locusUrl,
7995
+ });
7996
+ assert.calledOnceWithExactly(parseInterpretationInfo, meeting, FAKE_MEETING_INFO);
7610
7997
  });
7611
7998
  });
7612
7999
 
@@ -8723,7 +9110,6 @@ describe('plugin-meetings', () => {
8723
9110
  REMOTE_B: 'remote-user-B-url',
8724
9111
  };
8725
9112
 
8726
-
8727
9113
  const generateContent = (
8728
9114
  beneficiaryId = null,
8729
9115
  disposition = null,
@@ -8732,7 +9118,7 @@ describe('plugin-meetings', () => {
8732
9118
  ) => ({
8733
9119
  beneficiaryId,
8734
9120
  disposition,
8735
- deviceUrlSharing
9121
+ deviceUrlSharing,
8736
9122
  });
8737
9123
  const generateWhiteboard = (
8738
9124
  beneficiaryId = null,
@@ -8751,7 +9137,7 @@ describe('plugin-meetings', () => {
8751
9137
  annotation,
8752
9138
  url,
8753
9139
  shareInstanceId,
8754
- deviceUrlSharing,
9140
+ deviceUrlSharing
8755
9141
  ) => {
8756
9142
  const newPayload = cloneDeep(payload);
8757
9143
 
@@ -9196,7 +9582,7 @@ describe('plugin-meetings', () => {
9196
9582
  true,
9197
9583
  false,
9198
9584
  USER_IDS.ME,
9199
- RESOURCE_URLS.WHITEBOARD_A,
9585
+ RESOURCE_URLS.WHITEBOARD_A
9200
9586
  );
9201
9587
  const data2 = generateData(
9202
9588
  data1.payload,
@@ -9205,7 +9591,7 @@ describe('plugin-meetings', () => {
9205
9591
  USER_IDS.ME,
9206
9592
  RESOURCE_URLS.WHITEBOARD_A,
9207
9593
  true,
9208
- USER_IDS.ME,
9594
+ USER_IDS.ME
9209
9595
  );
9210
9596
  const data3 = generateData(
9211
9597
  data2.payload,
@@ -9218,9 +9604,21 @@ describe('plugin-meetings', () => {
9218
9604
  undefined,
9219
9605
  undefined,
9220
9606
  undefined,
9221
- DEVICE_URL.LOCAL_WEB,
9607
+ DEVICE_URL.LOCAL_WEB
9608
+ );
9609
+ const data4 = generateData(
9610
+ data3.payload,
9611
+ false,
9612
+ true,
9613
+ USER_IDS.ME,
9614
+ undefined,
9615
+ undefined,
9616
+ undefined,
9617
+ undefined,
9618
+ undefined,
9619
+ undefined,
9620
+ DEVICE_URL.LOCAL_WEB
9222
9621
  );
9223
- const data4 = generateData(data3.payload, false, true, USER_IDS.ME, undefined, undefined, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9224
9622
 
9225
9623
  payloadTestHelper([data1, data2, data3, data4]);
9226
9624
  });
@@ -9253,7 +9651,7 @@ describe('plugin-meetings', () => {
9253
9651
  undefined,
9254
9652
  undefined,
9255
9653
  undefined,
9256
- DEVICE_URL.REMOTE_A,
9654
+ DEVICE_URL.REMOTE_A
9257
9655
  );
9258
9656
  const data4 = generateData(data3.payload, false, true, USER_IDS.REMOTE_A);
9259
9657
 
@@ -9288,9 +9686,21 @@ describe('plugin-meetings', () => {
9288
9686
  undefined,
9289
9687
  undefined,
9290
9688
  undefined,
9291
- DEVICE_URL.LOCAL_WEB,
9689
+ DEVICE_URL.LOCAL_WEB
9690
+ );
9691
+ const data4 = generateData(
9692
+ data3.payload,
9693
+ false,
9694
+ true,
9695
+ USER_IDS.ME,
9696
+ undefined,
9697
+ undefined,
9698
+ undefined,
9699
+ undefined,
9700
+ undefined,
9701
+ undefined,
9702
+ DEVICE_URL.LOCAL_WEB
9292
9703
  );
9293
- const data4 = generateData(data3.payload, false, true, USER_IDS.ME, undefined, undefined, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9294
9704
 
9295
9705
  payloadTestHelper([data1, data2, data3, data4]);
9296
9706
  });
@@ -9323,7 +9733,7 @@ describe('plugin-meetings', () => {
9323
9733
  undefined,
9324
9734
  undefined,
9325
9735
  undefined,
9326
- DEVICE_URL.REMOTE_A,
9736
+ DEVICE_URL.REMOTE_A
9327
9737
  );
9328
9738
  const data4 = generateData(data3.payload, false, true, USER_IDS.REMOTE_A);
9329
9739
 
@@ -9358,7 +9768,7 @@ describe('plugin-meetings', () => {
9358
9768
  undefined,
9359
9769
  undefined,
9360
9770
  undefined,
9361
- DEVICE_URL.REMOTE_B,
9771
+ DEVICE_URL.REMOTE_B
9362
9772
  );
9363
9773
  const data4 = generateData(data3.payload, false, true, USER_IDS.REMOTE_B);
9364
9774
 
@@ -9368,7 +9778,19 @@ describe('plugin-meetings', () => {
9368
9778
 
9369
9779
  describe('Desktop --> Whiteboard A', () => {
9370
9780
  it('Scenario #1: you share desktop and then share whiteboard', () => {
9371
- const data1 = generateData(blankPayload, true, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9781
+ const data1 = generateData(
9782
+ blankPayload,
9783
+ true,
9784
+ true,
9785
+ USER_IDS.ME,
9786
+ undefined,
9787
+ false,
9788
+ undefined,
9789
+ undefined,
9790
+ undefined,
9791
+ undefined,
9792
+ DEVICE_URL.LOCAL_WEB
9793
+ );
9372
9794
  const data2 = generateData(
9373
9795
  data1.payload,
9374
9796
  true,
@@ -9382,7 +9804,19 @@ describe('plugin-meetings', () => {
9382
9804
  });
9383
9805
 
9384
9806
  it('Scenario #2: you share desktop and remote person A shares whiteboard', () => {
9385
- const data1 = generateData(blankPayload, true, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9807
+ const data1 = generateData(
9808
+ blankPayload,
9809
+ true,
9810
+ true,
9811
+ USER_IDS.ME,
9812
+ undefined,
9813
+ false,
9814
+ undefined,
9815
+ undefined,
9816
+ undefined,
9817
+ undefined,
9818
+ DEVICE_URL.LOCAL_WEB
9819
+ );
9386
9820
  const data2 = generateData(
9387
9821
  data1.payload,
9388
9822
  true,
@@ -9396,7 +9830,19 @@ describe('plugin-meetings', () => {
9396
9830
  });
9397
9831
 
9398
9832
  it('Scenario #3: remote person A shares desktop and you share whiteboard', () => {
9399
- const data1 = generateData(blankPayload, true, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A);
9833
+ const data1 = generateData(
9834
+ blankPayload,
9835
+ true,
9836
+ true,
9837
+ USER_IDS.REMOTE_A,
9838
+ undefined,
9839
+ false,
9840
+ undefined,
9841
+ undefined,
9842
+ undefined,
9843
+ undefined,
9844
+ DEVICE_URL.REMOTE_A
9845
+ );
9400
9846
  const data2 = generateData(
9401
9847
  data1.payload,
9402
9848
  true,
@@ -9410,7 +9856,19 @@ describe('plugin-meetings', () => {
9410
9856
  });
9411
9857
 
9412
9858
  it('Scenario #4: remote person A shares desktop and then shares whiteboard', () => {
9413
- const data1 = generateData(blankPayload, true, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A);
9859
+ const data1 = generateData(
9860
+ blankPayload,
9861
+ true,
9862
+ true,
9863
+ USER_IDS.REMOTE_A,
9864
+ undefined,
9865
+ false,
9866
+ undefined,
9867
+ undefined,
9868
+ undefined,
9869
+ undefined,
9870
+ DEVICE_URL.REMOTE_A
9871
+ );
9414
9872
  const data2 = generateData(
9415
9873
  data1.payload,
9416
9874
  true,
@@ -9424,7 +9882,19 @@ describe('plugin-meetings', () => {
9424
9882
  });
9425
9883
 
9426
9884
  it('Scenario #5: remote person A shares desktop and remote person B shares whiteboard', () => {
9427
- const data1 = generateData(blankPayload, true, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A);
9885
+ const data1 = generateData(
9886
+ blankPayload,
9887
+ true,
9888
+ true,
9889
+ USER_IDS.REMOTE_A,
9890
+ undefined,
9891
+ false,
9892
+ undefined,
9893
+ undefined,
9894
+ undefined,
9895
+ undefined,
9896
+ DEVICE_URL.REMOTE_A
9897
+ );
9428
9898
  const data2 = generateData(
9429
9899
  data1.payload,
9430
9900
  true,
@@ -9439,26 +9909,146 @@ describe('plugin-meetings', () => {
9439
9909
  });
9440
9910
  describe('Desktop A --> Desktop B', () => {
9441
9911
  it('Scenario #1: you share desktop using web client and then share using native client', () => {
9442
- const data1 = generateData(blankPayload, true, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9443
- const data2 = generateData(data1.payload, false, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9444
- const data3 = generateData(data2.payload, true, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_MAC);
9445
- const data4 = generateData(data3.payload, false, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_MAC);
9912
+ const data1 = generateData(
9913
+ blankPayload,
9914
+ true,
9915
+ true,
9916
+ USER_IDS.ME,
9917
+ undefined,
9918
+ false,
9919
+ undefined,
9920
+ undefined,
9921
+ undefined,
9922
+ undefined,
9923
+ DEVICE_URL.LOCAL_WEB
9924
+ );
9925
+ const data2 = generateData(
9926
+ data1.payload,
9927
+ false,
9928
+ true,
9929
+ USER_IDS.ME,
9930
+ undefined,
9931
+ false,
9932
+ undefined,
9933
+ undefined,
9934
+ undefined,
9935
+ undefined,
9936
+ DEVICE_URL.LOCAL_WEB
9937
+ );
9938
+ const data3 = generateData(
9939
+ data2.payload,
9940
+ true,
9941
+ true,
9942
+ USER_IDS.ME,
9943
+ undefined,
9944
+ false,
9945
+ undefined,
9946
+ undefined,
9947
+ undefined,
9948
+ undefined,
9949
+ DEVICE_URL.LOCAL_MAC
9950
+ );
9951
+ const data4 = generateData(
9952
+ data3.payload,
9953
+ false,
9954
+ true,
9955
+ USER_IDS.ME,
9956
+ undefined,
9957
+ false,
9958
+ undefined,
9959
+ undefined,
9960
+ undefined,
9961
+ undefined,
9962
+ DEVICE_URL.LOCAL_MAC
9963
+ );
9446
9964
 
9447
9965
  payloadTestHelper([data1, data2, data3, data4]);
9448
9966
  });
9449
9967
 
9450
9968
  it('Scenario #2: you share desktop using web client and remote person A shares desktop', () => {
9451
- const data1 = generateData(blankPayload, true, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9452
- const data2 = generateData(data1.payload, true, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A) ;
9453
- const data3 = generateData(data2.payload, false, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A);
9969
+ const data1 = generateData(
9970
+ blankPayload,
9971
+ true,
9972
+ true,
9973
+ USER_IDS.ME,
9974
+ undefined,
9975
+ false,
9976
+ undefined,
9977
+ undefined,
9978
+ undefined,
9979
+ undefined,
9980
+ DEVICE_URL.LOCAL_WEB
9981
+ );
9982
+ const data2 = generateData(
9983
+ data1.payload,
9984
+ true,
9985
+ true,
9986
+ USER_IDS.REMOTE_A,
9987
+ undefined,
9988
+ false,
9989
+ undefined,
9990
+ undefined,
9991
+ undefined,
9992
+ undefined,
9993
+ DEVICE_URL.REMOTE_A
9994
+ );
9995
+ const data3 = generateData(
9996
+ data2.payload,
9997
+ false,
9998
+ true,
9999
+ USER_IDS.REMOTE_A,
10000
+ undefined,
10001
+ false,
10002
+ undefined,
10003
+ undefined,
10004
+ undefined,
10005
+ undefined,
10006
+ DEVICE_URL.REMOTE_A
10007
+ );
9454
10008
 
9455
10009
  payloadTestHelper([data1, data2, data3]);
9456
10010
  });
9457
10011
 
9458
10012
  it('Scenario #3: remote person A shares desktop and then you share desktop using web client', () => {
9459
- const data1 = generateData(blankPayload, true, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A);
9460
- const data2 = generateData(data1.payload, true, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
9461
- const data3 = generateData(data2.payload, false, true, USER_IDS.ME, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.LOCAL_WEB);
10013
+ const data1 = generateData(
10014
+ blankPayload,
10015
+ true,
10016
+ true,
10017
+ USER_IDS.REMOTE_A,
10018
+ undefined,
10019
+ false,
10020
+ undefined,
10021
+ undefined,
10022
+ undefined,
10023
+ undefined,
10024
+ DEVICE_URL.REMOTE_A
10025
+ );
10026
+ const data2 = generateData(
10027
+ data1.payload,
10028
+ true,
10029
+ true,
10030
+ USER_IDS.ME,
10031
+ undefined,
10032
+ false,
10033
+ undefined,
10034
+ undefined,
10035
+ undefined,
10036
+ undefined,
10037
+ DEVICE_URL.LOCAL_WEB
10038
+ );
10039
+ const data3 = generateData(
10040
+ data2.payload,
10041
+ false,
10042
+ true,
10043
+ USER_IDS.ME,
10044
+ undefined,
10045
+ false,
10046
+ undefined,
10047
+ undefined,
10048
+ undefined,
10049
+ undefined,
10050
+ DEVICE_URL.LOCAL_WEB
10051
+ );
9462
10052
 
9463
10053
  payloadTestHelper([data1, data2, data3]);
9464
10054
  });
@@ -9472,8 +10062,32 @@ describe('plugin-meetings', () => {
9472
10062
  });
9473
10063
 
9474
10064
  it('Scenario #5: remote person A shares desktop A and remote person B shares desktop B', () => {
9475
- const data1 = generateData(blankPayload, true, true, USER_IDS.REMOTE_A, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_A);
9476
- const data2 = generateData(data1.payload, true, true, USER_IDS.REMOTE_B, undefined, false, undefined, undefined, undefined, undefined, DEVICE_URL.REMOTE_B);
10065
+ const data1 = generateData(
10066
+ blankPayload,
10067
+ true,
10068
+ true,
10069
+ USER_IDS.REMOTE_A,
10070
+ undefined,
10071
+ false,
10072
+ undefined,
10073
+ undefined,
10074
+ undefined,
10075
+ undefined,
10076
+ DEVICE_URL.REMOTE_A
10077
+ );
10078
+ const data2 = generateData(
10079
+ data1.payload,
10080
+ true,
10081
+ true,
10082
+ USER_IDS.REMOTE_B,
10083
+ undefined,
10084
+ false,
10085
+ undefined,
10086
+ undefined,
10087
+ undefined,
10088
+ undefined,
10089
+ DEVICE_URL.REMOTE_B
10090
+ );
9477
10091
  const data3 = generateData(data2.payload, false, true, USER_IDS.REMOTE_B);
9478
10092
 
9479
10093
  payloadTestHelper([data1, data2, data3]);
@@ -9892,26 +10506,34 @@ describe('plugin-meetings', () => {
9892
10506
 
9893
10507
  afterEach(() => {
9894
10508
  clock.restore();
9895
- })
10509
+ });
9896
10510
 
9897
10511
  it('should return undefined if exp is undefined', () => {
9898
- assert.equal(meeting.getPermissionTokenExpiryInfo(), undefined)
10512
+ assert.equal(meeting.getPermissionTokenExpiryInfo(), undefined);
9899
10513
  });
9900
10514
 
9901
10515
  it('should return the expected positive exp', () => {
9902
10516
  // set permission token as now + 1 sec
9903
10517
  const expiryTime = now + 1000;
9904
- meeting.permissionTokenPayload = {exp: (expiryTime).toString(), iat: now};
10518
+ meeting.permissionTokenPayload = {exp: expiryTime.toString(), iat: now};
9905
10519
  meeting.permissionTokenReceivedLocalTime = now;
9906
- assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: 1, expiryTime: Number(expiryTime), currentTime: now});
10520
+ assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {
10521
+ timeLeft: 1,
10522
+ expiryTime: Number(expiryTime),
10523
+ currentTime: now,
10524
+ });
9907
10525
  });
9908
10526
 
9909
10527
  it('should return the expected negative exp', () => {
9910
10528
  // set permission token as now - 1 sec
9911
10529
  const expiryTime = now - 1000;
9912
- meeting.permissionTokenPayload = {exp: (expiryTime).toString(), iat: now};
10530
+ meeting.permissionTokenPayload = {exp: expiryTime.toString(), iat: now};
9913
10531
  meeting.permissionTokenReceivedLocalTime = now;
9914
- assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: -1, expiryTime: Number(expiryTime), currentTime: now});
10532
+ assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {
10533
+ timeLeft: -1,
10534
+ expiryTime: Number(expiryTime),
10535
+ currentTime: now,
10536
+ });
9915
10537
  });
9916
10538
 
9917
10539
  describe('#getPermissionTokenExpiryInfo with wrong current time which is in future', () => {
@@ -9920,34 +10542,41 @@ describe('plugin-meetings', () => {
9920
10542
  beforeEach(() => {
9921
10543
  // current time is 3 hours off
9922
10544
  now = Date.now() + 10800000;
9923
-
10545
+
9924
10546
  // mock `new Date()` with constant `now`
9925
10547
  clock = sinon.useFakeTimers(now);
9926
10548
  });
9927
-
10549
+
9928
10550
  afterEach(() => {
9929
10551
  clock.restore();
9930
- })
9931
-
10552
+ });
10553
+
9932
10554
  it('should return the expected positive exp when client time is wrong', () => {
9933
10555
  const serverTime = Date.now();
9934
-
9935
- // set permission token as now + 1 sec
10556
+
10557
+ // set permission token as now + 1 sec
9936
10558
  const expiryTime = serverTime + 1000;
9937
- meeting.permissionTokenPayload = {exp: (expiryTime).toString(), iat: serverTime};
10559
+ meeting.permissionTokenPayload = {exp: expiryTime.toString(), iat: serverTime};
9938
10560
  meeting.permissionTokenReceivedLocalTime = now;
9939
- assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: 1, expiryTime: Number(expiryTime), currentTime: now});
10561
+ assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {
10562
+ timeLeft: 1,
10563
+ expiryTime: Number(expiryTime),
10564
+ currentTime: now,
10565
+ });
9940
10566
  });
9941
-
10567
+
9942
10568
  it('should return the expected negative exp when client time is wrong', () => {
9943
10569
  const serverTime = Date.now();
9944
10570
  // set permission token as now - 1 sec
9945
10571
  const expiryTime = serverTime - 1000;
9946
- meeting.permissionTokenPayload = {exp: (expiryTime).toString(), iat: serverTime};
10572
+ meeting.permissionTokenPayload = {exp: expiryTime.toString(), iat: serverTime};
9947
10573
  meeting.permissionTokenReceivedLocalTime = now;
9948
- assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: -1, expiryTime: Number(expiryTime), currentTime: now});
10574
+ assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {
10575
+ timeLeft: -1,
10576
+ expiryTime: Number(expiryTime),
10577
+ currentTime: now,
10578
+ });
9949
10579
  });
9950
-
9951
10580
  });
9952
10581
 
9953
10582
  describe('#getPermissionTokenExpiryInfo with wrong current Time which is in the past', () => {
@@ -9956,42 +10585,47 @@ describe('plugin-meetings', () => {
9956
10585
  beforeEach(() => {
9957
10586
  // current time is 3 hours off
9958
10587
  now = Date.now() - 10800000;
9959
-
10588
+
9960
10589
  // mock `new Date()` with constant `now`
9961
10590
  clock = sinon.useFakeTimers(now);
9962
10591
  });
9963
-
10592
+
9964
10593
  afterEach(() => {
9965
10594
  clock.restore();
9966
- })
9967
-
10595
+ });
10596
+
9968
10597
  it('should return the expected positive exp when client time is wrong', () => {
9969
10598
  const serverTime = Date.now();
9970
-
9971
- // set permission token as now + 1 sec
10599
+
10600
+ // set permission token as now + 1 sec
9972
10601
  const expiryTime = serverTime + 1000;
9973
- meeting.permissionTokenPayload = {exp: (expiryTime).toString(), iat: serverTime};
10602
+ meeting.permissionTokenPayload = {exp: expiryTime.toString(), iat: serverTime};
9974
10603
  meeting.permissionTokenReceivedLocalTime = now;
9975
- assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: 1, expiryTime: Number(expiryTime), currentTime: now});
10604
+ assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {
10605
+ timeLeft: 1,
10606
+ expiryTime: Number(expiryTime),
10607
+ currentTime: now,
10608
+ });
9976
10609
  });
9977
-
10610
+
9978
10611
  it('should return the expected negative exp when client time is wrong', () => {
9979
10612
  const serverTime = Date.now();
9980
10613
  // set permission token as now - 1 sec
9981
10614
  const expiryTime = serverTime - 1000;
9982
- meeting.permissionTokenPayload = {exp: (expiryTime).toString(), iat: serverTime};
10615
+ meeting.permissionTokenPayload = {exp: expiryTime.toString(), iat: serverTime};
9983
10616
  meeting.permissionTokenReceivedLocalTime = now;
9984
- assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: -1, expiryTime: Number(expiryTime), currentTime: now});
10617
+ assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {
10618
+ timeLeft: -1,
10619
+ expiryTime: Number(expiryTime),
10620
+ currentTime: now,
10621
+ });
9985
10622
  });
9986
-
9987
10623
  });
9988
10624
  });
9989
10625
 
9990
-
9991
-
9992
10626
  describe('#checkAndRefreshPermissionToken', () => {
9993
- it('should not fire refreshPermissionToken if permissionToken is not defined', async() => {
9994
- meeting.getPermissionTokenExpiryInfo = sinon.stub().returns(undefined)
10627
+ it('should not fire refreshPermissionToken if permissionToken is not defined', async () => {
10628
+ meeting.getPermissionTokenExpiryInfo = sinon.stub().returns(undefined);
9995
10629
  meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
9996
10630
 
9997
10631
  const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
@@ -10001,8 +10635,10 @@ describe('plugin-meetings', () => {
10001
10635
  assert.equal(returnValue, undefined);
10002
10636
  });
10003
10637
 
10004
- it('should fire refreshPermissionToken if time left is below 10sec', async() => {
10005
- meeting.getPermissionTokenExpiryInfo = sinon.stub().returns({timeLeft: 9, expiryTime: 122132, currentTime: Date.now()})
10638
+ it('should fire refreshPermissionToken if time left is below 10sec', async () => {
10639
+ meeting.getPermissionTokenExpiryInfo = sinon
10640
+ .stub()
10641
+ .returns({timeLeft: 9, expiryTime: 122132, currentTime: Date.now()});
10006
10642
  meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
10007
10643
 
10008
10644
  const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
@@ -10013,7 +10649,9 @@ describe('plugin-meetings', () => {
10013
10649
  });
10014
10650
 
10015
10651
  it('should fire refreshPermissionToken if time left is equal 10sec', async () => {
10016
- meeting.getPermissionTokenExpiryInfo = sinon.stub().returns({timeLeft: 10, expiryTime: 122132, currentTime: Date.now()})
10652
+ meeting.getPermissionTokenExpiryInfo = sinon
10653
+ .stub()
10654
+ .returns({timeLeft: 10, expiryTime: 122132, currentTime: Date.now()});
10017
10655
  meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
10018
10656
 
10019
10657
  const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
@@ -10024,7 +10662,9 @@ describe('plugin-meetings', () => {
10024
10662
  });
10025
10663
 
10026
10664
  it('should not fire refreshPermissionToken if time left is higher than 10sec', async () => {
10027
- meeting.getPermissionTokenExpiryInfo = sinon.stub().returns({timeLeft: 11, expiryTime: 122132, currentTime: Date.now()})
10665
+ meeting.getPermissionTokenExpiryInfo = sinon
10666
+ .stub()
10667
+ .returns({timeLeft: 11, expiryTime: 122132, currentTime: Date.now()});
10028
10668
  meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
10029
10669
 
10030
10670
  const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
@@ -10037,19 +10677,22 @@ describe('plugin-meetings', () => {
10037
10677
 
10038
10678
  describe('#roapMessageReceived', () => {
10039
10679
  it('calls roapMessageReceived on the webrtc media connection', () => {
10040
- const fakeMessage = { messageType: 'fake', sdp: 'fake sdp'};
10680
+ const fakeMessage = {messageType: 'fake', sdp: 'fake sdp'};
10041
10681
 
10042
10682
  const getMediaServer = sinon.stub(MeetingsUtil, 'getMediaServer').returns('homer');
10043
10683
 
10044
10684
  meeting.mediaProperties.webrtcMediaConnection = {
10045
- roapMessageReceived: sinon.stub()
10685
+ roapMessageReceived: sinon.stub(),
10046
10686
  };
10047
10687
 
10048
10688
  meeting.roapMessageReceived(fakeMessage);
10049
10689
 
10050
- assert.calledOnceWithExactly(meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived, fakeMessage);
10690
+ assert.calledOnceWithExactly(
10691
+ meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived,
10692
+ fakeMessage
10693
+ );
10051
10694
  assert.calledOnceWithExactly(getMediaServer, 'fake sdp');
10052
10695
  assert.equal(meeting.mediaProperties.webrtcMediaConnection.mediaServer, 'homer');
10053
- })
10054
- })
10696
+ });
10697
+ });
10055
10698
  });