test_response.js (10025B)
1 function testDefaultCtor() { 2 var res = new Response(); 3 is(res.type, "default", "Default Response type is default"); 4 ok( 5 res.headers instanceof Headers, 6 "Response should have non-null Headers object" 7 ); 8 is(res.url, "", "URL should be empty string"); 9 is(res.status, 200, "Default status is 200"); 10 is(res.statusText, "", "Default statusText is an empty string"); 11 } 12 13 function testClone() { 14 var orig = new Response("This is a body", { 15 status: 404, 16 statusText: "Not Found", 17 headers: { "Content-Length": 5 }, 18 }); 19 var clone = orig.clone(); 20 is(clone.status, 404, "Response status is 404"); 21 is(clone.statusText, "Not Found", "Response statusText is POST"); 22 ok( 23 clone.headers instanceof Headers, 24 "Response should have non-null Headers object" 25 ); 26 27 is( 28 clone.headers.get("content-length"), 29 "5", 30 "Response content-length should be 5." 31 ); 32 orig.headers.set("content-length", 6); 33 is( 34 clone.headers.get("content-length"), 35 "5", 36 "Response content-length should be 5." 37 ); 38 39 ok(!orig.bodyUsed, "Original body is not consumed."); 40 ok(!clone.bodyUsed, "Clone body is not consumed."); 41 42 var origBody = null; 43 var clone2 = null; 44 return orig 45 .text() 46 .then(function (body) { 47 origBody = body; 48 is(origBody, "This is a body", "Original body string matches"); 49 ok(orig.bodyUsed, "Original body is consumed."); 50 ok(!clone.bodyUsed, "Clone body is not consumed."); 51 52 try { 53 orig.clone(); 54 ok(false, "Cannot clone Response whose body is already consumed"); 55 } catch (e) { 56 is( 57 e.name, 58 "TypeError", 59 "clone() of consumed body should throw TypeError" 60 ); 61 } 62 63 clone2 = clone.clone(); 64 return clone.text(); 65 }) 66 .then(function (body) { 67 is(body, origBody, "Clone body matches original body."); 68 ok(clone.bodyUsed, "Clone body is consumed."); 69 70 try { 71 clone.clone(); 72 ok(false, "Cannot clone Response whose body is already consumed"); 73 } catch (e) { 74 is( 75 e.name, 76 "TypeError", 77 "clone() of consumed body should throw TypeError" 78 ); 79 } 80 81 return clone2.text(); 82 }) 83 .then(function (body) { 84 is(body, origBody, "Clone body matches original body."); 85 ok(clone2.bodyUsed, "Clone body is consumed."); 86 87 try { 88 clone2.clone(); 89 ok(false, "Cannot clone Response whose body is already consumed"); 90 } catch (e) { 91 is( 92 e.name, 93 "TypeError", 94 "clone() of consumed body should throw TypeError" 95 ); 96 } 97 }); 98 } 99 100 function testCloneUnfiltered() { 101 var url = 102 "http://example.com/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?status=200"; 103 return fetch(url, { mode: "no-cors" }).then(function (response) { 104 // By default the chrome-only function should not be available. 105 is(response.type, "opaque", "response should be opaque"); 106 is( 107 response.cloneUnfiltered, 108 undefined, 109 "response.cloneUnfiltered should be undefined" 110 ); 111 112 // When the test is run in a worker context we can't actually try to use 113 // the chrome-only function. SpecialPowers is not defined. 114 if (typeof SpecialPowers !== "object") { 115 return; 116 } 117 118 // With a chrome code, however, should be able to get an unfiltered response. 119 var chromeResponse = SpecialPowers.wrap(response); 120 is( 121 typeof chromeResponse.cloneUnfiltered, 122 "function", 123 "chromeResponse.cloneFiltered should be a function" 124 ); 125 var unfiltered = chromeResponse.cloneUnfiltered(); 126 is(unfiltered.type, "default", "unfiltered response should be default"); 127 is(unfiltered.status, 200, "unfiltered response should have 200 status"); 128 }); 129 } 130 131 function testError() { 132 var res = Response.error(); 133 is(res.status, 0, "Error response status should be 0"); 134 try { 135 res.headers.set("someheader", "not allowed"); 136 ok(false, "Error response should have immutable headers"); 137 } catch (e) { 138 ok(true, "Error response should have immutable headers"); 139 } 140 } 141 142 function testRedirect() { 143 var res = Response.redirect("./redirect.response"); 144 is(res.status, 302, "Default redirect has status code 302"); 145 is(res.statusText, "", "Default redirect has status text empty"); 146 var h = res.headers.get("location"); 147 ok( 148 h === new URL("./redirect.response", self.location.href).href, 149 "Location header should be correct absolute URL" 150 ); 151 try { 152 res.headers.set("someheader", "not allowed"); 153 ok(false, "Redirects should have immutable headers"); 154 } catch (e) { 155 ok(true, "Redirects should have immutable headers"); 156 } 157 158 var successStatus = [301, 302, 303, 307, 308]; 159 for (var i = 0; i < successStatus.length; ++i) { 160 var res = Response.redirect("./redirect.response", successStatus[i]); 161 is(res.status, successStatus[i], "Status code should match"); 162 } 163 164 var failStatus = [300, 0, 304, 305, 306, 309, 500]; 165 for (var i = 0; i < failStatus.length; ++i) { 166 try { 167 var res = Response.redirect(".", failStatus[i]); 168 ok(false, "Invalid status code should fail " + failStatus[i]); 169 } catch (e) { 170 is( 171 e.name, 172 "RangeError", 173 "Invalid status code should fail " + failStatus[i] 174 ); 175 } 176 } 177 } 178 179 function testOk() { 180 var r1 = new Response("", { status: 200 }); 181 ok(r1.ok, "Response with status 200 should have ok true"); 182 183 var r2 = new Response(undefined, { status: 204 }); 184 ok(r2.ok, "Response with status 204 should have ok true"); 185 186 var r3 = new Response("", { status: 299 }); 187 ok(r3.ok, "Response with status 299 should have ok true"); 188 189 var r4 = new Response("", { status: 302 }); 190 ok(!r4.ok, "Response with status 302 should have ok false"); 191 } 192 193 function testBodyUsed() { 194 var res = new Response("Sample body"); 195 ok(!res.bodyUsed, "bodyUsed is initially false."); 196 return res 197 .text() 198 .then(v => { 199 is(v, "Sample body", "Body should match"); 200 ok(res.bodyUsed, "After reading body, bodyUsed should be true."); 201 }) 202 .then(() => { 203 return res.blob().then( 204 v => { 205 ok(false, "Attempting to read body again should fail."); 206 }, 207 e => { 208 ok(true, "Attempting to read body again should fail."); 209 } 210 ); 211 }); 212 } 213 214 function testBodyCreation() { 215 var text = "κόσμε"; 216 var res1 = new Response(text); 217 var p1 = res1.text().then(function (v) { 218 ok(typeof v === "string", "Should resolve to string"); 219 is(text, v, "Extracted string should match"); 220 }); 221 222 var res2 = new Response(new Uint8Array([72, 101, 108, 108, 111])); 223 var p2 = res2.text().then(function (v) { 224 is("Hello", v, "Extracted string should match"); 225 }); 226 227 var res2b = new Response(new Uint8Array([72, 101, 108, 108, 111]).buffer); 228 var p2b = res2b.text().then(function (v) { 229 is("Hello", v, "Extracted string should match"); 230 }); 231 232 var resblob = new Response(new Blob([text])); 233 var pblob = resblob.text().then(function (v) { 234 is(v, text, "Extracted string should match"); 235 }); 236 237 var params = new URLSearchParams(); 238 params.append("item", "Geckos"); 239 params.append("feature", "stickyfeet"); 240 params.append("quantity", "700"); 241 var res3 = new Response(params); 242 var p3 = res3.text().then(function (v) { 243 var extracted = new URLSearchParams(v); 244 is(extracted.get("item"), "Geckos", "Param should match"); 245 is(extracted.get("feature"), "stickyfeet", "Param should match"); 246 is(extracted.get("quantity"), "700", "Param should match"); 247 }); 248 249 return Promise.all([p1, p2, p2b, pblob, p3]); 250 } 251 252 function testBodyExtraction() { 253 var text = "κόσμε"; 254 var newRes = function () { 255 return new Response(text); 256 }; 257 return newRes() 258 .text() 259 .then(function (v) { 260 ok(typeof v === "string", "Should resolve to string"); 261 is(text, v, "Extracted string should match"); 262 }) 263 .then(function () { 264 return newRes() 265 .blob() 266 .then(function (v) { 267 ok(v instanceof Blob, "Should resolve to Blob"); 268 return readAsText(v).then(function (result) { 269 is(result, text, "Decoded Blob should match original"); 270 }); 271 }); 272 }) 273 .then(function () { 274 return newRes() 275 .json() 276 .then( 277 function (v) { 278 ok(false, "Invalid json should reject"); 279 }, 280 function (e) { 281 ok(true, "Invalid json should reject"); 282 } 283 ); 284 }) 285 .then(function () { 286 return newRes() 287 .arrayBuffer() 288 .then(function (v) { 289 ok(v instanceof ArrayBuffer, "Should resolve to ArrayBuffer"); 290 var dec = new TextDecoder(); 291 is( 292 dec.decode(new Uint8Array(v)), 293 text, 294 "UTF-8 decoded ArrayBuffer should match original" 295 ); 296 }); 297 }); 298 } 299 300 function testNullBodyStatus() { 301 [204, 205, 304].forEach(function (status) { 302 try { 303 var res = new Response(new Blob(), { status }); 304 ok( 305 false, 306 "Response body provided but status code does not permit a body" 307 ); 308 } catch (e) { 309 ok(true, "Response body provided but status code does not permit a body"); 310 } 311 }); 312 313 [204, 205, 304].forEach(function (status) { 314 try { 315 var res = new Response(undefined, { status }); 316 ok(true, "Response body provided but status code does not permit a body"); 317 } catch (e) { 318 ok( 319 false, 320 "Response body provided but status code does not permit a body" 321 ); 322 } 323 }); 324 } 325 326 function runTest() { 327 testDefaultCtor(); 328 testError(); 329 testRedirect(); 330 testOk(); 331 testNullBodyStatus(); 332 333 return ( 334 Promise.resolve() 335 .then(testBodyCreation) 336 .then(testBodyUsed) 337 .then(testBodyExtraction) 338 .then(testClone) 339 .then(testCloneUnfiltered) 340 // Put more promise based tests here. 341 .catch(function (e) { 342 dump("### ### " + e + "\n"); 343 ok(false, "got unexpected error!"); 344 }) 345 ); 346 }