services/common/tests/unit/test_restrequest.js

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 "use strict";
michael@0 5
michael@0 6 Cu.import("resource://gre/modules/NetUtil.jsm");
michael@0 7 Cu.import("resource://gre/modules/Log.jsm");
michael@0 8 Cu.import("resource://services-common/rest.js");
michael@0 9 Cu.import("resource://services-common/utils.js");
michael@0 10
michael@0 11 function run_test() {
michael@0 12 Log.repository.getLogger("Services.Common.RESTRequest").level =
michael@0 13 Log.Level.Trace;
michael@0 14 initTestLogging("Trace");
michael@0 15
michael@0 16 run_next_test();
michael@0 17 }
michael@0 18
michael@0 19 /**
michael@0 20 * Initializing a RESTRequest with an invalid URI throws
michael@0 21 * NS_ERROR_MALFORMED_URI.
michael@0 22 */
michael@0 23 add_test(function test_invalid_uri() {
michael@0 24 do_check_throws(function() {
michael@0 25 new RESTRequest("an invalid URI");
michael@0 26 }, Cr.NS_ERROR_MALFORMED_URI);
michael@0 27 run_next_test();
michael@0 28 });
michael@0 29
michael@0 30 /**
michael@0 31 * Verify initial values for attributes.
michael@0 32 */
michael@0 33 add_test(function test_attributes() {
michael@0 34 let uri = "http://foo.com/bar/baz";
michael@0 35 let request = new RESTRequest(uri);
michael@0 36
michael@0 37 do_check_true(request.uri instanceof Ci.nsIURI);
michael@0 38 do_check_eq(request.uri.spec, uri);
michael@0 39 do_check_eq(request.response, null);
michael@0 40 do_check_eq(request.status, request.NOT_SENT);
michael@0 41 let expectedLoadFlags = Ci.nsIRequest.LOAD_BYPASS_CACHE |
michael@0 42 Ci.nsIRequest.INHIBIT_CACHING |
michael@0 43 Ci.nsIRequest.LOAD_ANONYMOUS;
michael@0 44 do_check_eq(request.loadFlags, expectedLoadFlags);
michael@0 45
michael@0 46 run_next_test();
michael@0 47 });
michael@0 48
michael@0 49 /**
michael@0 50 * Verify that a proxy auth redirect doesn't break us. This has to be the first
michael@0 51 * request made in the file!
michael@0 52 */
michael@0 53 add_test(function test_proxy_auth_redirect() {
michael@0 54 let pacFetched = false;
michael@0 55 function pacHandler(metadata, response) {
michael@0 56 pacFetched = true;
michael@0 57 let body = 'function FindProxyForURL(url, host) { return "DIRECT"; }';
michael@0 58 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 59 response.setHeader("Content-Type", "application/x-ns-proxy-autoconfig", false);
michael@0 60 response.bodyOutputStream.write(body, body.length);
michael@0 61 }
michael@0 62
michael@0 63 let fetched = false;
michael@0 64 function original(metadata, response) {
michael@0 65 fetched = true;
michael@0 66 let body = "TADA!";
michael@0 67 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 68 response.bodyOutputStream.write(body, body.length);
michael@0 69 }
michael@0 70
michael@0 71 let server = httpd_setup({
michael@0 72 "/original": original,
michael@0 73 "/pac3": pacHandler
michael@0 74 });
michael@0 75 PACSystemSettings.PACURI = server.baseURI + "/pac3";
michael@0 76 installFakePAC();
michael@0 77
michael@0 78 let res = new RESTRequest(server.baseURI + "/original");
michael@0 79 res.get(function (error) {
michael@0 80 do_check_true(pacFetched);
michael@0 81 do_check_true(fetched);
michael@0 82 do_check_true(!error);
michael@0 83 do_check_true(this.response.success);
michael@0 84 do_check_eq("TADA!", this.response.body);
michael@0 85 uninstallFakePAC();
michael@0 86 server.stop(run_next_test);
michael@0 87 });
michael@0 88 });
michael@0 89
michael@0 90 /**
michael@0 91 * Ensure that failures that cause asyncOpen to throw
michael@0 92 * result in callbacks being invoked.
michael@0 93 * Bug 826086.
michael@0 94 */
michael@0 95 add_test(function test_forbidden_port() {
michael@0 96 let request = new RESTRequest("http://localhost:6000/");
michael@0 97 request.get(function(error) {
michael@0 98 if (!error) {
michael@0 99 do_throw("Should have got an error.");
michael@0 100 }
michael@0 101 do_check_eq(error.result, Components.results.NS_ERROR_PORT_ACCESS_NOT_ALLOWED);
michael@0 102 run_next_test();
michael@0 103 });
michael@0 104 });
michael@0 105
michael@0 106 /**
michael@0 107 * Demonstrate API short-hand: create a request and dispatch it immediately.
michael@0 108 */
michael@0 109 add_test(function test_simple_get() {
michael@0 110 let handler = httpd_handler(200, "OK", "Huzzah!");
michael@0 111 let server = httpd_setup({"/resource": handler});
michael@0 112
michael@0 113 let request = new RESTRequest(server.baseURI + "/resource").get(function (error) {
michael@0 114 do_check_eq(error, null);
michael@0 115
michael@0 116 do_check_eq(this.status, this.COMPLETED);
michael@0 117 do_check_true(this.response.success);
michael@0 118 do_check_eq(this.response.status, 200);
michael@0 119 do_check_eq(this.response.body, "Huzzah!");
michael@0 120
michael@0 121 server.stop(run_next_test);
michael@0 122 });
michael@0 123 do_check_eq(request.status, request.SENT);
michael@0 124 do_check_eq(request.method, "GET");
michael@0 125 });
michael@0 126
michael@0 127 /**
michael@0 128 * Test HTTP GET with all bells and whistles.
michael@0 129 */
michael@0 130 add_test(function test_get() {
michael@0 131 let handler = httpd_handler(200, "OK", "Huzzah!");
michael@0 132 let server = httpd_setup({"/resource": handler});
michael@0 133
michael@0 134 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 135 do_check_eq(request.status, request.NOT_SENT);
michael@0 136
michael@0 137 request.onProgress = request.onComplete = function () {
michael@0 138 do_throw("This function should have been overwritten!");
michael@0 139 };
michael@0 140
michael@0 141 let onProgress_called = false;
michael@0 142 function onProgress() {
michael@0 143 onProgress_called = true;
michael@0 144 do_check_eq(this.status, request.IN_PROGRESS);
michael@0 145 do_check_true(this.response.body.length > 0);
michael@0 146
michael@0 147 do_check_true(!!(this.channel.loadFlags & Ci.nsIRequest.LOAD_BYPASS_CACHE));
michael@0 148 do_check_true(!!(this.channel.loadFlags & Ci.nsIRequest.INHIBIT_CACHING));
michael@0 149 };
michael@0 150
michael@0 151 function onComplete(error) {
michael@0 152 do_check_eq(error, null);
michael@0 153
michael@0 154 do_check_eq(this.status, this.COMPLETED);
michael@0 155 do_check_true(this.response.success);
michael@0 156 do_check_eq(this.response.status, 200);
michael@0 157 do_check_eq(this.response.body, "Huzzah!");
michael@0 158 do_check_eq(handler.request.method, "GET");
michael@0 159
michael@0 160 do_check_true(onProgress_called);
michael@0 161 CommonUtils.nextTick(function () {
michael@0 162 do_check_eq(request.onComplete, null);
michael@0 163 do_check_eq(request.onProgress, null);
michael@0 164 server.stop(run_next_test);
michael@0 165 });
michael@0 166 };
michael@0 167
michael@0 168 do_check_eq(request.get(onComplete, onProgress), request);
michael@0 169 do_check_eq(request.status, request.SENT);
michael@0 170 do_check_eq(request.method, "GET");
michael@0 171 do_check_throws(function () {
michael@0 172 request.get();
michael@0 173 });
michael@0 174 });
michael@0 175
michael@0 176 /**
michael@0 177 * Test HTTP GET with UTF-8 content, and custom Content-Type.
michael@0 178 */
michael@0 179 add_test(function test_get_utf8() {
michael@0 180 let response = "Hello World or Καλημέρα κόσμε or こんにちは 世界";
michael@0 181
michael@0 182 let contentType = "text/plain";
michael@0 183 let charset = true;
michael@0 184 let charsetSuffix = "; charset=UTF-8";
michael@0 185
michael@0 186 let server = httpd_setup({"/resource": function(req, res) {
michael@0 187 res.setStatusLine(req.httpVersion, 200, "OK");
michael@0 188 res.setHeader("Content-Type", contentType + (charset ? charsetSuffix : ""));
michael@0 189
michael@0 190 let converter = Cc["@mozilla.org/intl/converter-output-stream;1"]
michael@0 191 .createInstance(Ci.nsIConverterOutputStream);
michael@0 192 converter.init(res.bodyOutputStream, "UTF-8", 0, 0x0000);
michael@0 193 converter.writeString(response);
michael@0 194 converter.close();
michael@0 195 }});
michael@0 196
michael@0 197 // Check if charset in Content-Type is propertly interpreted.
michael@0 198 let request1 = new RESTRequest(server.baseURI + "/resource");
michael@0 199 request1.get(function(error) {
michael@0 200 do_check_null(error);
michael@0 201
michael@0 202 do_check_eq(request1.response.status, 200);
michael@0 203 do_check_eq(request1.response.body, response);
michael@0 204 do_check_eq(request1.response.headers["content-type"],
michael@0 205 contentType + charsetSuffix);
michael@0 206
michael@0 207 // Check that we default to UTF-8 if Content-Type doesn't have a charset.
michael@0 208 charset = false;
michael@0 209 let request2 = new RESTRequest(server.baseURI + "/resource");
michael@0 210 request2.get(function(error) {
michael@0 211 do_check_null(error);
michael@0 212
michael@0 213 do_check_eq(request2.response.status, 200);
michael@0 214 do_check_eq(request2.response.body, response);
michael@0 215 do_check_eq(request2.response.headers["content-type"], contentType);
michael@0 216 do_check_eq(request2.response.charset, "utf-8");
michael@0 217
michael@0 218 server.stop(run_next_test);
michael@0 219 });
michael@0 220 });
michael@0 221 });
michael@0 222
michael@0 223 /**
michael@0 224 * Test more variations of charset handling.
michael@0 225 */
michael@0 226 add_test(function test_charsets() {
michael@0 227 let response = "Hello World, I can't speak Russian";
michael@0 228
michael@0 229 let contentType = "text/plain";
michael@0 230 let charset = true;
michael@0 231 let charsetSuffix = "; charset=us-ascii";
michael@0 232
michael@0 233 let server = httpd_setup({"/resource": function(req, res) {
michael@0 234 res.setStatusLine(req.httpVersion, 200, "OK");
michael@0 235 res.setHeader("Content-Type", contentType + (charset ? charsetSuffix : ""));
michael@0 236
michael@0 237 let converter = Cc["@mozilla.org/intl/converter-output-stream;1"]
michael@0 238 .createInstance(Ci.nsIConverterOutputStream);
michael@0 239 converter.init(res.bodyOutputStream, "us-ascii", 0, 0x0000);
michael@0 240 converter.writeString(response);
michael@0 241 converter.close();
michael@0 242 }});
michael@0 243
michael@0 244 // Check that provided charset overrides hint.
michael@0 245 let request1 = new RESTRequest(server.baseURI + "/resource");
michael@0 246 request1.charset = "not-a-charset";
michael@0 247 request1.get(function(error) {
michael@0 248 do_check_null(error);
michael@0 249
michael@0 250 do_check_eq(request1.response.status, 200);
michael@0 251 do_check_eq(request1.response.body, response);
michael@0 252 do_check_eq(request1.response.headers["content-type"],
michael@0 253 contentType + charsetSuffix);
michael@0 254 do_check_eq(request1.response.charset, "us-ascii");
michael@0 255
michael@0 256 // Check that hint is used if Content-Type doesn't have a charset.
michael@0 257 charset = false;
michael@0 258 let request2 = new RESTRequest(server.baseURI + "/resource");
michael@0 259 request2.charset = "us-ascii";
michael@0 260 request2.get(function(error) {
michael@0 261 do_check_null(error);
michael@0 262
michael@0 263 do_check_eq(request2.response.status, 200);
michael@0 264 do_check_eq(request2.response.body, response);
michael@0 265 do_check_eq(request2.response.headers["content-type"], contentType);
michael@0 266 do_check_eq(request2.response.charset, "us-ascii");
michael@0 267
michael@0 268 server.stop(run_next_test);
michael@0 269 });
michael@0 270 });
michael@0 271 });
michael@0 272
michael@0 273 /**
michael@0 274 * Test HTTP PUT with a simple string argument and default Content-Type.
michael@0 275 */
michael@0 276 add_test(function test_put() {
michael@0 277 let handler = httpd_handler(200, "OK", "Got it!");
michael@0 278 let server = httpd_setup({"/resource": handler});
michael@0 279
michael@0 280 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 281 do_check_eq(request.status, request.NOT_SENT);
michael@0 282
michael@0 283 request.onProgress = request.onComplete = function () {
michael@0 284 do_throw("This function should have been overwritten!");
michael@0 285 };
michael@0 286
michael@0 287 let onProgress_called = false;
michael@0 288 function onProgress() {
michael@0 289 onProgress_called = true;
michael@0 290 do_check_eq(this.status, request.IN_PROGRESS);
michael@0 291 do_check_true(this.response.body.length > 0);
michael@0 292 };
michael@0 293
michael@0 294 function onComplete(error) {
michael@0 295 do_check_eq(error, null);
michael@0 296
michael@0 297 do_check_eq(this.status, this.COMPLETED);
michael@0 298 do_check_true(this.response.success);
michael@0 299 do_check_eq(this.response.status, 200);
michael@0 300 do_check_eq(this.response.body, "Got it!");
michael@0 301
michael@0 302 do_check_eq(handler.request.method, "PUT");
michael@0 303 do_check_eq(handler.request.body, "Hullo?");
michael@0 304 do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
michael@0 305
michael@0 306 do_check_true(onProgress_called);
michael@0 307 CommonUtils.nextTick(function () {
michael@0 308 do_check_eq(request.onComplete, null);
michael@0 309 do_check_eq(request.onProgress, null);
michael@0 310 server.stop(run_next_test);
michael@0 311 });
michael@0 312 };
michael@0 313
michael@0 314 do_check_eq(request.put("Hullo?", onComplete, onProgress), request);
michael@0 315 do_check_eq(request.status, request.SENT);
michael@0 316 do_check_eq(request.method, "PUT");
michael@0 317 do_check_throws(function () {
michael@0 318 request.put("Hai!");
michael@0 319 });
michael@0 320 });
michael@0 321
michael@0 322 /**
michael@0 323 * Test HTTP POST with a simple string argument and default Content-Type.
michael@0 324 */
michael@0 325 add_test(function test_post() {
michael@0 326 let handler = httpd_handler(200, "OK", "Got it!");
michael@0 327 let server = httpd_setup({"/resource": handler});
michael@0 328
michael@0 329 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 330 do_check_eq(request.status, request.NOT_SENT);
michael@0 331
michael@0 332 request.onProgress = request.onComplete = function () {
michael@0 333 do_throw("This function should have been overwritten!");
michael@0 334 };
michael@0 335
michael@0 336 let onProgress_called = false;
michael@0 337 function onProgress() {
michael@0 338 onProgress_called = true;
michael@0 339 do_check_eq(this.status, request.IN_PROGRESS);
michael@0 340 do_check_true(this.response.body.length > 0);
michael@0 341 };
michael@0 342
michael@0 343 function onComplete(error) {
michael@0 344 do_check_eq(error, null);
michael@0 345
michael@0 346 do_check_eq(this.status, this.COMPLETED);
michael@0 347 do_check_true(this.response.success);
michael@0 348 do_check_eq(this.response.status, 200);
michael@0 349 do_check_eq(this.response.body, "Got it!");
michael@0 350
michael@0 351 do_check_eq(handler.request.method, "POST");
michael@0 352 do_check_eq(handler.request.body, "Hullo?");
michael@0 353 do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
michael@0 354
michael@0 355 do_check_true(onProgress_called);
michael@0 356 CommonUtils.nextTick(function () {
michael@0 357 do_check_eq(request.onComplete, null);
michael@0 358 do_check_eq(request.onProgress, null);
michael@0 359 server.stop(run_next_test);
michael@0 360 });
michael@0 361 };
michael@0 362
michael@0 363 do_check_eq(request.post("Hullo?", onComplete, onProgress), request);
michael@0 364 do_check_eq(request.status, request.SENT);
michael@0 365 do_check_eq(request.method, "POST");
michael@0 366 do_check_throws(function () {
michael@0 367 request.post("Hai!");
michael@0 368 });
michael@0 369 });
michael@0 370
michael@0 371 /**
michael@0 372 * Test HTTP DELETE.
michael@0 373 */
michael@0 374 add_test(function test_delete() {
michael@0 375 let handler = httpd_handler(200, "OK", "Got it!");
michael@0 376 let server = httpd_setup({"/resource": handler});
michael@0 377
michael@0 378 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 379 do_check_eq(request.status, request.NOT_SENT);
michael@0 380
michael@0 381 request.onProgress = request.onComplete = function () {
michael@0 382 do_throw("This function should have been overwritten!");
michael@0 383 };
michael@0 384
michael@0 385 let onProgress_called = false;
michael@0 386 function onProgress() {
michael@0 387 onProgress_called = true;
michael@0 388 do_check_eq(this.status, request.IN_PROGRESS);
michael@0 389 do_check_true(this.response.body.length > 0);
michael@0 390 };
michael@0 391
michael@0 392 function onComplete(error) {
michael@0 393 do_check_eq(error, null);
michael@0 394
michael@0 395 do_check_eq(this.status, this.COMPLETED);
michael@0 396 do_check_true(this.response.success);
michael@0 397 do_check_eq(this.response.status, 200);
michael@0 398 do_check_eq(this.response.body, "Got it!");
michael@0 399 do_check_eq(handler.request.method, "DELETE");
michael@0 400
michael@0 401 do_check_true(onProgress_called);
michael@0 402 CommonUtils.nextTick(function () {
michael@0 403 do_check_eq(request.onComplete, null);
michael@0 404 do_check_eq(request.onProgress, null);
michael@0 405 server.stop(run_next_test);
michael@0 406 });
michael@0 407 };
michael@0 408
michael@0 409 do_check_eq(request.delete(onComplete, onProgress), request);
michael@0 410 do_check_eq(request.status, request.SENT);
michael@0 411 do_check_eq(request.method, "DELETE");
michael@0 412 do_check_throws(function () {
michael@0 413 request.delete();
michael@0 414 });
michael@0 415 });
michael@0 416
michael@0 417 /**
michael@0 418 * Test an HTTP response with a non-200 status code.
michael@0 419 */
michael@0 420 add_test(function test_get_404() {
michael@0 421 let handler = httpd_handler(404, "Not Found", "Cannae find it!");
michael@0 422 let server = httpd_setup({"/resource": handler});
michael@0 423
michael@0 424 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 425 request.get(function (error) {
michael@0 426 do_check_eq(error, null);
michael@0 427
michael@0 428 do_check_eq(this.status, this.COMPLETED);
michael@0 429 do_check_false(this.response.success);
michael@0 430 do_check_eq(this.response.status, 404);
michael@0 431 do_check_eq(this.response.body, "Cannae find it!");
michael@0 432
michael@0 433 server.stop(run_next_test);
michael@0 434 });
michael@0 435 });
michael@0 436
michael@0 437 /**
michael@0 438 * The 'data' argument to PUT, if not a string already, is automatically
michael@0 439 * stringified as JSON.
michael@0 440 */
michael@0 441 add_test(function test_put_json() {
michael@0 442 let handler = httpd_handler(200, "OK");
michael@0 443 let server = httpd_setup({"/resource": handler});
michael@0 444
michael@0 445 let sample_data = {
michael@0 446 some: "sample_data",
michael@0 447 injson: "format",
michael@0 448 number: 42
michael@0 449 };
michael@0 450 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 451 request.put(sample_data, function (error) {
michael@0 452 do_check_eq(error, null);
michael@0 453
michael@0 454 do_check_eq(this.status, this.COMPLETED);
michael@0 455 do_check_true(this.response.success);
michael@0 456 do_check_eq(this.response.status, 200);
michael@0 457 do_check_eq(this.response.body, "");
michael@0 458
michael@0 459 do_check_eq(handler.request.method, "PUT");
michael@0 460 do_check_eq(handler.request.body, JSON.stringify(sample_data));
michael@0 461 do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
michael@0 462
michael@0 463 server.stop(run_next_test);
michael@0 464 });
michael@0 465 });
michael@0 466
michael@0 467 /**
michael@0 468 * The 'data' argument to POST, if not a string already, is automatically
michael@0 469 * stringified as JSON.
michael@0 470 */
michael@0 471 add_test(function test_post_json() {
michael@0 472 let handler = httpd_handler(200, "OK");
michael@0 473 let server = httpd_setup({"/resource": handler});
michael@0 474
michael@0 475 let sample_data = {
michael@0 476 some: "sample_data",
michael@0 477 injson: "format",
michael@0 478 number: 42
michael@0 479 };
michael@0 480 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 481 request.post(sample_data, function (error) {
michael@0 482 do_check_eq(error, null);
michael@0 483
michael@0 484 do_check_eq(this.status, this.COMPLETED);
michael@0 485 do_check_true(this.response.success);
michael@0 486 do_check_eq(this.response.status, 200);
michael@0 487 do_check_eq(this.response.body, "");
michael@0 488
michael@0 489 do_check_eq(handler.request.method, "POST");
michael@0 490 do_check_eq(handler.request.body, JSON.stringify(sample_data));
michael@0 491 do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
michael@0 492
michael@0 493 server.stop(run_next_test);
michael@0 494 });
michael@0 495 });
michael@0 496
michael@0 497 /**
michael@0 498 * HTTP PUT with a custom Content-Type header.
michael@0 499 */
michael@0 500 add_test(function test_put_override_content_type() {
michael@0 501 let handler = httpd_handler(200, "OK");
michael@0 502 let server = httpd_setup({"/resource": handler});
michael@0 503
michael@0 504 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 505 request.setHeader("Content-Type", "application/lolcat");
michael@0 506 request.put("O HAI!!1!", function (error) {
michael@0 507 do_check_eq(error, null);
michael@0 508
michael@0 509 do_check_eq(this.status, this.COMPLETED);
michael@0 510 do_check_true(this.response.success);
michael@0 511 do_check_eq(this.response.status, 200);
michael@0 512 do_check_eq(this.response.body, "");
michael@0 513
michael@0 514 do_check_eq(handler.request.method, "PUT");
michael@0 515 do_check_eq(handler.request.body, "O HAI!!1!");
michael@0 516 do_check_eq(handler.request.getHeader("Content-Type"), "application/lolcat");
michael@0 517
michael@0 518 server.stop(run_next_test);
michael@0 519 });
michael@0 520 });
michael@0 521
michael@0 522 /**
michael@0 523 * HTTP POST with a custom Content-Type header.
michael@0 524 */
michael@0 525 add_test(function test_post_override_content_type() {
michael@0 526 let handler = httpd_handler(200, "OK");
michael@0 527 let server = httpd_setup({"/resource": handler});
michael@0 528
michael@0 529 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 530 request.setHeader("Content-Type", "application/lolcat");
michael@0 531 request.post("O HAI!!1!", function (error) {
michael@0 532 do_check_eq(error, null);
michael@0 533
michael@0 534 do_check_eq(this.status, this.COMPLETED);
michael@0 535 do_check_true(this.response.success);
michael@0 536 do_check_eq(this.response.status, 200);
michael@0 537 do_check_eq(this.response.body, "");
michael@0 538
michael@0 539 do_check_eq(handler.request.method, "POST");
michael@0 540 do_check_eq(handler.request.body, "O HAI!!1!");
michael@0 541 do_check_eq(handler.request.getHeader("Content-Type"), "application/lolcat");
michael@0 542
michael@0 543 server.stop(run_next_test);
michael@0 544 });
michael@0 545 });
michael@0 546
michael@0 547 /**
michael@0 548 * No special headers are sent by default on a GET request.
michael@0 549 */
michael@0 550 add_test(function test_get_no_headers() {
michael@0 551 let handler = httpd_handler(200, "OK");
michael@0 552 let server = httpd_setup({"/resource": handler});
michael@0 553
michael@0 554 let ignore_headers = ["host", "user-agent", "accept", "accept-language",
michael@0 555 "accept-encoding", "accept-charset", "keep-alive",
michael@0 556 "connection", "pragma", "cache-control",
michael@0 557 "content-length"];
michael@0 558
michael@0 559 new RESTRequest(server.baseURI + "/resource").get(function (error) {
michael@0 560 do_check_eq(error, null);
michael@0 561
michael@0 562 do_check_eq(this.response.status, 200);
michael@0 563 do_check_eq(this.response.body, "");
michael@0 564
michael@0 565 let server_headers = handler.request.headers;
michael@0 566 while (server_headers.hasMoreElements()) {
michael@0 567 let header = server_headers.getNext().toString();
michael@0 568 if (ignore_headers.indexOf(header) == -1) {
michael@0 569 do_throw("Got unexpected header!");
michael@0 570 }
michael@0 571 }
michael@0 572
michael@0 573 server.stop(run_next_test);
michael@0 574 });
michael@0 575 });
michael@0 576
michael@0 577 /**
michael@0 578 * Test changing the URI after having created the request.
michael@0 579 */
michael@0 580 add_test(function test_changing_uri() {
michael@0 581 let handler = httpd_handler(200, "OK");
michael@0 582 let server = httpd_setup({"/resource": handler});
michael@0 583
michael@0 584 let request = new RESTRequest("http://localhost:1234/the-wrong-resource");
michael@0 585 request.uri = CommonUtils.makeURI(server.baseURI + "/resource");
michael@0 586 request.get(function (error) {
michael@0 587 do_check_eq(error, null);
michael@0 588 do_check_eq(this.response.status, 200);
michael@0 589 server.stop(run_next_test);
michael@0 590 });
michael@0 591 });
michael@0 592
michael@0 593 /**
michael@0 594 * Test setting HTTP request headers.
michael@0 595 */
michael@0 596 add_test(function test_request_setHeader() {
michael@0 597 let handler = httpd_handler(200, "OK");
michael@0 598 let server = httpd_setup({"/resource": handler});
michael@0 599
michael@0 600 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 601
michael@0 602 request.setHeader("X-What-Is-Weave", "awesome");
michael@0 603 request.setHeader("X-WHAT-is-Weave", "more awesomer");
michael@0 604 request.setHeader("Another-Header", "Hello World");
michael@0 605
michael@0 606 request.get(function (error) {
michael@0 607 do_check_eq(error, null);
michael@0 608
michael@0 609 do_check_eq(this.response.status, 200);
michael@0 610 do_check_eq(this.response.body, "");
michael@0 611
michael@0 612 do_check_eq(handler.request.getHeader("X-What-Is-Weave"), "more awesomer");
michael@0 613 do_check_eq(handler.request.getHeader("another-header"), "Hello World");
michael@0 614
michael@0 615 server.stop(run_next_test);
michael@0 616 });
michael@0 617 });
michael@0 618
michael@0 619 /**
michael@0 620 * Test receiving HTTP response headers.
michael@0 621 */
michael@0 622 add_test(function test_response_headers() {
michael@0 623 function handler(request, response) {
michael@0 624 response.setHeader("X-What-Is-Weave", "awesome");
michael@0 625 response.setHeader("Another-Header", "Hello World");
michael@0 626 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 627 }
michael@0 628 let server = httpd_setup({"/resource": handler});
michael@0 629 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 630
michael@0 631 request.get(function (error) {
michael@0 632 do_check_eq(error, null);
michael@0 633
michael@0 634 do_check_eq(this.response.status, 200);
michael@0 635 do_check_eq(this.response.body, "");
michael@0 636
michael@0 637 do_check_eq(this.response.headers["x-what-is-weave"], "awesome");
michael@0 638 do_check_eq(this.response.headers["another-header"], "Hello World");
michael@0 639
michael@0 640 server.stop(run_next_test);
michael@0 641 });
michael@0 642 });
michael@0 643
michael@0 644 /**
michael@0 645 * The onComplete() handler gets called in case of any network errors
michael@0 646 * (e.g. NS_ERROR_CONNECTION_REFUSED).
michael@0 647 */
michael@0 648 add_test(function test_connection_refused() {
michael@0 649 let request = new RESTRequest("http://localhost:1234/resource");
michael@0 650 request.onProgress = function onProgress() {
michael@0 651 do_throw("Shouldn't have called request.onProgress()!");
michael@0 652 };
michael@0 653 request.get(function (error) {
michael@0 654 do_check_eq(error.result, Cr.NS_ERROR_CONNECTION_REFUSED);
michael@0 655 do_check_eq(error.message, "NS_ERROR_CONNECTION_REFUSED");
michael@0 656 do_check_eq(this.status, this.COMPLETED);
michael@0 657 run_next_test();
michael@0 658 });
michael@0 659 do_check_eq(request.status, request.SENT);
michael@0 660 });
michael@0 661
michael@0 662 /**
michael@0 663 * Abort a request that just sent off.
michael@0 664 */
michael@0 665 add_test(function test_abort() {
michael@0 666 function handler() {
michael@0 667 do_throw("Shouldn't have gotten here!");
michael@0 668 }
michael@0 669 let server = httpd_setup({"/resource": handler});
michael@0 670
michael@0 671 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 672
michael@0 673 // Aborting a request that hasn't been sent yet is pointless and will throw.
michael@0 674 do_check_throws(function () {
michael@0 675 request.abort();
michael@0 676 });
michael@0 677
michael@0 678 request.onProgress = request.onComplete = function () {
michael@0 679 do_throw("Shouldn't have gotten here!");
michael@0 680 };
michael@0 681 request.get();
michael@0 682 request.abort();
michael@0 683
michael@0 684 // Aborting an already aborted request is pointless and will throw.
michael@0 685 do_check_throws(function () {
michael@0 686 request.abort();
michael@0 687 });
michael@0 688
michael@0 689 do_check_eq(request.status, request.ABORTED);
michael@0 690 CommonUtils.nextTick(function () {
michael@0 691 server.stop(run_next_test);
michael@0 692 });
michael@0 693 });
michael@0 694
michael@0 695 /**
michael@0 696 * A non-zero 'timeout' property specifies the amount of seconds to wait after
michael@0 697 * channel activity until the request is automatically canceled.
michael@0 698 */
michael@0 699 add_test(function test_timeout() {
michael@0 700 let server = new HttpServer();
michael@0 701 let server_connection;
michael@0 702 server._handler.handleResponse = function(connection) {
michael@0 703 // This is a handler that doesn't do anything, just keeps the connection
michael@0 704 // open, thereby mimicking a timing out connection. We keep a reference to
michael@0 705 // the open connection for later so it can be properly disposed of. That's
michael@0 706 // why you really only want to make one HTTP request to this server ever.
michael@0 707 server_connection = connection;
michael@0 708 };
michael@0 709 server.start();
michael@0 710 let identity = server.identity;
michael@0 711 let uri = identity.primaryScheme + "://" + identity.primaryHost + ":" +
michael@0 712 identity.primaryPort;
michael@0 713
michael@0 714 let request = new RESTRequest(uri + "/resource");
michael@0 715 request.timeout = 0.1; // 100 milliseconds
michael@0 716 request.get(function (error) {
michael@0 717 do_check_eq(error.result, Cr.NS_ERROR_NET_TIMEOUT);
michael@0 718 do_check_eq(this.status, this.ABORTED);
michael@0 719
michael@0 720 // server_connection is undefined on the Android emulator for reasons
michael@0 721 // unknown. Yet, we still get here. If this test is refactored, we should
michael@0 722 // investigate the reason why the above callback is behaving differently.
michael@0 723 if (server_connection) {
michael@0 724 _("Closing connection.");
michael@0 725 server_connection.close();
michael@0 726 }
michael@0 727
michael@0 728 _("Shutting down server.");
michael@0 729 server.stop(run_next_test);
michael@0 730 });
michael@0 731 });
michael@0 732
michael@0 733 /**
michael@0 734 * An exception thrown in 'onProgress' propagates to the 'onComplete' handler.
michael@0 735 */
michael@0 736 add_test(function test_exception_in_onProgress() {
michael@0 737 let handler = httpd_handler(200, "OK", "Foobar");
michael@0 738 let server = httpd_setup({"/resource": handler});
michael@0 739
michael@0 740 let request = new RESTRequest(server.baseURI + "/resource");
michael@0 741 request.onProgress = function onProgress() {
michael@0 742 it.does.not.exist();
michael@0 743 };
michael@0 744 request.get(function onComplete(error) {
michael@0 745 do_check_eq(error, "ReferenceError: it is not defined");
michael@0 746 do_check_eq(this.status, this.ABORTED);
michael@0 747
michael@0 748 server.stop(run_next_test);
michael@0 749 });
michael@0 750 });
michael@0 751
michael@0 752 add_test(function test_new_channel() {
michael@0 753 _("Ensure a redirect to a new channel is handled properly.");
michael@0 754
michael@0 755 function checkUA(metadata) {
michael@0 756 let ua = metadata.getHeader("User-Agent");
michael@0 757 _("User-Agent is " + ua);
michael@0 758 do_check_eq("foo bar", ua);
michael@0 759 }
michael@0 760
michael@0 761 let redirectRequested = false;
michael@0 762 let redirectURL;
michael@0 763 function redirectHandler(metadata, response) {
michael@0 764 checkUA(metadata);
michael@0 765 redirectRequested = true;
michael@0 766
michael@0 767 let body = "Redirecting";
michael@0 768 response.setStatusLine(metadata.httpVersion, 307, "TEMPORARY REDIRECT");
michael@0 769 response.setHeader("Location", redirectURL);
michael@0 770 response.bodyOutputStream.write(body, body.length);
michael@0 771 }
michael@0 772
michael@0 773 let resourceRequested = false;
michael@0 774 function resourceHandler(metadata, response) {
michael@0 775 checkUA(metadata);
michael@0 776 resourceRequested = true;
michael@0 777
michael@0 778 let body = "Test";
michael@0 779 response.setHeader("Content-Type", "text/plain");
michael@0 780 response.bodyOutputStream.write(body, body.length);
michael@0 781 }
michael@0 782
michael@0 783 let server1 = httpd_setup({"/redirect": redirectHandler});
michael@0 784 let server2 = httpd_setup({"/resource": resourceHandler});
michael@0 785 redirectURL = server2.baseURI + "/resource";
michael@0 786
michael@0 787 function advance() {
michael@0 788 server1.stop(function () {
michael@0 789 server2.stop(run_next_test);
michael@0 790 });
michael@0 791 }
michael@0 792
michael@0 793 let request = new RESTRequest(server1.baseURI + "/redirect");
michael@0 794 request.setHeader("User-Agent", "foo bar");
michael@0 795
michael@0 796 // Swizzle in our own fakery, because this redirect is neither
michael@0 797 // internal nor URI-preserving. RESTRequest's policy is to only
michael@0 798 // copy headers under certain circumstances.
michael@0 799 let protoMethod = request.shouldCopyOnRedirect;
michael@0 800 request.shouldCopyOnRedirect = function wrapped(o, n, f) {
michael@0 801 // Check the default policy.
michael@0 802 do_check_false(protoMethod.call(this, o, n, f));
michael@0 803 return true;
michael@0 804 };
michael@0 805
michael@0 806 request.get(function onComplete(error) {
michael@0 807 let response = this.response;
michael@0 808
michael@0 809 do_check_eq(200, response.status);
michael@0 810 do_check_eq("Test", response.body);
michael@0 811 do_check_true(redirectRequested);
michael@0 812 do_check_true(resourceRequested);
michael@0 813
michael@0 814 advance();
michael@0 815 });
michael@0 816 });
michael@0 817
michael@0 818 add_test(function test_not_sending_cookie() {
michael@0 819 function handler(metadata, response) {
michael@0 820 let body = "COOKIE!";
michael@0 821 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 822 response.bodyOutputStream.write(body, body.length);
michael@0 823 do_check_false(metadata.hasHeader("Cookie"));
michael@0 824 }
michael@0 825 let server = httpd_setup({"/test": handler});
michael@0 826
michael@0 827 let cookieSer = Cc["@mozilla.org/cookieService;1"]
michael@0 828 .getService(Ci.nsICookieService);
michael@0 829 let uri = CommonUtils.makeURI(server.baseURI);
michael@0 830 cookieSer.setCookieString(uri, null, "test=test; path=/;", null);
michael@0 831
michael@0 832 let res = new RESTRequest(server.baseURI + "/test");
michael@0 833 res.get(function (error) {
michael@0 834 do_check_null(error);
michael@0 835 do_check_true(this.response.success);
michael@0 836 do_check_eq("COOKIE!", this.response.body);
michael@0 837 server.stop(run_next_test);
michael@0 838 });
michael@0 839 });
michael@0 840

mercurial