blob: 31c85227a857fb445e22c583611dcf2da9f128cc [file] [log] [blame]
Soares Chen363f1252017-07-10 09:22:151<!doctype html>
2<meta charset=utf-8>
3<title>RTCPeerConnection.prototype.setLocalDescription</title>
4<script src="/resources/testharness.js"></script>
5<script src="/resources/testharnessreport.js"></script>
6<script src="RTCPeerConnection-helper.js"></script>
7<script>
8 'use strict';
9
10 // Test is based on the following editor draft:
11 // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
12
13 // The following helper functions are called from RTCPeerConnection-helper.js:
youennfcd17e3b2018-11-04 08:03:5914 // generateDataChannelOffer
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:0915 // assert_session_desc_not_similar
16 // assert_session_desc_similar
Soares Chen363f1252017-07-10 09:22:1517
18 /*
19 4.3.2. Interface Definition
20 [Constructor(optional RTCConfiguration configuration)]
21 interface RTCPeerConnection : EventTarget {
22 Promise<void> setRemoteDescription(
23 RTCSessionDescriptionInit description);
24
25 readonly attribute RTCSessionDescription? remoteDescription;
26 readonly attribute RTCSessionDescription? currentRemoteDescription;
27 readonly attribute RTCSessionDescription? pendingRemoteDescription;
28 ...
29 };
30
31 4.6.2. RTCSessionDescription Class
32 dictionary RTCSessionDescriptionInit {
33 required RTCSdpType type;
34 DOMString sdp = "";
35 };
36
37 4.6.1. RTCSdpType
38 enum RTCSdpType {
39 "offer",
40 "pranswer",
41 "answer",
42 "rollback"
43 };
44 */
45
46 /*
47 4.3.2. setLocalDescription
48 2. Let lastOffer be the result returned by the last call to createOffer.
49 5. If description.sdp is null and description.type is offer, set description.sdp
50 to lastOffer.
51
52 4.3.1.6. Set the RTCSessionSessionDescription
Soares Chen25d8bf32017-07-20 03:08:4153 2.2.2. If description is set as a local description, then run one of the following
54 steps:
55 - If description is of type "offer", set connection.pendingLocalDescription
56 to description and signaling state to have-local-offer.
Soares Chen363f1252017-07-10 09:22:1557 */
58 promise_test(t => {
59 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:5360 t.add_cleanup(() => pc.close());
Philipp Hanckeeb37a992018-05-30 15:55:0261
62 const states = [];
63 pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
Soares Chen363f1252017-07-10 09:22:1564
Youenn Fablet7b163582018-11-04 07:30:5965 return generateAudioReceiveOnlyOffer(pc)
Soares Chen363f1252017-07-10 09:22:1566 .then(offer =>
67 pc.setLocalDescription(offer)
68 .then(() => {
69 assert_equals(pc.signalingState, 'have-local-offer');
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:0970 assert_session_desc_similar(pc.localDescription, offer);
71 assert_session_desc_similar(pc.pendingLocalDescription, offer);
Soares Chen363f1252017-07-10 09:22:1572 assert_equals(pc.currentLocalDescription, null);
Philipp Hanckeeb37a992018-05-30 15:55:0273
74 assert_array_equals(states, ['have-local-offer']);
Soares Chen363f1252017-07-10 09:22:1575 }));
76 }, 'setLocalDescription with valid offer should succeed');
77
78 /*
79 4.3.2. setLocalDescription
80 2. Let lastOffer be the result returned by the last call to createOffer.
81 5. If description.sdp is null and description.type is offer, set description.sdp
82 to lastOffer.
83 */
84 promise_test(t => {
85 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:5386 t.add_cleanup(() => pc.close());
Youenn Fablet7b163582018-11-04 07:30:5987 return generateAudioReceiveOnlyOffer(pc)
Soares Chen363f1252017-07-10 09:22:1588 .then(offer =>
89 pc.setLocalDescription({ type: 'offer' })
90 .then(() => {
91 assert_equals(pc.signalingState, 'have-local-offer');
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:0992 assert_session_desc_similar(pc.localDescription, offer);
93 assert_session_desc_similar(pc.pendingLocalDescription, offer);
Soares Chen363f1252017-07-10 09:22:1594 assert_equals(pc.currentLocalDescription, null);
95 }));
96 }, 'setLocalDescription with type offer and null sdp should use lastOffer generated from createOffer');
97
98 /*
99 4.3.2. setLocalDescription
100 2. Let lastOffer be the result returned by the last call to createOffer.
101 6. If description.type is offer and description.sdp does not match lastOffer,
102 reject the promise with a newly created InvalidModificationError and abort
103 these steps.
104 */
105 promise_test(t => {
106 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53107 t.add_cleanup(() => pc.close());
Harald Alvestrande48a42f2018-03-22 18:59:43108 const pc2 = new RTCPeerConnection();
Soares Chen363f1252017-07-10 09:22:15109
Philipp Hancke1622a022018-06-11 10:00:53110 t.add_cleanup(() => pc2.close());
111
youennfcd17e3b2018-11-04 08:03:59112 return generateDataChannelOffer(pc)
Soares Chen363f1252017-07-10 09:22:15113 .then(offer =>
114 promise_rejects(t, 'InvalidModificationError',
Harald Alvestrande48a42f2018-03-22 18:59:43115 pc2.setLocalDescription(offer)));
Soares Chen363f1252017-07-10 09:22:15116 }, 'setLocalDescription() with offer not created by own createOffer() should reject with InvalidModificationError');
117
118 promise_test(t => {
119 // Create first offer with audio line, then second offer with
120 // both audio and video line. Since the second offer is the
121 // last offer, setLocalDescription would reject when setting
122 // with the first offer
123 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53124 t.add_cleanup(() => pc.close());
Youenn Fablet7b163582018-11-04 07:30:59125 return generateAudioReceiveOnlyOffer(pc)
Soares Chen363f1252017-07-10 09:22:15126 .then(offer1 =>
Youenn Fablet7b163582018-11-04 07:30:59127 generateVideoReceiveOnlyOffer(pc)
Soares Chen363f1252017-07-10 09:22:15128 .then(offer2 => {
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:09129 assert_session_desc_not_similar(offer1, offer2);
Soares Chen363f1252017-07-10 09:22:15130 return promise_rejects(t, 'InvalidModificationError',
131 pc.setLocalDescription(offer1));
132 }));
133 }, 'Set created offer other than last offer should reject with InvalidModificationError');
134
135 promise_test(t => {
136 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53137 t.add_cleanup(() => pc.close());
Soares Chen363f1252017-07-10 09:22:15138
Philipp Hanckeeb37a992018-05-30 15:55:02139 const states = [];
140 pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
Soares Chen363f1252017-07-10 09:22:15141
Youenn Fablet7b163582018-11-04 07:30:59142 return generateAudioReceiveOnlyOffer(pc)
Soares Chen363f1252017-07-10 09:22:15143 .then(offer1 =>
144 pc.setLocalDescription(offer1)
145 .then(() =>
Youenn Fablet7b163582018-11-04 07:30:59146 generateVideoReceiveOnlyOffer(pc)
Soares Chen363f1252017-07-10 09:22:15147 .then(offer2 =>
148 pc.setLocalDescription(offer2)
Mark Robertsbfa6d942018-11-08 05:55:00149 .then(() => {
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:09150 assert_session_desc_not_similar(offer1, offer2);
Soares Chen363f1252017-07-10 09:22:15151 assert_equals(pc.signalingState, 'have-local-offer');
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:09152 assert_session_desc_similar(pc.localDescription, offer2);
153 assert_session_desc_similar(pc.pendingLocalDescription, offer2);
Soares Chen363f1252017-07-10 09:22:15154 assert_equals(pc.currentLocalDescription, null);
Philipp Hanckeeb37a992018-05-30 15:55:02155
156 assert_array_equals(states, ['have-local-offer']);
Soares Chen363f1252017-07-10 09:22:15157 }))));
158 }, 'Creating and setting offer multiple times should succeed');
159
Byron Campen [:bwc]65f12c62019-03-23 17:05:00160 promise_test(async t => {
161 const pc1 = new RTCPeerConnection();
162 t.add_cleanup(() => pc1.close());
163 const pc2 = new RTCPeerConnection();
164 t.add_cleanup(() => pc2.close());
165
166 const offer = await pc1.createOffer({offerToReceiveAudio: true}); // [[LastOffer]] set
167 const offer2 = await pc2.createOffer({offerToReceiveVideo: true});
168 await pc1.setRemoteDescription(offer2);
169 await pc1.createAnswer(); // [[LastAnswer]] set
170 await pc1.setRemoteDescription({type: "rollback"});
171 await pc1.setLocalDescription(offer);
172 }, "Setting previously generated offer after a call to createAnswer should work");
173
Soares Chen363f1252017-07-10 09:22:15174</script>