1<!doctype html> 2<!-- 3@license 4Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 5This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 6The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 7The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 8Code distributed by Google as part of the polymer project is also 9subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 10--> 11<html> 12<head> 13 <title>iron-request</title> 14 15 <script src="../../webcomponentsjs/webcomponents-lite.js"></script> 16 <script src="../../web-component-tester/browser.js"></script> 17 18 <link rel="import" href="../../polymer/polymer.html"> 19 <link rel="import" href="../../promise-polyfill/promise-polyfill.html"> 20 <link rel="import" href="../iron-request.html"> 21</head> 22<body> 23 <test-fixture id="TrivialRequest"> 24 <template> 25 <iron-request></iron-request> 26 </template> 27 </test-fixture> 28 <script> 29 suite('<iron-request>', function() { 30 var jsonResponseHeaders; 31 var successfulRequestOptions; 32 var request; 33 var server; 34 35 setup(function() { 36 jsonResponseHeaders = { 37 'Content-Type': 'application/json' 38 }; 39 server = sinon.fakeServer.create(); 40 server.respondWith('GET', '/responds_to_get_with_json', [ 41 200, 42 jsonResponseHeaders, 43 '{"success":true}' 44 ]); 45 46 server.respondWith('GET', '/responds_to_get_with_prefixed_json', [ 47 200, 48 jsonResponseHeaders, 49 '])}while(1);</x>{"success":true}' 50 ]); 51 52 server.respondWith('GET', '/responds_to_get_with_500', [ 53 500, 54 {}, 55 '' 56 ]); 57 58 server.respondWith('GET', '/responds_to_get_with_100', [ 59 100, 60 {}, 61 '' 62 ]); 63 64 server.respondWith('GET', '/responds_to_get_with_0', [ 65 0, 66 jsonResponseHeaders, 67 '{"success":true}' 68 ]); 69 70 71 request = fixture('TrivialRequest'); 72 successfulRequestOptions = { 73 url: '/responds_to_get_with_json' 74 }; 75 76 synchronousSuccessfulRequestOptions = { 77 url: '/responds_to_get_with_json', 78 async: false, 79 timeout: 100 80 }; 81 82 asynchronousSuccessfulRequestOptions = { 83 url: '/responds_to_get_with_json', 84 async: true, 85 timeout: 100 86 }; 87 }); 88 89 teardown(function() { 90 server.restore(); 91 }); 92 93 suite('basic usage', function() { 94 test('creates network requests, requiring only `url`', function() { 95 request.send(successfulRequestOptions); 96 97 server.respond(); 98 99 expect(request.response).to.be.ok; 100 }); 101 102 test('timeout not set if synchronous', function() { 103 request.send(synchronousSuccessfulRequestOptions); 104 105 expect(request.xhr.async).to.be.eql(false); 106 expect(request.xhr.timeout).to.be.eql(undefined); 107 }); 108 109 test('timeout set if asynchronous', function() { 110 request.send(asynchronousSuccessfulRequestOptions); 111 112 expect(request.xhr.async).to.be.eql(true); 113 expect(request.xhr.timeout).to.be.eql(100); 114 }); 115 116 test('sets async to true by default', function() { 117 request.send(successfulRequestOptions); 118 expect(request.xhr.async).to.be.eql(true); 119 }); 120 121 test('can be aborted', function() { 122 request.send(successfulRequestOptions); 123 124 request.abort(); 125 126 server.respond(); 127 128 return request.completes.then(function() { 129 throw new Error('Request did not abort appropriately!'); 130 }).catch(function(e) { 131 expect(request.response).to.not.be.ok; 132 }); 133 }); 134 135 test('can be aborted with request element', function() { 136 var options = { 137 url: successfulRequestOptions.url, 138 rejectWithRequest: true 139 }; 140 request.send(options); 141 142 request.abort(); 143 144 server.respond(); 145 146 return request.completes.then(function() { 147 throw new Error('Request did not abort appropriately!'); 148 }).catch(function(e) { 149 expect(e.error).to.be.instanceof(Error); 150 expect(e.request).to.deep.equal(request); 151 }); 152 }); 153 154 test('default responseType is text', function() { 155 request.send(successfulRequestOptions); 156 server.respond(); 157 158 return request.completes.then(function() { 159 expect(request.response).to.be.an('string') 160 }); 161 }); 162 163 test('default responseType of text is not applied, when async is false', function() { 164 var options = Object.create(successfulRequestOptions); 165 options.async = false; 166 167 request.send(options); 168 server.respond(); 169 170 return request.completes.then(function() { 171 expect(request.xhr.responseType).to.be.empty; 172 }); 173 }); 174 175 test('responseType can be configured via handleAs option', function() { 176 var options = Object.create(successfulRequestOptions); 177 options.handleAs = 'json'; 178 179 request.send(options); 180 expect(server.requests.length).to.be.equal(1); 181 expect(server.requests[0].requestHeaders['accept']).to.be.equal( 182 'application/json'); 183 server.respond(); 184 185 return request.completes.then(function() { 186 expect(request.response).to.be.an('object'); 187 }); 188 }); 189 190 test('setting jsonPrefix correctly strips it from the response', function() { 191 var options = { 192 url: '/responds_to_get_with_prefixed_json', 193 handleAs: 'json', 194 jsonPrefix: '])}while(1);</x>' 195 }; 196 197 request.send(options); 198 expect(server.requests.length).to.be.equal(1); 199 expect(server.requests[0].requestHeaders['accept']).to.be.equal( 200 'application/json'); 201 server.respond(); 202 203 return request.completes.then(function() { 204 expect(request.response).to.deep.eq({success: true}); 205 }); 206 }); 207 208 test('responseType cannot be configured via handleAs option, when async is false', function() { 209 var options = Object.create(successfulRequestOptions); 210 options.handleAs = 'json'; 211 options.async = false; 212 213 request.send(options); 214 expect(server.requests.length).to.be.equal(1); 215 expect(server.requests[0].requestHeaders['accept']).to.be.equal( 216 'application/json'); 217 server.respond(); 218 219 return request.completes.then(function() { 220 expect(request.response).to.be.a('string'); 221 }); 222 }); 223 224 test('headers are sent up', function() { 225 var options = Object.create(successfulRequestOptions); 226 options.headers = { 227 'foo': 'bar', 228 'accept': 'this should override the default' 229 }; 230 request.send(options); 231 expect(server.requests.length).to.be.equal(1); 232 var fakeXhr = server.requests[0] 233 expect(fakeXhr.requestHeaders['foo']).to.be.equal( 234 'bar'); 235 expect(fakeXhr.requestHeaders['accept']).to.be.equal( 236 'this should override the default'); 237 }); 238 239 test('headers are deduped by lowercasing', function() { 240 var options = Object.create(successfulRequestOptions); 241 options.headers = { 242 'foo': 'bar', 243 'Foo': 'bar', 244 'fOo': 'bar', 245 'Accept': 'this should also override the default' 246 }; 247 request.send(options); 248 expect(server.requests.length).to.be.equal(1); 249 var fakeXhr = server.requests[0] 250 expect(Object.keys(fakeXhr.requestHeaders).length).to.be.equal(2); 251 expect(fakeXhr.requestHeaders['foo']).to.be.equal( 252 'bar'); 253 expect(fakeXhr.requestHeaders['accept']).to.be.equal( 254 'this should also override the default'); 255 }); 256 }); 257 258 suite('special cases', function() { 259 test('treats status code 0 as success, though the outcome is ambiguous', function() { 260 // Note: file:// status code will probably be 0 no matter what happened. 261 request.send({ 262 url: '/responds_to_get_with_0' 263 }); 264 265 server.respond(); 266 267 expect(request.succeeded).to.be.equal(true); 268 }); 269 270 test('special form characters', function() { 271 var testCases = [ 272 { 273 test: null, 274 answer: '' 275 }, 276 { 277 test: undefined, 278 answer: '' 279 }, 280 { 281 test: NaN, 282 answer: 'NaN' 283 }, 284 { 285 test: new String('\n\r\n\r'), 286 answer: '%0D%0A%0D%0A%0D' // \r\n\r\n\r 287 }, 288 { 289 test: 0, 290 answer: '0' 291 }, 292 { 293 test: new String('hello world'), 294 answer: 'hello+world' 295 } 296 ]; 297 298 var testCase; 299 for (var i = 0; i < testCases.length; i++) { 300 testCase = testCases[i]; 301 var encoded = request._wwwFormUrlEncodePiece(testCase.test); 302 303 expect(encoded).to.be.equal(testCase.answer); 304 } 305 }); 306 }); 307 308 suite('errors', function() { 309 test('treats status codes between 1 and 199 as errors', function() { 310 request.send({ 311 url: '/responds_to_get_with_100' 312 }); 313 314 server.respond(); 315 316 expect(request.succeeded).to.be.equal(false); 317 }); 318 319 test('treats status codes between 300 and ∞ as errors', function() { 320 request.send({ 321 url: '/responds_to_get_with_500' 322 }); 323 324 server.respond(); 325 326 expect(request.succeeded).to.be.equal(false); 327 }); 328 }); 329 330 suite('status codes', function() { 331 test('status and statusText is set after a ambiguous request', function() { 332 request.send({ 333 url: '/responds_to_get_with_0' 334 }); 335 336 server.respond(); 337 338 expect(request.status).to.be.equal(0); 339 expect(request.statusText).to.be.equal(''); 340 }); 341 342 test('status and statusText is set after a request that succeeded', function() { 343 request.send({ 344 url: '/responds_to_get_with_json' 345 }); 346 347 server.respond(); 348 349 expect(request.status).to.be.equal(200); 350 expect(request.statusText).to.be.equal('OK'); 351 }); 352 353 test('status and statusText is set after a request that failed', function() { 354 request.send({ 355 url: '/responds_to_get_with_500' 356 }); 357 358 server.respond(); 359 360 expect(request.status).to.be.equal(500); 361 expect(request.statusText).to.be.equal('Internal Server Error'); 362 }); 363 }); 364 }); 365 </script> 366 367</body> 368</html> 369