RTCIceCandidate-constructor.html (10840B)
1 <!doctype html> 2 <title>RTCIceCandidate constructor</title> 3 <script src=/resources/testharness.js></script> 4 <script src=/resources/testharnessreport.js></script> 5 <script> 6 'use strict'; 7 8 const candidateString = 'candidate:1905690388 1 udp 2113937151 192.168.0.1 58041 typ host generation 0 ufrag thC8 network-cost 50'; 9 const candidateString2 = 'candidate:435653019 2 tcp 1845501695 192.168.0.196 4444 typ srflx raddr www.example.com rport 22222 tcptype active'; 10 const arbitraryString = '<arbitrary string[0] content>;'; 11 12 test(t => { 13 // The argument for RTCIceCandidateInit is optional (w3c/webrtc-pc #1153 #1166), 14 // but the constructor throws because both sdpMid and sdpMLineIndex are null by default. 15 // Note that current browsers pass this test but may throw TypeError for 16 // different reason, i.e. they don't accept empty argument. 17 // Further tests below are used to differentiate the errors. 18 assert_throws_js(TypeError, () => new RTCIceCandidate()); 19 }, 'new RTCIceCandidate()'); 20 21 test(t => { 22 // All fields in RTCIceCandidateInit are optional, 23 // but the constructor throws because both sdpMid and sdpMLineIndex are null by default. 24 // Note that current browsers pass this test but may throw TypeError for 25 // different reason, i.e. they don't allow undefined candidate string. 26 // Further tests below are used to differentiate the errors. 27 assert_throws_js(TypeError, () => new RTCIceCandidate({})); 28 }, 'new RTCIceCandidate({})'); 29 30 test(t => { 31 // Checks that manually filling the default values for RTCIceCandidateInit 32 // still throws because both sdpMid and sdpMLineIndex are null 33 assert_throws_js(TypeError, 34 () => new RTCIceCandidate({ 35 candidate: '', 36 sdpMid: null, 37 sdpMLineIndex: null, 38 usernameFragment: undefined 39 })); 40 }, 'new RTCIceCandidate({ ... }) with manually filled default values'); 41 42 test(t => { 43 // Checks that explicitly setting both sdpMid and sdpMLineIndex null should throw 44 assert_throws_js(TypeError, 45 () => new RTCIceCandidate({ 46 sdpMid: null, 47 sdpMLineIndex: null 48 })); 49 }, 'new RTCIceCandidate({ sdpMid: null, sdpMLineIndex: null })'); 50 51 test(t => { 52 // Throws because both sdpMid and sdpMLineIndex are null by default 53 assert_throws_js(TypeError, 54 () => new RTCIceCandidate({ 55 candidate: '' 56 })); 57 }, `new RTCIceCandidate({ candidate: '' })`); 58 59 test(t => { 60 // Throws because both sdpMid and sdpMLineIndex are null by default 61 assert_throws_js(TypeError, 62 () => new RTCIceCandidate({ 63 candidate: null 64 })); 65 }, `new RTCIceCandidate({ candidate: null })`); 66 67 test(t => { 68 // Throws because both sdpMid and sdpMLineIndex are null by default 69 assert_throws_js(TypeError, 70 () => new RTCIceCandidate({ 71 candidate: candidateString 72 })); 73 }, 'new RTCIceCandidate({ ... }) with valid candidate string only'); 74 75 test(t => { 76 const candidate = new RTCIceCandidate({ sdpMid: 'audio' }); 77 78 assert_equals(candidate.candidate, '', 'candidate'); 79 assert_equals(candidate.sdpMid, 'audio', 'sdpMid'); 80 assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex'); 81 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 82 }, `new RTCIceCandidate({ sdpMid: 'audio' })`); 83 84 test(t => { 85 const candidate = new RTCIceCandidate({ sdpMLineIndex: 0 }); 86 87 assert_equals(candidate.candidate, '', 'candidate'); 88 assert_equals(candidate.sdpMid, null, 'sdpMid'); 89 assert_equals(candidate.sdpMLineIndex, 0, 'sdpMLineIndex'); 90 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 91 }, 'new RTCIceCandidate({ sdpMLineIndex: 0 })'); 92 93 test(t => { 94 const candidate = new RTCIceCandidate({ 95 sdpMid: 'audio', 96 sdpMLineIndex: 0 97 }); 98 99 assert_equals(candidate.candidate, '', 'candidate'); 100 assert_equals(candidate.sdpMid, 'audio', 'sdpMid'); 101 assert_equals(candidate.sdpMLineIndex, 0, 'sdpMLineIndex'); 102 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 103 }, `new RTCIceCandidate({ sdpMid: 'audio', sdpMLineIndex: 0 })`); 104 105 test(t => { 106 const candidate = new RTCIceCandidate({ 107 candidate: '', 108 sdpMid: 'audio' 109 }); 110 111 assert_equals(candidate.candidate, '', 'candidate'); 112 assert_equals(candidate.sdpMid, 'audio', 'sdpMid'); 113 assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex'); 114 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 115 }, `new RTCIceCandidate({ candidate: '', sdpMid: 'audio' }`); 116 117 test(t => { 118 const candidate = new RTCIceCandidate({ 119 candidate: null, 120 sdpMLineIndex: 0 121 }); 122 123 assert_equals(candidate.candidate, 'null', 'candidate'); 124 assert_equals(candidate.sdpMid, null, 'sdpMid', 'sdpMid'); 125 assert_equals(candidate.sdpMLineIndex, 0, 'sdpMLineIndex'); 126 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 127 }, `new RTCIceCandidate({ candidate: null, sdpMLineIndex: 0 }`); 128 129 test(t => { 130 const candidate = new RTCIceCandidate({ 131 candidate: candidateString, 132 sdpMid: 'audio' 133 }); 134 135 assert_equals(candidate.candidate, candidateString, 'candidate'); 136 assert_equals(candidate.sdpMid, 'audio', 'sdpMid'); 137 assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex'); 138 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 139 }, 'new RTCIceCandidate({ ... }) with valid candidate string and sdpMid'); 140 141 test(t => { 142 // candidate string is not validated in RTCIceCandidate 143 const candidate = new RTCIceCandidate({ 144 candidate: arbitraryString, 145 sdpMid: 'audio' 146 }); 147 148 assert_equals(candidate.candidate, arbitraryString, 'candidate'); 149 assert_equals(candidate.sdpMid, 'audio', 'sdpMid'); 150 assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex'); 151 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 152 }, 'new RTCIceCandidate({ ... }) with invalid candidate string and sdpMid'); 153 154 ["most", "all"].forEach(howMany => { 155 test(t => { 156 const candidate = new RTCIceCandidate({ 157 candidate: candidateString, 158 sdpMid: 'video', 159 sdpMLineIndex: 1, 160 usernameFragment: 'test', 161 relayProtocol: 'udp', 162 url: 'stun:stun.example.org' 163 }); 164 165 assert_equals(candidate.candidate, candidateString, 'candidate'); 166 assert_equals(candidate.sdpMid, 'video', 'sdpMid'); 167 assert_equals(candidate.sdpMLineIndex, 1, 'sdpMLineIndex'); 168 assert_equals(candidate.usernameFragment, 'test', 'usernameFragment'); 169 170 // The following fields should match those in the candidate field 171 assert_equals(candidate.foundation, '1905690388', 'foundation'); 172 assert_equals(candidate.component, 'rtp', 'component'); 173 assert_equals(candidate.priority, 2113937151, 'priority'); 174 assert_equals(candidate.address, '192.168.0.1', 'address'); 175 assert_equals(candidate.protocol, 'udp', 'protocol'); 176 assert_equals(candidate.port, 58041, 'port'); 177 assert_equals(candidate.type, 'host', 'type'); 178 assert_equals(candidate.tcpType, null, 'tcpType'); 179 assert_equals(candidate.relatedAddress, null, 'relatedAddress'); 180 assert_equals(candidate.relatedPort, null, 'relatedPort'); 181 // The remaining fields are newer, so test them seperately 182 if (howMany != "most") { 183 assert_equals(candidate.relayProtocol, 'udp', 'relayProtocol'); 184 assert_equals(candidate.url, 'stun:stun.example.org', 'url'); 185 } 186 }, `new RTCIceCandidate({ ... }) with nondefault values for ${howMany} fields`); 187 188 test(t => { 189 const candidate = new RTCIceCandidate({ 190 candidate: candidateString2, 191 sdpMid: 'video', 192 sdpMLineIndex: 1, 193 usernameFragment: 'user1', 194 relayProtocol: 'tcp', 195 url: 'turn:turn.example.net' 196 }); 197 198 assert_equals(candidate.candidate, candidateString2, 'candidate'); 199 assert_equals(candidate.sdpMid, 'video', 'sdpMid'); 200 assert_equals(candidate.sdpMLineIndex, 1, 'sdpMLineIndex'); 201 assert_equals(candidate.usernameFragment, 'user1', 'usernameFragment'); 202 203 // The following fields should match those in the candidate field 204 assert_equals(candidate.foundation, '435653019', 'foundation'); 205 assert_equals(candidate.component, 'rtcp', 'component'); 206 assert_equals(candidate.priority, 1845501695, 'priority'); 207 assert_equals(candidate.address, '192.168.0.196', 'address'); 208 assert_equals(candidate.protocol, 'tcp', 'protocol'); 209 assert_equals(candidate.port, 4444, 'port'); 210 assert_equals(candidate.type, 'srflx', 'type'); 211 assert_equals(candidate.tcpType, 'active', 'tcpType'); 212 assert_equals(candidate.relatedAddress, 'www.example.com', 'relatedAddress'); 213 assert_equals(candidate.relatedPort, 22222, 'relatedPort'); 214 // The remaining fields are newer, so test them seperately 215 if (howMany != "most") { 216 assert_equals(candidate.url, 'turn:turn.example.net', 'url'); 217 assert_equals(candidate.relayProtocol, 'tcp', 'relayProtocol'); 218 } 219 }, `new RTCIceCandidate({ ... }) with nondefault values for ${howMany} fields, tcp candidate`); 220 }); 221 222 test(t => { 223 let candidate = new RTCIceCandidate(new RTCIceCandidate({ 224 sdpMid: 'video', 225 relayProtocol: 'tls', 226 url: 'turn:turn.example.net' 227 })); 228 229 assert_equals(candidate.relayProtocol, 'tls', 'relayProtocol cloned'); 230 assert_equals(candidate.url, 'turn:turn.example.net', 'url cloned'); 231 232 candidate = new RTCIceCandidate(JSON.parse(JSON.stringify(candidate))); 233 assert_equals(candidate.relayProtocol, null, 'relayProtocol not signaled'); 234 assert_equals(candidate.url, null, 'url not signaled'); 235 }, `new RTCIceCandidate({ relayProtocol, url }) cloned vs signaled`); 236 237 test(t => { 238 // sdpMid is not validated in RTCIceCandidate 239 const candidate = new RTCIceCandidate({ 240 sdpMid: arbitraryString 241 }); 242 243 assert_equals(candidate.candidate, '', 'candidate'); 244 assert_equals(candidate.sdpMid, arbitraryString, 'sdpMid'); 245 assert_equals(candidate.sdpMLineIndex, null, 'sdpMLineIndex'); 246 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 247 }, 'new RTCIceCandidate({ ... }) with invalid sdpMid'); 248 249 250 test(t => { 251 // Some arbitrary large out of bound line index that practically 252 // do not reference any m= line in SDP. 253 // However sdpMLineIndex is not validated in RTCIceCandidate 254 // and it has no knowledge of the SDP it is associated with. 255 const candidate = new RTCIceCandidate({ 256 sdpMLineIndex: 65535 257 }); 258 259 assert_equals(candidate.candidate, '', 'candidate'); 260 assert_equals(candidate.sdpMid, null, 'sdpMid'); 261 assert_equals(candidate.sdpMLineIndex, 65535, 'sdpMLineIndex'); 262 assert_equals(candidate.usernameFragment, null, 'usernameFragment'); 263 }, 'new RTCIceCandidate({ ... }) with invalid sdpMLineIndex'); 264 265 </script>