@webex/plugin-meetings 3.0.0-beta.294 → 3.0.0-beta.296
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +151 -127
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/util.js +1 -5
- package/dist/meetings/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/roap/index.js +37 -2
- package/dist/roap/index.js.map +1 -1
- package/dist/types/meeting/index.d.ts +6 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +20 -20
- package/src/meeting/index.ts +84 -42
- package/src/meetings/util.ts +1 -7
- package/src/metrics/constants.ts +1 -0
- package/src/roap/index.ts +38 -1
- package/test/unit/spec/meeting/index.js +115 -46
- package/test/unit/spec/meetings/utils.js +1 -5
- package/test/unit/spec/roap/index.ts +153 -13
|
@@ -58,6 +58,7 @@ import * as MeetingRequestImport from '@webex/plugin-meetings/src/meeting/reques
|
|
|
58
58
|
import LocusInfo from '@webex/plugin-meetings/src/locus-info';
|
|
59
59
|
import MediaProperties from '@webex/plugin-meetings/src/media/properties';
|
|
60
60
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
61
|
+
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
61
62
|
import Media from '@webex/plugin-meetings/src/media/index';
|
|
62
63
|
import ReconnectionManager from '@webex/plugin-meetings/src/reconnection-manager';
|
|
63
64
|
import MediaUtil from '@webex/plugin-meetings/src/media/util';
|
|
@@ -1193,7 +1194,7 @@ describe('plugin-meetings', () => {
|
|
|
1193
1194
|
|
|
1194
1195
|
it('should send metrics and reset the statsAnalyzer to null if addMedia throws an error without a turn server retry', async () => {
|
|
1195
1196
|
meeting.meetingState = 'ACTIVE';
|
|
1196
|
-
|
|
1197
|
+
|
|
1197
1198
|
meeting.webex.meetings.reachability = {
|
|
1198
1199
|
getReachabilityMetrics: sinon.stub().resolves({
|
|
1199
1200
|
someReachabilityMetric1: 'some value1',
|
|
@@ -2361,7 +2362,7 @@ describe('plugin-meetings', () => {
|
|
|
2361
2362
|
let clock;
|
|
2362
2363
|
|
|
2363
2364
|
beforeEach(() => {
|
|
2364
|
-
clock = sinon.useFakeTimers();
|
|
2365
|
+
clock = sinon.useFakeTimers();
|
|
2365
2366
|
|
|
2366
2367
|
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
2367
2368
|
|
|
@@ -2501,7 +2502,7 @@ describe('plugin-meetings', () => {
|
|
|
2501
2502
|
|
|
2502
2503
|
// simulates a Roap OK being sent
|
|
2503
2504
|
const simulateRoapOk = async () => {
|
|
2504
|
-
const roapListener = getRoapListener();
|
|
2505
|
+
const roapListener = getRoapListener();
|
|
2505
2506
|
|
|
2506
2507
|
await roapListener({roapMessage: roapOKMessage});
|
|
2507
2508
|
await stableState();
|
|
@@ -2523,7 +2524,7 @@ describe('plugin-meetings', () => {
|
|
|
2523
2524
|
correlationId: meeting.correlationId,
|
|
2524
2525
|
localMedias: [
|
|
2525
2526
|
{
|
|
2526
|
-
localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OFFER","sdps":["${sdp}"],"version":"2","seq":"${seq}","tieBreaker":"${tieBreaker}"}}`,
|
|
2527
|
+
localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OFFER","sdps":["${sdp}"],"version":"2","seq":"${seq}","tieBreaker":"${tieBreaker}","headers":["includeAnswerInHttpResponse","noOkInTransaction"]}}`,
|
|
2527
2528
|
mediaId: 'fake media id',
|
|
2528
2529
|
},
|
|
2529
2530
|
],
|
|
@@ -5746,34 +5747,20 @@ describe('plugin-meetings', () => {
|
|
|
5746
5747
|
});
|
|
5747
5748
|
});
|
|
5748
5749
|
|
|
5749
|
-
describe('handles
|
|
5750
|
-
let sendRoapOKStub;
|
|
5751
|
-
let sendRoapMediaRequestStub;
|
|
5752
|
-
let sendRoapAnswerStub;
|
|
5753
|
-
let sendRoapErrorStub;
|
|
5754
|
-
|
|
5750
|
+
describe('handles SDP events correctly', () => {
|
|
5755
5751
|
beforeEach(() => {
|
|
5756
|
-
sendRoapOKStub = sinon.stub(meeting.roap, 'sendRoapOK').resolves({});
|
|
5757
|
-
sendRoapMediaRequestStub = sinon
|
|
5758
|
-
.stub(meeting.roap, 'sendRoapMediaRequest')
|
|
5759
|
-
.resolves({});
|
|
5760
|
-
sendRoapAnswerStub = sinon.stub(meeting.roap, 'sendRoapAnswer').resolves({});
|
|
5761
|
-
sendRoapErrorStub = sinon.stub(meeting.roap, 'sendRoapError').resolves({});
|
|
5762
|
-
|
|
5763
5752
|
meeting.setupMediaConnectionListeners();
|
|
5764
5753
|
});
|
|
5765
5754
|
|
|
5766
|
-
it('handles
|
|
5755
|
+
it('handles REMOTE_SDP_ANSWER_PROCESSED correctly', () => {
|
|
5767
5756
|
const clock = sinon.useFakeTimers();
|
|
5768
|
-
sinon.spy(clock,
|
|
5757
|
+
sinon.spy(clock, 'clearTimeout');
|
|
5769
5758
|
meeting.deferSDPAnswer = {
|
|
5770
5759
|
resolve: sinon.stub(),
|
|
5771
5760
|
};
|
|
5772
5761
|
meeting.sdpResponseTimer = '1234';
|
|
5773
5762
|
|
|
5774
|
-
eventListeners[Event.
|
|
5775
|
-
roapMessage: {messageType: 'OK', seq: 1},
|
|
5776
|
-
});
|
|
5763
|
+
eventListeners[Event.REMOTE_SDP_ANSWER_PROCESSED]();
|
|
5777
5764
|
|
|
5778
5765
|
assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
|
|
5779
5766
|
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
@@ -5781,13 +5768,6 @@ describe('plugin-meetings', () => {
|
|
|
5781
5768
|
options: {meetingId: meeting.id},
|
|
5782
5769
|
});
|
|
5783
5770
|
|
|
5784
|
-
assert.calledOnce(sendRoapOKStub);
|
|
5785
|
-
assert.calledWith(sendRoapOKStub, {
|
|
5786
|
-
seq: 1,
|
|
5787
|
-
mediaId: meeting.mediaId,
|
|
5788
|
-
correlationId: meeting.correlationId,
|
|
5789
|
-
});
|
|
5790
|
-
|
|
5791
5771
|
assert.calledOnce(Metrics.sendBehavioralMetric);
|
|
5792
5772
|
assert.calledWith(
|
|
5793
5773
|
Metrics.sendBehavioralMetric,
|
|
@@ -5799,15 +5779,70 @@ describe('plugin-meetings', () => {
|
|
|
5799
5779
|
}
|
|
5800
5780
|
);
|
|
5801
5781
|
|
|
5802
|
-
assert.calledOnce(meeting.deferSDPAnswer.resolve)
|
|
5803
|
-
assert.calledOnce(clock.clearTimeout)
|
|
5804
|
-
assert.calledWith(clock.clearTimeout, '1234')
|
|
5805
|
-
assert.equal(meeting.sdpResponseTimer, undefined)
|
|
5782
|
+
assert.calledOnce(meeting.deferSDPAnswer.resolve);
|
|
5783
|
+
assert.calledOnce(clock.clearTimeout);
|
|
5784
|
+
assert.calledWith(clock.clearTimeout, '1234');
|
|
5785
|
+
assert.equal(meeting.sdpResponseTimer, undefined);
|
|
5806
5786
|
});
|
|
5807
5787
|
|
|
5808
|
-
it('handles
|
|
5788
|
+
it('handles LOCAL_SDP_OFFER_GENERATED correctly', () => {
|
|
5809
5789
|
assert.equal(meeting.deferSDPAnswer, undefined);
|
|
5810
5790
|
|
|
5791
|
+
eventListeners[Event.LOCAL_SDP_OFFER_GENERATED]();
|
|
5792
|
+
|
|
5793
|
+
assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
|
|
5794
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
5795
|
+
name: 'client.media-engine.local-sdp-generated',
|
|
5796
|
+
options: {meetingId: meeting.id},
|
|
5797
|
+
});
|
|
5798
|
+
|
|
5799
|
+
assert.notEqual(meeting.deferSDPAnswer, undefined);
|
|
5800
|
+
});
|
|
5801
|
+
|
|
5802
|
+
it('handles LOCAL_SDP_ANSWER_GENERATED correctly', () => {
|
|
5803
|
+
eventListeners[Event.LOCAL_SDP_ANSWER_GENERATED]();
|
|
5804
|
+
|
|
5805
|
+
assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
|
|
5806
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
5807
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
5808
|
+
options: {meetingId: meeting.id},
|
|
5809
|
+
});
|
|
5810
|
+
});
|
|
5811
|
+
});
|
|
5812
|
+
|
|
5813
|
+
describe('handles Event.ROAP_MESSAGE_TO_SEND correctly', () => {
|
|
5814
|
+
let sendRoapOKStub;
|
|
5815
|
+
let sendRoapMediaRequestStub;
|
|
5816
|
+
let sendRoapAnswerStub;
|
|
5817
|
+
let sendRoapErrorStub;
|
|
5818
|
+
|
|
5819
|
+
beforeEach(() => {
|
|
5820
|
+
sendRoapOKStub = sinon.stub(meeting.roap, 'sendRoapOK').resolves({});
|
|
5821
|
+
sendRoapMediaRequestStub = sinon
|
|
5822
|
+
.stub(meeting.roap, 'sendRoapMediaRequest')
|
|
5823
|
+
.resolves({});
|
|
5824
|
+
sendRoapAnswerStub = sinon.stub(meeting.roap, 'sendRoapAnswer').resolves({});
|
|
5825
|
+
sendRoapErrorStub = sinon.stub(meeting.roap, 'sendRoapError').resolves({});
|
|
5826
|
+
|
|
5827
|
+
meeting.setupMediaConnectionListeners();
|
|
5828
|
+
});
|
|
5829
|
+
|
|
5830
|
+
it('handles OK message correctly', () => {
|
|
5831
|
+
eventListeners[Event.ROAP_MESSAGE_TO_SEND]({
|
|
5832
|
+
roapMessage: {messageType: 'OK', seq: 1},
|
|
5833
|
+
});
|
|
5834
|
+
|
|
5835
|
+
assert.calledOnce(sendRoapOKStub);
|
|
5836
|
+
assert.calledWith(sendRoapOKStub, {
|
|
5837
|
+
seq: 1,
|
|
5838
|
+
mediaId: meeting.mediaId,
|
|
5839
|
+
correlationId: meeting.correlationId,
|
|
5840
|
+
});
|
|
5841
|
+
});
|
|
5842
|
+
|
|
5843
|
+
it('handles OFFER message correctly (no answer in the http response)', async () => {
|
|
5844
|
+
sinon.stub(meeting, 'roapMessageReceived');
|
|
5845
|
+
|
|
5811
5846
|
eventListeners[Event.ROAP_MESSAGE_TO_SEND]({
|
|
5812
5847
|
roapMessage: {
|
|
5813
5848
|
messageType: 'OFFER',
|
|
@@ -5817,11 +5852,7 @@ describe('plugin-meetings', () => {
|
|
|
5817
5852
|
},
|
|
5818
5853
|
});
|
|
5819
5854
|
|
|
5820
|
-
|
|
5821
|
-
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
5822
|
-
name: 'client.media-engine.local-sdp-generated',
|
|
5823
|
-
options: {meetingId: meeting.id},
|
|
5824
|
-
});
|
|
5855
|
+
await testUtils.flushPromises();
|
|
5825
5856
|
|
|
5826
5857
|
assert.calledOnce(sendRoapMediaRequestStub);
|
|
5827
5858
|
assert.calledWith(sendRoapMediaRequestStub, {
|
|
@@ -5831,8 +5862,34 @@ describe('plugin-meetings', () => {
|
|
|
5831
5862
|
meeting,
|
|
5832
5863
|
reconnect: false,
|
|
5833
5864
|
});
|
|
5865
|
+
assert.notCalled(meeting.roapMessageReceived);
|
|
5866
|
+
});
|
|
5834
5867
|
|
|
5835
|
-
|
|
5868
|
+
it('handles OFFER message correctly (with an answer in the http response)', async () => {
|
|
5869
|
+
const fakeAnswer = {messageType: 'answer', sdp: 'sdp'};
|
|
5870
|
+
sendRoapMediaRequestStub.resolves({roapAnswer: fakeAnswer});
|
|
5871
|
+
sinon.stub(meeting, 'roapMessageReceived');
|
|
5872
|
+
|
|
5873
|
+
eventListeners[Event.ROAP_MESSAGE_TO_SEND]({
|
|
5874
|
+
roapMessage: {
|
|
5875
|
+
messageType: 'OFFER',
|
|
5876
|
+
seq: 1,
|
|
5877
|
+
sdp: 'fake sdp',
|
|
5878
|
+
tieBreaker: 12345,
|
|
5879
|
+
},
|
|
5880
|
+
});
|
|
5881
|
+
|
|
5882
|
+
await testUtils.flushPromises();
|
|
5883
|
+
|
|
5884
|
+
assert.calledOnce(sendRoapMediaRequestStub);
|
|
5885
|
+
assert.calledWith(sendRoapMediaRequestStub, {
|
|
5886
|
+
seq: 1,
|
|
5887
|
+
sdp: 'fake sdp',
|
|
5888
|
+
tieBreaker: 12345,
|
|
5889
|
+
meeting,
|
|
5890
|
+
reconnect: false,
|
|
5891
|
+
});
|
|
5892
|
+
assert.calledWith(meeting.roapMessageReceived, fakeAnswer);
|
|
5836
5893
|
});
|
|
5837
5894
|
|
|
5838
5895
|
it('handles ANSWER message correctly', () => {
|
|
@@ -5845,12 +5902,6 @@ describe('plugin-meetings', () => {
|
|
|
5845
5902
|
},
|
|
5846
5903
|
});
|
|
5847
5904
|
|
|
5848
|
-
assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
|
|
5849
|
-
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
5850
|
-
name: 'client.media-engine.remote-sdp-received',
|
|
5851
|
-
options: {meetingId: meeting.id},
|
|
5852
|
-
});
|
|
5853
|
-
|
|
5854
5905
|
assert.calledOnce(sendRoapAnswerStub);
|
|
5855
5906
|
assert.calledWith(sendRoapAnswerStub, {
|
|
5856
5907
|
seq: 10,
|
|
@@ -9300,4 +9351,22 @@ describe('plugin-meetings', () => {
|
|
|
9300
9351
|
assert.equal(returnValue, undefined);
|
|
9301
9352
|
});
|
|
9302
9353
|
});
|
|
9354
|
+
|
|
9355
|
+
describe('#roapMessageReceived', () => {
|
|
9356
|
+
it('calls roapMessageReceived on the webrtc media connection', () => {
|
|
9357
|
+
const fakeMessage = { messageType: 'fake', sdp: 'fake sdp'};
|
|
9358
|
+
|
|
9359
|
+
const getMediaServer = sinon.stub(MeetingsUtil, 'getMediaServer').returns('homer');
|
|
9360
|
+
|
|
9361
|
+
meeting.mediaProperties.webrtcMediaConnection = {
|
|
9362
|
+
roapMessageReceived: sinon.stub()
|
|
9363
|
+
};
|
|
9364
|
+
|
|
9365
|
+
meeting.roapMessageReceived(fakeMessage);
|
|
9366
|
+
|
|
9367
|
+
assert.calledOnceWithExactly(meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived, fakeMessage);
|
|
9368
|
+
assert.calledOnceWithExactly(getMediaServer, 'fake sdp');
|
|
9369
|
+
assert.equal(meeting.mediaProperties.webrtcMediaConnection.mediaServer, 'homer');
|
|
9370
|
+
})
|
|
9371
|
+
})
|
|
9303
9372
|
});
|
|
@@ -7,6 +7,8 @@ import RoapRequest from '@webex/plugin-meetings/src/roap/request';
|
|
|
7
7
|
import Roap from '@webex/plugin-meetings/src/roap/';
|
|
8
8
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
9
9
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
10
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
11
|
+
import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
|
|
10
12
|
|
|
11
13
|
import { IP_VERSION } from '../../../../src/constants';
|
|
12
14
|
|
|
@@ -42,6 +44,9 @@ describe('Roap', () => {
|
|
|
42
44
|
let meeting;
|
|
43
45
|
|
|
44
46
|
let webex;
|
|
47
|
+
let roap;
|
|
48
|
+
|
|
49
|
+
const fakeLocus = {id: 'fake locus'};
|
|
45
50
|
|
|
46
51
|
beforeEach(() => {
|
|
47
52
|
webex = new MockWebex({});
|
|
@@ -50,21 +55,27 @@ describe('Roap', () => {
|
|
|
50
55
|
correlationId: 'correlation id',
|
|
51
56
|
selfUrl: 'self url',
|
|
52
57
|
mediaId: 'media id',
|
|
53
|
-
audio:{
|
|
58
|
+
audio: {
|
|
54
59
|
isLocallyMuted: () => true,
|
|
55
60
|
},
|
|
56
|
-
video:{
|
|
61
|
+
video: {
|
|
57
62
|
isLocallyMuted: () => false,
|
|
58
63
|
},
|
|
64
|
+
isMultistream: true,
|
|
59
65
|
setRoapSeq: sinon.stub(),
|
|
60
66
|
locusMediaRequest: {fake: true},
|
|
61
|
-
webex: {
|
|
67
|
+
webex: {meetings: {reachability: {isAnyPublicClusterReachable: () => true}}},
|
|
68
|
+
updateMediaConnections: sinon.stub(),
|
|
62
69
|
};
|
|
63
70
|
|
|
64
71
|
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
72
|
+
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
65
73
|
|
|
66
74
|
sendRoapStub = sinon.stub(RoapRequest.prototype, 'sendRoap').resolves({});
|
|
67
75
|
meeting.setRoapSeq.resetHistory();
|
|
76
|
+
|
|
77
|
+
roap = new Roap({}, {parent: webex});
|
|
78
|
+
sinon.stub(roap.turnDiscovery, 'isSkipped').resolves(false);
|
|
68
79
|
});
|
|
69
80
|
|
|
70
81
|
afterEach(() => {
|
|
@@ -82,9 +93,7 @@ describe('Roap', () => {
|
|
|
82
93
|
}reconnecting and TURN discovery is ${
|
|
83
94
|
turnDiscoverySkipped ? 'skipped' : 'not skipped'
|
|
84
95
|
}`, async () => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
sinon.stub(roap.turnDiscovery, 'isSkipped').resolves(turnDiscoverySkipped);
|
|
96
|
+
roap.turnDiscovery.isSkipped.resolves(turnDiscoverySkipped);
|
|
88
97
|
|
|
89
98
|
await roap.sendRoapMediaRequest({
|
|
90
99
|
meeting,
|
|
@@ -100,17 +109,148 @@ describe('Roap', () => {
|
|
|
100
109
|
version: '2',
|
|
101
110
|
seq: 2,
|
|
102
111
|
tieBreaker: 4294967294,
|
|
112
|
+
headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
|
|
103
113
|
};
|
|
104
114
|
|
|
105
115
|
assert.calledOnce(sendRoapStub);
|
|
106
|
-
assert.calledWith(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
assert.calledWith(
|
|
117
|
+
sendRoapStub,
|
|
118
|
+
sinon.match({
|
|
119
|
+
roapMessage: expectedRoapMessage,
|
|
120
|
+
locusSelfUrl: meeting.selfUrl,
|
|
121
|
+
mediaId: expectEmptyMediaId ? '' : meeting.mediaId,
|
|
122
|
+
meetingId: meeting.id,
|
|
123
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
124
|
+
})
|
|
125
|
+
);
|
|
113
126
|
})
|
|
114
127
|
);
|
|
128
|
+
|
|
129
|
+
it('reads SDP answer from the http response', async () => {
|
|
130
|
+
const roapAnswer = {
|
|
131
|
+
seq: 5,
|
|
132
|
+
messageType: 'ANSWER',
|
|
133
|
+
sdps: ['sdp answer'],
|
|
134
|
+
errorType: 'error type', // normally ANSWER would not have errorType or errorCause (only error messages have these)
|
|
135
|
+
errorCause: 'error cause', // but we're just testing here that all the fields are forwarded to the caller of sendRoapMediaRequest()
|
|
136
|
+
headers: ['header1', 'header2'],
|
|
137
|
+
};
|
|
138
|
+
const fakeMediaConnections = [
|
|
139
|
+
{
|
|
140
|
+
remoteSdp: JSON.stringify({
|
|
141
|
+
roapMessage: roapAnswer,
|
|
142
|
+
}),
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
sendRoapStub.resolves({
|
|
147
|
+
mediaConnections: fakeMediaConnections,
|
|
148
|
+
locus: fakeLocus,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const result = await roap.sendRoapMediaRequest({
|
|
152
|
+
meeting,
|
|
153
|
+
sdp: 'sdp',
|
|
154
|
+
reconnect: false,
|
|
155
|
+
seq: 1,
|
|
156
|
+
tieBreaker: 4294967294,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
assert.calledOnce(sendRoapStub);
|
|
160
|
+
assert.calledOnceWithExactly(meeting.updateMediaConnections, fakeMediaConnections);
|
|
161
|
+
assert.deepEqual(result, {
|
|
162
|
+
locus: fakeLocus,
|
|
163
|
+
roapAnswer: {
|
|
164
|
+
seq: 5,
|
|
165
|
+
messageType: 'ANSWER',
|
|
166
|
+
sdp: 'sdp answer',
|
|
167
|
+
errorType: 'error type',
|
|
168
|
+
errorCause: 'error cause',
|
|
169
|
+
headers: ['header1', 'header2'],
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('handles the case when there is no answer in the http response', async () => {
|
|
175
|
+
const fakeMediaConnections = [
|
|
176
|
+
{
|
|
177
|
+
// this is the actual value Locus returns to us when they don't send Roap ANSWER in the http response
|
|
178
|
+
remoteSdp:
|
|
179
|
+
'{"audioMuted":false,"videoMuted":false,"csis":[],"dtmfReceiveSupported":true,"type":"SDP"}',
|
|
180
|
+
},
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
sendRoapStub.resolves({
|
|
184
|
+
mediaConnections: fakeMediaConnections,
|
|
185
|
+
locus: fakeLocus,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const result = await roap.sendRoapMediaRequest({
|
|
189
|
+
meeting,
|
|
190
|
+
sdp: 'sdp',
|
|
191
|
+
reconnect: false,
|
|
192
|
+
seq: 1,
|
|
193
|
+
tieBreaker: 4294967294,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
assert.calledOnce(sendRoapStub);
|
|
197
|
+
assert.calledOnceWithExactly(meeting.updateMediaConnections, fakeMediaConnections);
|
|
198
|
+
assert.deepEqual(result, {
|
|
199
|
+
locus: fakeLocus,
|
|
200
|
+
roapAnswer: undefined,
|
|
201
|
+
});
|
|
202
|
+
assert.calledOnceWithExactly(
|
|
203
|
+
Metrics.sendBehavioralMetric,
|
|
204
|
+
BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING,
|
|
205
|
+
{
|
|
206
|
+
correlationId: meeting.correlationId,
|
|
207
|
+
messageType: 'ANSWER',
|
|
208
|
+
isMultistream: meeting.isMultistream,
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe('does not crash when http response is missing things', () => {
|
|
214
|
+
[
|
|
215
|
+
{mediaConnections: undefined, title: 'mediaConnections are undefined'},
|
|
216
|
+
{mediaConnections: [], title: 'mediaConnections are empty array'},
|
|
217
|
+
{mediaConnections: [{}], title: 'mediaConnections[0] has no remoteSdp'},
|
|
218
|
+
{
|
|
219
|
+
mediaConnections: [{remoteSdp: '{}'}],
|
|
220
|
+
title: 'mediaConnections[0].remoteSdp is an empty json',
|
|
221
|
+
},
|
|
222
|
+
].forEach(({mediaConnections, title}) =>
|
|
223
|
+
it(title, async () => {
|
|
224
|
+
sendRoapStub.resolves({
|
|
225
|
+
mediaConnections,
|
|
226
|
+
locus: fakeLocus,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const result = await roap.sendRoapMediaRequest({
|
|
230
|
+
meeting,
|
|
231
|
+
sdp: 'sdp',
|
|
232
|
+
reconnect: false,
|
|
233
|
+
seq: 1,
|
|
234
|
+
tieBreaker: 4294967294,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
assert.calledOnce(sendRoapStub);
|
|
238
|
+
assert.deepEqual(result, {
|
|
239
|
+
locus: fakeLocus,
|
|
240
|
+
roapAnswer: undefined,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
assert.calledOnceWithExactly(
|
|
244
|
+
Metrics.sendBehavioralMetric,
|
|
245
|
+
BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING,
|
|
246
|
+
{
|
|
247
|
+
correlationId: meeting.correlationId,
|
|
248
|
+
messageType: 'ANSWER',
|
|
249
|
+
isMultistream: meeting.isMultistream,
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
})
|
|
253
|
+
);
|
|
254
|
+
});
|
|
115
255
|
});
|
|
116
256
|
});
|