blob: b216e95004d3adb6fefab4482ef87dfc9350adc6 [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:
14 // generateOffer
15 // generateAnswer
Soares Chen363f1252017-07-10 09:22:1516 // assert_session_desc_equals
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.1.6. Set the RTCSessionSessionDescription
Soares Chen25d8bf32017-07-20 03:08:4148 2.2.2. If description is set as a local description, then run one of the following
49 steps:
Soares Chen363f1252017-07-10 09:22:1550
51 - If description is of type "answer", then this completes an offer answer
52 negotiation.
53
54 Set connection's currentLocalDescription to description and
55 currentRemoteDescription to the value of pendingRemoteDescription.
56
57 Set both pendingRemoteDescription and pendingLocalDescription to null.
58
59 Finally set connection's signaling state to stable.
60 */
61 promise_test(t => {
62 const pc = new RTCPeerConnection();
Philipp Hanckeeb37a992018-05-30 15:55:0263
64 const states = [];
65 pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
Soares Chen363f1252017-07-10 09:22:1566
Rick Waldron5445fa32017-08-30 21:53:5967 return pc.createOffer({ offerToReceiveVideo: true })
Soares Chen363f1252017-07-10 09:22:1568 .then(offer =>
69 pc.setRemoteDescription(offer)
70 .then(() => pc.createAnswer())
71 .then(answer =>
72 pc.setLocalDescription(answer)
73 .then(() => {
74 assert_equals(pc.signalingState, 'stable');
75 assert_session_desc_equals(pc.localDescription, answer);
76 assert_session_desc_equals(pc.remoteDescription, offer);
77
78 assert_session_desc_equals(pc.currentLocalDescription, answer);
79 assert_session_desc_equals(pc.currentRemoteDescription, offer);
80
81 assert_equals(pc.pendingLocalDescription, null);
82 assert_equals(pc.pendingRemoteDescription, null);
Philipp Hanckeeb37a992018-05-30 15:55:0283
84 assert_array_equals(states, ['have-remote-offer', 'stable']);
Soares Chen363f1252017-07-10 09:22:1585 })));
86 }, 'setLocalDescription() with valid answer should succeed');
87
88 /*
89 4.3.2. setLocalDescription
90 3. Let lastAnswer be the result returned by the last call to createAnswer.
91 4. If description.sdp is null and description.type is answer, set description.sdp
92 to lastAnswer.
93 */
94 promise_test(t => {
95 const pc = new RTCPeerConnection();
96
Rick Waldron5445fa32017-08-30 21:53:5997 return pc.createOffer({ offerToReceiveVideo: true })
Soares Chen363f1252017-07-10 09:22:1598 .then(offer =>
99 pc.setRemoteDescription(offer)
100 .then(() => pc.createAnswer())
101 .then(answer =>
102 pc.setLocalDescription({ type: 'answer' })
103 .then(() => {
104 assert_equals(pc.signalingState, 'stable');
105 assert_session_desc_equals(pc.localDescription, answer);
106 assert_session_desc_equals(pc.remoteDescription, offer);
107
108 assert_session_desc_equals(pc.currentLocalDescription, answer);
109 assert_session_desc_equals(pc.currentRemoteDescription, offer);
110
111 assert_equals(pc.pendingLocalDescription, null);
112 assert_equals(pc.pendingRemoteDescription, null);
113 })));
114 }, 'setLocalDescription() with type answer and null sdp should use lastAnswer generated from createAnswer');
115
116 /*
117 4.3.2. setLocalDescription
118 3. Let lastAnswer be the result returned by the last call to createAnswer.
119 7. If description.type is answer and description.sdp does not match lastAnswer,
120 reject the promise with a newly created InvalidModificationError and abort these
121 steps.
122 */
123 promise_test(t => {
124 const pc = new RTCPeerConnection();
125
Rick Waldron5445fa32017-08-30 21:53:59126 return pc.createOffer({ offerToReceiveVideo: true })
Soares Chen363f1252017-07-10 09:22:15127 .then(offer =>
128 pc.setRemoteDescription(offer)
129 .then(() => generateAnswer(offer))
130 .then(answer =>
131 promise_rejects(t, 'InvalidModificationError',
132 pc.setLocalDescription(answer))));
133 }, 'setLocalDescription() with answer not created by own createAnswer() should reject with InvalidModificationError');
134
135 /*
136 4.3.1.6. Set the RTCSessionSessionDescription
137 2.3. If the description's type is invalid for the current signaling state of
138 connection, then reject p with a newly created InvalidStateError and abort
139 these steps.
140
141 [jsep]
142 5.5. If the type is "pranswer" or "answer", the PeerConnection
143 state MUST be either "have-remote-offer" or "have-local-pranswer".
144 */
145 promise_test(t => {
146 const pc = new RTCPeerConnection();
147
Rick Waldron5445fa32017-08-30 21:53:59148 return pc.createOffer()
Soares Chen363f1252017-07-10 09:22:15149 .then(offer =>
150 promise_rejects(t, 'InvalidStateError',
151 pc.setLocalDescription({ type: 'answer', sdp: offer.sdp })));
152
153 }, 'Calling setLocalDescription(answer) from stable state should reject with InvalidStateError');
154
155 promise_test(t => {
156 const pc = new RTCPeerConnection();
157
158 return pc.createOffer()
159 .then(offer =>
160 pc.setLocalDescription(offer)
161 .then(() => generateAnswer(offer)))
162 .then(answer =>
163 promise_rejects(t, 'InvalidStateError',
164 pc.setLocalDescription(answer)));
165 }, 'Calling setLocalDescription(answer) from have-local-offer state should reject with InvalidStateError');
166
167</script>