OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 */ | 7 */ |
8 | 8 |
9 (function() { | 9 (function() { |
10 | 10 |
11 'use strict'; | 11 'use strict'; |
12 | 12 |
| 13 /** @type {sinon.FakeXhrCtrl} */ |
| 14 var fakeXhrCtrl; |
| 15 |
13 /** @type {sinon.FakeXhr} */ | 16 /** @type {sinon.FakeXhr} */ |
14 var fakeXhr; | 17 var fakeXhr; |
15 | 18 |
16 QUnit.module('xhr', { | 19 QUnit.module('xhr', { |
17 beforeEach: function() { | 20 beforeEach: function() { |
18 fakeXhr = null; | 21 fakeXhr = null; |
19 sinon.useFakeXMLHttpRequest().onCreate = | 22 fakeXhrCtrl = sinon.useFakeXMLHttpRequest(); |
| 23 fakeXhrCtrl.onCreate = |
20 function(/** sinon.FakeXhr */ xhr) { | 24 function(/** sinon.FakeXhr */ xhr) { |
21 fakeXhr = xhr; | 25 fakeXhr = xhr; |
22 }; | 26 }; |
| 27 remoting.identity = new remoting.Identity(); |
| 28 sinon.stub(remoting.identity, 'getToken'). |
| 29 returns(Promise.resolve('my_token')); |
| 30 }, |
| 31 afterEach: function() { |
| 32 remoting.identity = null; |
23 } | 33 } |
24 }); | 34 }); |
25 | 35 |
26 QUnit.test('urlencodeParamHash', function(assert) { | 36 QUnit.test('urlencodeParamHash', function(assert) { |
27 assert.equal( | 37 assert.equal( |
28 remoting.Xhr.urlencodeParamHash({}), | 38 remoting.Xhr.urlencodeParamHash({}), |
29 ''); | 39 ''); |
30 assert.equal( | 40 assert.equal( |
31 remoting.Xhr.urlencodeParamHash({'key': 'value'}), | 41 remoting.Xhr.urlencodeParamHash({'key': 'value'}), |
32 'key=value'); | 42 'key=value'); |
33 assert.equal( | 43 assert.equal( |
34 remoting.Xhr.urlencodeParamHash({'key /?=&': 'value /?=&'}), | 44 remoting.Xhr.urlencodeParamHash({'key /?=&': 'value /?=&'}), |
35 'key%20%2F%3F%3D%26=value%20%2F%3F%3D%26'); | 45 'key%20%2F%3F%3D%26=value%20%2F%3F%3D%26'); |
36 assert.equal( | 46 assert.equal( |
37 remoting.Xhr.urlencodeParamHash({'k1': 'v1', 'k2': 'v2'}), | 47 remoting.Xhr.urlencodeParamHash({'k1': 'v1', 'k2': 'v2'}), |
38 'k1=v1&k2=v2'); | 48 'k1=v1&k2=v2'); |
39 }); | 49 }); |
40 | 50 |
41 QUnit.test('basic GET', function(assert) { | 51 // |
| 52 // Test for what happens when the parameters are specified |
| 53 // incorrectly. |
| 54 // |
| 55 |
| 56 QUnit.test('invalid *content parameters', function(assert) { |
| 57 assert.throws(function() { |
| 58 new remoting.Xhr({ |
| 59 method: 'POST', |
| 60 url: 'http://foo.com', |
| 61 jsonContent: {}, |
| 62 formContent: {} |
| 63 }); |
| 64 }); |
| 65 |
| 66 assert.throws(function() { |
| 67 new remoting.Xhr({ |
| 68 method: 'POST', |
| 69 url: 'http://foo.com', |
| 70 textContent: '', |
| 71 formContent: {} |
| 72 }); |
| 73 }); |
| 74 |
| 75 assert.throws(function() { |
| 76 new remoting.Xhr({ |
| 77 method: 'POST', |
| 78 url: 'http://foo.com', |
| 79 textContent: '', |
| 80 jsonContent: {} |
| 81 }); |
| 82 }); |
| 83 }); |
| 84 |
| 85 |
| 86 QUnit.test('invalid URL parameters', function(assert) { |
| 87 assert.throws(function() { |
| 88 new remoting.Xhr({ |
| 89 method: 'POST', |
| 90 url: 'http://foo.com?', |
| 91 urlParams: {} |
| 92 }); |
| 93 }); |
| 94 |
| 95 assert.throws(function() { |
| 96 new remoting.Xhr({ |
| 97 method: 'POST', |
| 98 url: 'http://foo.com#', |
| 99 urlParams: {} |
| 100 }); |
| 101 }); |
| 102 }); |
| 103 |
| 104 QUnit.test('invalid auth parameters', function(assert) { |
| 105 assert.throws(function() { |
| 106 new remoting.Xhr({ |
| 107 method: 'POST', |
| 108 url: 'http://foo.com', |
| 109 useIdentity: false, |
| 110 oauthToken: '', |
| 111 headers: { |
| 112 'Authorization': '' |
| 113 } |
| 114 }); |
| 115 }); |
| 116 |
| 117 assert.throws(function() { |
| 118 new remoting.Xhr({ |
| 119 method: 'POST', |
| 120 url: 'http://foo.com', |
| 121 useIdentity: true, |
| 122 headers: { |
| 123 'Authorization': '' |
| 124 } |
| 125 }); |
| 126 }); |
| 127 |
| 128 assert.throws(function() { |
| 129 new remoting.Xhr({ |
| 130 method: 'POST', |
| 131 url: 'http://foo.com', |
| 132 useIdentity: true, |
| 133 oauthToken: '', |
| 134 headers: {} |
| 135 }); |
| 136 }); |
| 137 }); |
| 138 |
| 139 QUnit.test('invalid auth parameters', function(assert) { |
| 140 assert.throws(function() { |
| 141 new remoting.Xhr({ |
| 142 method: 'POST', |
| 143 url: 'http://foo.com', |
| 144 useIdentity: false, |
| 145 oauthToken: '', |
| 146 headers: { |
| 147 'Authorization': '' |
| 148 } |
| 149 }); |
| 150 }); |
| 151 |
| 152 assert.throws(function() { |
| 153 new remoting.Xhr({ |
| 154 method: 'POST', |
| 155 url: 'http://foo.com', |
| 156 useIdentity: true, |
| 157 headers: { |
| 158 'Authorization': '' |
| 159 } |
| 160 }); |
| 161 }); |
| 162 |
| 163 assert.throws(function() { |
| 164 new remoting.Xhr({ |
| 165 method: 'POST', |
| 166 url: 'http://foo.com', |
| 167 useIdentity: true, |
| 168 oauthToken: '', |
| 169 headers: {} |
| 170 }); |
| 171 }); |
| 172 }); |
| 173 |
| 174 // |
| 175 // The typical case. |
| 176 // |
| 177 |
| 178 QUnit.test('successful GET', function(assert) { |
42 var promise = new remoting.Xhr({ | 179 var promise = new remoting.Xhr({ |
43 method: 'GET', | 180 method: 'GET', |
44 url: 'http://foo.com', | 181 url: 'http://foo.com' |
45 responseType: remoting.Xhr.ResponseType.TEXT | |
46 }).start().then(function(response) { | 182 }).start().then(function(response) { |
47 assert.equal(response.status, 200); | 183 assert.equal(response.status, 200); |
48 assert.equal(response.getText(), 'body'); | 184 assert.equal(response.getText(), 'body'); |
49 }); | 185 }); |
50 assert.equal(fakeXhr.method, 'GET'); | 186 assert.equal(fakeXhr.method, 'GET'); |
51 assert.equal(fakeXhr.url, 'http://foo.com'); | 187 assert.equal(fakeXhr.url, 'http://foo.com'); |
52 assert.equal(fakeXhr.withCredentials, false); | 188 assert.equal(fakeXhr.withCredentials, false); |
53 assert.equal(fakeXhr.requestBody, null); | 189 assert.equal(fakeXhr.requestBody, null); |
54 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); | 190 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); |
55 fakeXhr.respond(200, {}, 'body'); | 191 fakeXhr.respond(200, {}, 'body'); |
56 return promise; | 192 return promise; |
57 }); | 193 }); |
58 | 194 |
59 QUnit.test('GET with param string', function(assert) { | 195 // |
| 196 // Tests for the effect of acceptJson. |
| 197 // |
| 198 |
| 199 QUnit.test('acceptJson required', function(assert) { |
| 200 var promise = new remoting.Xhr({ |
| 201 method: 'GET', |
| 202 url: 'http://foo.com' |
| 203 }).start().then(function(response) { |
| 204 assert.throws(response.getJson); |
| 205 }); |
| 206 fakeXhr.respond(200, {}, '{}'); |
| 207 return promise; |
| 208 }); |
| 209 |
| 210 QUnit.test('JSON response', function(assert) { |
| 211 var responseJson = { |
| 212 'myJsonData': [true] |
| 213 }; |
| 214 var responseText = JSON.stringify(responseJson); |
60 var promise = new remoting.Xhr({ | 215 var promise = new remoting.Xhr({ |
61 method: 'GET', | 216 method: 'GET', |
62 url: 'http://foo.com', | 217 url: 'http://foo.com', |
63 responseType: remoting.Xhr.ResponseType.TEXT, | 218 acceptJson: true |
64 urlParams: 'the_param_string' | |
65 }).start().then(function(response) { | 219 }).start().then(function(response) { |
66 assert.equal(response.status, 200); | 220 // Calling getText is still OK even when a JSON response is |
67 assert.equal(response.getText(), 'body'); | 221 // requested. |
| 222 assert.equal( |
| 223 response.getText(), |
| 224 responseText); |
| 225 // Check that getJson works as advertised. |
| 226 assert.deepEqual( |
| 227 response.getJson(), |
| 228 responseJson); |
| 229 // Calling getJson multiple times doesn't re-parse the response. |
| 230 assert.strictEqual( |
| 231 response.getJson(), |
| 232 response.getJson()); |
68 }); | 233 }); |
69 assert.equal(fakeXhr.method, 'GET'); | 234 fakeXhr.respond(200, {}, responseText); |
70 assert.equal(fakeXhr.url, 'http://foo.com?the_param_string'); | |
71 assert.equal(fakeXhr.withCredentials, false); | |
72 assert.equal(fakeXhr.requestBody, null); | |
73 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); | |
74 fakeXhr.respond(200, {}, 'body'); | |
75 return promise; | 235 return promise; |
76 }); | 236 }); |
77 | 237 |
78 QUnit.test('GET with param object', function(assert) { | 238 // |
79 var promise = new remoting.Xhr({ | 239 // Tests for various parameters that modify the HTTP request. |
| 240 // |
| 241 |
| 242 QUnit.test('GET with param string', function(assert) { |
| 243 new remoting.Xhr({ |
80 method: 'GET', | 244 method: 'GET', |
81 url: 'http://foo.com', | 245 url: 'http://foo.com', |
82 responseType: remoting.Xhr.ResponseType.TEXT, | 246 urlParams: 'the_param_string' |
| 247 }).start(); |
| 248 assert.equal(fakeXhr.url, 'http://foo.com?the_param_string'); |
| 249 }); |
| 250 |
| 251 QUnit.test('GET with param object', function(assert) { |
| 252 new remoting.Xhr({ |
| 253 method: 'GET', |
| 254 url: 'http://foo.com', |
83 urlParams: {'a': 'b', 'c': 'd'} | 255 urlParams: {'a': 'b', 'c': 'd'} |
84 }).start().then(function(response) { | 256 }).start(); |
85 assert.equal(response.status, 200); | |
86 assert.equal(response.getText(), 'body'); | |
87 }); | |
88 assert.equal(fakeXhr.method, 'GET'); | |
89 assert.equal(fakeXhr.url, 'http://foo.com?a=b&c=d'); | 257 assert.equal(fakeXhr.url, 'http://foo.com?a=b&c=d'); |
90 assert.equal(fakeXhr.withCredentials, false); | |
91 assert.equal(fakeXhr.requestBody, null); | |
92 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); | |
93 fakeXhr.respond(200, {}, 'body'); | |
94 return promise; | |
95 }); | 258 }); |
96 | 259 |
97 QUnit.test('GET with headers', function(assert) { | 260 QUnit.test('GET with headers', function(assert) { |
98 var promise = new remoting.Xhr({ | 261 new remoting.Xhr({ |
99 method: 'GET', | 262 method: 'GET', |
100 url: 'http://foo.com', | 263 url: 'http://foo.com', |
101 responseType: remoting.Xhr.ResponseType.TEXT, | |
102 headers: {'Header1': 'headerValue1', 'Header2': 'headerValue2'} | 264 headers: {'Header1': 'headerValue1', 'Header2': 'headerValue2'} |
103 }).start().then(function(response) { | 265 }).start(); |
104 assert.equal(response.status, 200); | |
105 assert.equal(response.getText(), 'body'); | |
106 }); | |
107 assert.equal(fakeXhr.method, 'GET'); | |
108 assert.equal(fakeXhr.url, 'http://foo.com'); | |
109 assert.equal(fakeXhr.withCredentials, false); | |
110 assert.equal(fakeXhr.requestBody, null); | |
111 assert.equal( | 266 assert.equal( |
112 fakeXhr.requestHeaders['Header1'], | 267 fakeXhr.requestHeaders['Header1'], |
113 'headerValue1'); | 268 'headerValue1'); |
114 assert.equal( | 269 assert.equal( |
115 fakeXhr.requestHeaders['Header2'], | 270 fakeXhr.requestHeaders['Header2'], |
116 'headerValue2'); | 271 'headerValue2'); |
117 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); | |
118 fakeXhr.respond(200, {}, 'body'); | |
119 return promise; | |
120 }); | 272 }); |
121 | 273 |
122 | 274 |
123 QUnit.test('GET with credentials', function(assert) { | 275 QUnit.test('GET with credentials', function(assert) { |
124 var promise = new remoting.Xhr({ | 276 new remoting.Xhr({ |
125 method: 'GET', | 277 method: 'GET', |
126 url: 'http://foo.com', | 278 url: 'http://foo.com', |
127 responseType: remoting.Xhr.ResponseType.TEXT, | |
128 withCredentials: true | 279 withCredentials: true |
129 }).start().then(function(response) { | 280 }).start(); |
130 assert.equal(response.status, 200); | |
131 assert.equal(response.getText(), 'body'); | |
132 }); | |
133 assert.equal(fakeXhr.method, 'GET'); | |
134 assert.equal(fakeXhr.url, 'http://foo.com'); | |
135 assert.equal(fakeXhr.withCredentials, true); | 281 assert.equal(fakeXhr.withCredentials, true); |
136 assert.equal(fakeXhr.requestBody, null); | |
137 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); | |
138 fakeXhr.respond(200, {}, 'body'); | |
139 return promise; | |
140 }); | 282 }); |
141 | 283 |
| 284 // |
| 285 // Checking that typical POST requests work. |
| 286 // |
| 287 |
142 QUnit.test('POST with text content', function(assert) { | 288 QUnit.test('POST with text content', function(assert) { |
143 var done = assert.async(); | 289 var done = assert.async(); |
144 | 290 |
145 var promise = new remoting.Xhr({ | 291 var promise = new remoting.Xhr({ |
146 method: 'POST', | 292 method: 'POST', |
147 url: 'http://foo.com', | 293 url: 'http://foo.com', |
148 responseType: remoting.Xhr.ResponseType.TEXT, | |
149 textContent: 'the_content_string' | 294 textContent: 'the_content_string' |
150 }).start().then(function(response) { | 295 }).start().then(function(response) { |
151 assert.equal(response.status, 200); | 296 assert.equal(response.status, 200); |
152 assert.equal(response.getText(), 'body'); | 297 assert.equal(response.getText(), 'body'); |
153 done(); | 298 done(); |
154 }); | 299 }); |
155 assert.equal(fakeXhr.method, 'POST'); | 300 assert.equal(fakeXhr.method, 'POST'); |
156 assert.equal(fakeXhr.url, 'http://foo.com'); | 301 assert.equal(fakeXhr.url, 'http://foo.com'); |
157 assert.equal(fakeXhr.withCredentials, false); | 302 assert.equal(fakeXhr.withCredentials, false); |
158 assert.equal(fakeXhr.requestBody, 'the_content_string'); | 303 assert.equal(fakeXhr.requestBody, 'the_content_string'); |
159 assert.ok(!('Content-type' in fakeXhr.requestHeaders)); | 304 assert.equal(fakeXhr.requestHeaders['Content-type'], |
| 305 'text/plain; charset=UTF-8'); |
160 fakeXhr.respond(200, {}, 'body'); | 306 fakeXhr.respond(200, {}, 'body'); |
161 return promise; | 307 return promise; |
162 }); | 308 }); |
163 | 309 |
164 QUnit.test('POST with form content', function(assert) { | 310 QUnit.test('POST with form content', function(assert) { |
165 var promise = new remoting.Xhr({ | 311 new remoting.Xhr({ |
166 method: 'POST', | 312 method: 'POST', |
167 url: 'http://foo.com', | 313 url: 'http://foo.com', |
168 responseType: remoting.Xhr.ResponseType.TEXT, | |
169 formContent: {'a': 'b', 'c': 'd'} | 314 formContent: {'a': 'b', 'c': 'd'} |
170 }).start().then(function(response) { | 315 }).start(); |
171 assert.equal(response.status, 200); | |
172 assert.equal(response.getText(), 'body'); | |
173 }); | |
174 assert.equal(fakeXhr.method, 'POST'); | |
175 assert.equal(fakeXhr.url, 'http://foo.com'); | |
176 assert.equal(fakeXhr.withCredentials, false); | |
177 assert.equal(fakeXhr.requestBody, 'a=b&c=d'); | 316 assert.equal(fakeXhr.requestBody, 'a=b&c=d'); |
178 assert.equal( | 317 assert.equal( |
179 fakeXhr.requestHeaders['Content-type'], | 318 fakeXhr.requestHeaders['Content-type'], |
180 'application/x-www-form-urlencoded'); | 319 'application/x-www-form-urlencoded; charset=UTF-8'); |
181 fakeXhr.respond(200, {}, 'body'); | 320 }); |
| 321 |
| 322 // |
| 323 // Tests for authentication-related options. |
| 324 // |
| 325 |
| 326 QUnit.test('GET with auth token', function(assert) { |
| 327 new remoting.Xhr({ |
| 328 method: 'GET', |
| 329 url: 'http://foo.com', |
| 330 oauthToken: 'my_token' |
| 331 }).start(); |
| 332 assert.equal(fakeXhr.requestHeaders['Authorization'], |
| 333 'Bearer my_token'); |
| 334 }); |
| 335 |
| 336 QUnit.test('GET with useIdentity', function(assert) { |
| 337 var xhr = new remoting.Xhr({ |
| 338 method: 'GET', |
| 339 url: 'http://foo.com', |
| 340 useIdentity: true |
| 341 }); |
| 342 |
| 343 xhr.start(); |
| 344 |
| 345 var done = assert.async(); |
| 346 fakeXhr.addEventListener('loadstart', function() { |
| 347 assert.equal(fakeXhr.requestHeaders['Authorization'], |
| 348 'Bearer my_token'); |
| 349 done(); |
| 350 }); |
| 351 }); |
| 352 |
| 353 |
| 354 // |
| 355 // Tests for the abort method. |
| 356 // |
| 357 |
| 358 QUnit.test('abort before start', function(assert) { |
| 359 assert.expect(0); |
| 360 var xhr = new remoting.Xhr({ |
| 361 method: 'GET', |
| 362 url: 'http://foo.com' |
| 363 }); |
| 364 fakeXhr.addEventListener('abort', assert.async()); |
| 365 xhr.abort(); |
| 366 xhr.start().then(function() { |
| 367 assert.ok(false, 'promise resolved after abort'); |
| 368 }, function() { |
| 369 assert.ok(false, 'promise rejected after abort'); |
| 370 }); |
| 371 }); |
| 372 |
| 373 QUnit.test('abort before send', function(assert) { |
| 374 assert.expect(0); |
| 375 var xhr = new remoting.Xhr({ |
| 376 method: 'GET', |
| 377 url: 'http://foo.com', |
| 378 useIdentity: true |
| 379 }); |
| 380 xhr.start().then(function() { |
| 381 assert.ok(false, 'promise resolved after abort'); |
| 382 }, function() { |
| 383 assert.ok(false, 'promise rejected after abort'); |
| 384 }); |
| 385 fakeXhr.addEventListener('abort', assert.async()); |
| 386 xhr.abort(); |
| 387 }); |
| 388 |
| 389 QUnit.test('abort after resolved', function(assert) { |
| 390 var xhr = new remoting.Xhr({ |
| 391 method: 'GET', |
| 392 url: 'http://foo.com', |
| 393 useIdentity: true |
| 394 }); |
| 395 var promise = xhr.start().then(function() { |
| 396 assert.ok(true); |
| 397 fakeXhr.addEventListener('abort', assert.async()); |
| 398 xhr.abort(); |
| 399 }); |
| 400 fakeXhr.addEventListener('loadstart', function() { |
| 401 fakeXhr.respond(200, {}, 'body'); |
| 402 }); |
182 return promise; | 403 return promise; |
183 }); | 404 }); |
184 | 405 |
185 QUnit.test('defaultResponse 200', function(assert) { | |
186 var done = assert.async(); | |
187 | |
188 var onDone = function() { | |
189 assert.ok(true); | |
190 done(); | |
191 }; | |
192 | |
193 var onError = function(error) { | |
194 assert.ok(false); | |
195 done(); | |
196 }; | |
197 | |
198 new remoting.Xhr({ | |
199 method: 'POST', | |
200 url: 'http://foo.com' | |
201 }).start().then(remoting.Xhr.defaultResponse(onDone, onError)); | |
202 fakeXhr.respond(200, {}, ''); | |
203 }); | |
204 | |
205 | |
206 QUnit.test('defaultResponse 404', function(assert) { | |
207 var done = assert.async(); | |
208 | |
209 var onDone = function() { | |
210 assert.ok(false); | |
211 done(); | |
212 }; | |
213 | |
214 var onError = function(error) { | |
215 assert.ok(true); | |
216 done(); | |
217 }; | |
218 | |
219 new remoting.Xhr({ | |
220 method: 'POST', | |
221 url: 'http://foo.com' | |
222 }).start().then(remoting.Xhr.defaultResponse(onDone, onError)); | |
223 fakeXhr.respond(404, {}, ''); | |
224 }); | |
225 | |
226 })(); | 406 })(); |
OLD | NEW |