services/sync/tests/unit/test_resource_async.js

Wed, 31 Dec 2014 07:22:50 +0100

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

Correct previous dual key logic pending first delivery installment.

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 Cu.import("resource://gre/modules/Log.jsm");
michael@0 5 Cu.import("resource://services-common/observers.js");
michael@0 6 Cu.import("resource://services-sync/identity.js");
michael@0 7 Cu.import("resource://services-sync/resource.js");
michael@0 8 Cu.import("resource://services-sync/util.js");
michael@0 9
michael@0 10 let logger;
michael@0 11
michael@0 12 let fetched = false;
michael@0 13 function server_open(metadata, response) {
michael@0 14 let body;
michael@0 15 if (metadata.method == "GET") {
michael@0 16 fetched = true;
michael@0 17 body = "This path exists";
michael@0 18 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 19 } else {
michael@0 20 body = "Wrong request method";
michael@0 21 response.setStatusLine(metadata.httpVersion, 405, "Method Not Allowed");
michael@0 22 }
michael@0 23 response.bodyOutputStream.write(body, body.length);
michael@0 24 }
michael@0 25
michael@0 26 function server_protected(metadata, response) {
michael@0 27 let body;
michael@0 28
michael@0 29 if (basic_auth_matches(metadata, "guest", "guest")) {
michael@0 30 body = "This path exists and is protected";
michael@0 31 response.setStatusLine(metadata.httpVersion, 200, "OK, authorized");
michael@0 32 response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
michael@0 33 } else {
michael@0 34 body = "This path exists and is protected - failed";
michael@0 35 response.setStatusLine(metadata.httpVersion, 401, "Unauthorized");
michael@0 36 response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
michael@0 37 }
michael@0 38
michael@0 39 response.bodyOutputStream.write(body, body.length);
michael@0 40 }
michael@0 41
michael@0 42 function server_404(metadata, response) {
michael@0 43 let body = "File not found";
michael@0 44 response.setStatusLine(metadata.httpVersion, 404, "Not Found");
michael@0 45 response.bodyOutputStream.write(body, body.length);
michael@0 46 }
michael@0 47
michael@0 48 let pacFetched = false;
michael@0 49 function server_pac(metadata, response) {
michael@0 50 _("Invoked PAC handler.");
michael@0 51 pacFetched = true;
michael@0 52 let body = 'function FindProxyForURL(url, host) { return "DIRECT"; }';
michael@0 53 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 54 response.setHeader("Content-Type", "application/x-ns-proxy-autoconfig", false);
michael@0 55 response.bodyOutputStream.write(body, body.length);
michael@0 56 }
michael@0 57
michael@0 58 let sample_data = {
michael@0 59 some: "sample_data",
michael@0 60 injson: "format",
michael@0 61 number: 42
michael@0 62 };
michael@0 63
michael@0 64 function server_upload(metadata, response) {
michael@0 65 let body;
michael@0 66
michael@0 67 let input = readBytesFromInputStream(metadata.bodyInputStream);
michael@0 68 if (input == JSON.stringify(sample_data)) {
michael@0 69 body = "Valid data upload via " + metadata.method;
michael@0 70 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 71 } else {
michael@0 72 body = "Invalid data upload via " + metadata.method + ': ' + input;
michael@0 73 response.setStatusLine(metadata.httpVersion, 500, "Internal Server Error");
michael@0 74 }
michael@0 75
michael@0 76 response.bodyOutputStream.write(body, body.length);
michael@0 77 }
michael@0 78
michael@0 79 function server_delete(metadata, response) {
michael@0 80 let body;
michael@0 81 if (metadata.method == "DELETE") {
michael@0 82 body = "This resource has been deleted";
michael@0 83 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 84 } else {
michael@0 85 body = "Wrong request method";
michael@0 86 response.setStatusLine(metadata.httpVersion, 405, "Method Not Allowed");
michael@0 87 }
michael@0 88 response.bodyOutputStream.write(body, body.length);
michael@0 89 }
michael@0 90
michael@0 91 function server_json(metadata, response) {
michael@0 92 let body = JSON.stringify(sample_data);
michael@0 93 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 94 response.bodyOutputStream.write(body, body.length);
michael@0 95 }
michael@0 96
michael@0 97 const TIMESTAMP = 1274380461;
michael@0 98
michael@0 99 function server_timestamp(metadata, response) {
michael@0 100 let body = "Thank you for your request";
michael@0 101 response.setHeader("X-Weave-Timestamp", ''+TIMESTAMP, false);
michael@0 102 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 103 response.bodyOutputStream.write(body, body.length);
michael@0 104 }
michael@0 105
michael@0 106 function server_backoff(metadata, response) {
michael@0 107 let body = "Hey, back off!";
michael@0 108 response.setHeader("X-Weave-Backoff", '600', false);
michael@0 109 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 110 response.bodyOutputStream.write(body, body.length);
michael@0 111 }
michael@0 112
michael@0 113 function server_quota_notice(request, response) {
michael@0 114 let body = "You're approaching quota.";
michael@0 115 response.setHeader("X-Weave-Quota-Remaining", '1048576', false);
michael@0 116 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 117 response.bodyOutputStream.write(body, body.length);
michael@0 118 }
michael@0 119
michael@0 120 function server_quota_error(request, response) {
michael@0 121 let body = "14";
michael@0 122 response.setHeader("X-Weave-Quota-Remaining", '-1024', false);
michael@0 123 response.setStatusLine(request.httpVersion, 400, "OK");
michael@0 124 response.bodyOutputStream.write(body, body.length);
michael@0 125 }
michael@0 126
michael@0 127 function server_headers(metadata, response) {
michael@0 128 let ignore_headers = ["host", "user-agent", "accept", "accept-language",
michael@0 129 "accept-encoding", "accept-charset", "keep-alive",
michael@0 130 "connection", "pragma", "cache-control",
michael@0 131 "content-length"];
michael@0 132 let headers = metadata.headers;
michael@0 133 let header_names = [];
michael@0 134 while (headers.hasMoreElements()) {
michael@0 135 let header = headers.getNext().toString();
michael@0 136 if (ignore_headers.indexOf(header) == -1) {
michael@0 137 header_names.push(header);
michael@0 138 }
michael@0 139 }
michael@0 140 header_names = header_names.sort();
michael@0 141
michael@0 142 headers = {};
michael@0 143 for each (let header in header_names) {
michael@0 144 headers[header] = metadata.getHeader(header);
michael@0 145 }
michael@0 146 let body = JSON.stringify(headers);
michael@0 147 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 148 response.bodyOutputStream.write(body, body.length);
michael@0 149 }
michael@0 150
michael@0 151 let quotaValue;
michael@0 152 Observers.add("weave:service:quota:remaining",
michael@0 153 function (subject) { quotaValue = subject; });
michael@0 154
michael@0 155 function run_test() {
michael@0 156 logger = Log.repository.getLogger('Test');
michael@0 157 Log.repository.rootLogger.addAppender(new Log.DumpAppender());
michael@0 158
michael@0 159 Svc.Prefs.set("network.numRetries", 1); // speed up test
michael@0 160 run_next_test();
michael@0 161 }
michael@0 162
michael@0 163 // This apparently has to come first in order for our PAC URL to be hit.
michael@0 164 // Don't put any other HTTP requests earlier in the file!
michael@0 165 add_test(function test_proxy_auth_redirect() {
michael@0 166 _("Ensure that a proxy auth redirect (which switches out our channel) " +
michael@0 167 "doesn't break AsyncResource.");
michael@0 168 let server = httpd_setup({
michael@0 169 "/open": server_open,
michael@0 170 "/pac2": server_pac
michael@0 171 });
michael@0 172
michael@0 173 PACSystemSettings.PACURI = server.baseURI + "/pac2";
michael@0 174 installFakePAC();
michael@0 175 let res = new AsyncResource(server.baseURI + "/open");
michael@0 176 res.get(function (error, result) {
michael@0 177 do_check_true(!error);
michael@0 178 do_check_true(pacFetched);
michael@0 179 do_check_true(fetched);
michael@0 180 do_check_eq("This path exists", result);
michael@0 181 pacFetched = fetched = false;
michael@0 182 uninstallFakePAC();
michael@0 183 server.stop(run_next_test);
michael@0 184 });
michael@0 185 });
michael@0 186
michael@0 187 add_test(function test_new_channel() {
michael@0 188 _("Ensure a redirect to a new channel is handled properly.");
michael@0 189
michael@0 190 let resourceRequested = false;
michael@0 191 function resourceHandler(metadata, response) {
michael@0 192 resourceRequested = true;
michael@0 193
michael@0 194 let body = "Test";
michael@0 195 response.setHeader("Content-Type", "text/plain");
michael@0 196 response.bodyOutputStream.write(body, body.length);
michael@0 197 }
michael@0 198
michael@0 199 let locationURL;
michael@0 200 function redirectHandler(metadata, response) {
michael@0 201 let body = "Redirecting";
michael@0 202 response.setStatusLine(metadata.httpVersion, 307, "TEMPORARY REDIRECT");
michael@0 203 response.setHeader("Location", locationURL);
michael@0 204 response.bodyOutputStream.write(body, body.length);
michael@0 205 }
michael@0 206
michael@0 207 let server = httpd_setup({"/resource": resourceHandler,
michael@0 208 "/redirect": redirectHandler});
michael@0 209 locationURL = server.baseURI + "/resource";
michael@0 210
michael@0 211 let request = new AsyncResource(server.baseURI + "/redirect");
michael@0 212 request.get(function onRequest(error, content) {
michael@0 213 do_check_null(error);
michael@0 214 do_check_true(resourceRequested);
michael@0 215 do_check_eq(200, content.status);
michael@0 216 do_check_true("content-type" in content.headers);
michael@0 217 do_check_eq("text/plain", content.headers["content-type"]);
michael@0 218
michael@0 219 server.stop(run_next_test);
michael@0 220 });
michael@0 221 });
michael@0 222
michael@0 223
michael@0 224 let server;
michael@0 225
michael@0 226 add_test(function setup() {
michael@0 227 server = httpd_setup({
michael@0 228 "/open": server_open,
michael@0 229 "/protected": server_protected,
michael@0 230 "/404": server_404,
michael@0 231 "/upload": server_upload,
michael@0 232 "/delete": server_delete,
michael@0 233 "/json": server_json,
michael@0 234 "/timestamp": server_timestamp,
michael@0 235 "/headers": server_headers,
michael@0 236 "/backoff": server_backoff,
michael@0 237 "/pac2": server_pac,
michael@0 238 "/quota-notice": server_quota_notice,
michael@0 239 "/quota-error": server_quota_error
michael@0 240 });
michael@0 241
michael@0 242 run_next_test();
michael@0 243 });
michael@0 244
michael@0 245 add_test(function test_members() {
michael@0 246 _("Resource object members");
michael@0 247 let uri = server.baseURI + "/open";
michael@0 248 let res = new AsyncResource(uri);
michael@0 249 do_check_true(res.uri instanceof Ci.nsIURI);
michael@0 250 do_check_eq(res.uri.spec, uri);
michael@0 251 do_check_eq(res.spec, uri);
michael@0 252 do_check_eq(typeof res.headers, "object");
michael@0 253 do_check_eq(typeof res.authenticator, "object");
michael@0 254 // Initially res.data is null since we haven't performed a GET or
michael@0 255 // PUT/POST request yet.
michael@0 256 do_check_eq(res.data, null);
michael@0 257
michael@0 258 run_next_test();
michael@0 259 });
michael@0 260
michael@0 261 add_test(function test_get() {
michael@0 262 _("GET a non-password-protected resource");
michael@0 263 let res = new AsyncResource(server.baseURI + "/open");
michael@0 264 res.get(function (error, content) {
michael@0 265 do_check_eq(error, null);
michael@0 266 do_check_eq(content, "This path exists");
michael@0 267 do_check_eq(content.status, 200);
michael@0 268 do_check_true(content.success);
michael@0 269 // res.data has been updated with the result from the request
michael@0 270 do_check_eq(res.data, content);
michael@0 271
michael@0 272 // Observe logging messages.
michael@0 273 let logger = res._log;
michael@0 274 let dbg = logger.debug;
michael@0 275 let debugMessages = [];
michael@0 276 logger.debug = function (msg) {
michael@0 277 debugMessages.push(msg);
michael@0 278 dbg.call(this, msg);
michael@0 279 }
michael@0 280
michael@0 281 // Since we didn't receive proper JSON data, accessing content.obj
michael@0 282 // will result in a SyntaxError from JSON.parse
michael@0 283 let didThrow = false;
michael@0 284 try {
michael@0 285 content.obj;
michael@0 286 } catch (ex) {
michael@0 287 didThrow = true;
michael@0 288 }
michael@0 289 do_check_true(didThrow);
michael@0 290 do_check_eq(debugMessages.length, 1);
michael@0 291 do_check_eq(debugMessages[0],
michael@0 292 "Parse fail: Response body starts: \"\"This path exists\"\".");
michael@0 293 logger.debug = dbg;
michael@0 294
michael@0 295 run_next_test();
michael@0 296 });
michael@0 297 });
michael@0 298
michael@0 299 add_test(function test_basicauth() {
michael@0 300 _("Test that the BasicAuthenticator doesn't screw up header case.");
michael@0 301 let res1 = new AsyncResource(server.baseURI + "/foo");
michael@0 302 res1.setHeader("Authorization", "Basic foobar");
michael@0 303 do_check_eq(res1._headers["authorization"], "Basic foobar");
michael@0 304 do_check_eq(res1.headers["authorization"], "Basic foobar");
michael@0 305
michael@0 306 run_next_test();
michael@0 307 });
michael@0 308
michael@0 309 add_test(function test_get_protected_fail() {
michael@0 310 _("GET a password protected resource (test that it'll fail w/o pass, no throw)");
michael@0 311 let res2 = new AsyncResource(server.baseURI + "/protected");
michael@0 312 res2.get(function (error, content) {
michael@0 313 do_check_eq(error, null);
michael@0 314 do_check_eq(content, "This path exists and is protected - failed");
michael@0 315 do_check_eq(content.status, 401);
michael@0 316 do_check_false(content.success);
michael@0 317 run_next_test();
michael@0 318 });
michael@0 319 });
michael@0 320
michael@0 321 add_test(function test_get_protected_success() {
michael@0 322 _("GET a password protected resource");
michael@0 323 let identity = new IdentityManager();
michael@0 324 let auth = identity.getBasicResourceAuthenticator("guest", "guest");
michael@0 325 let res3 = new AsyncResource(server.baseURI + "/protected");
michael@0 326 res3.authenticator = auth;
michael@0 327 do_check_eq(res3.authenticator, auth);
michael@0 328 res3.get(function (error, content) {
michael@0 329 do_check_eq(error, null);
michael@0 330 do_check_eq(content, "This path exists and is protected");
michael@0 331 do_check_eq(content.status, 200);
michael@0 332 do_check_true(content.success);
michael@0 333 run_next_test();
michael@0 334 });
michael@0 335 });
michael@0 336
michael@0 337 add_test(function test_get_404() {
michael@0 338 _("GET a non-existent resource (test that it'll fail, but not throw)");
michael@0 339 let res4 = new AsyncResource(server.baseURI + "/404");
michael@0 340 res4.get(function (error, content) {
michael@0 341 do_check_eq(error, null);
michael@0 342 do_check_eq(content, "File not found");
michael@0 343 do_check_eq(content.status, 404);
michael@0 344 do_check_false(content.success);
michael@0 345
michael@0 346 // Check some headers of the 404 response
michael@0 347 do_check_eq(content.headers.connection, "close");
michael@0 348 do_check_eq(content.headers.server, "httpd.js");
michael@0 349 do_check_eq(content.headers["content-length"], 14);
michael@0 350
michael@0 351 run_next_test();
michael@0 352 });
michael@0 353 });
michael@0 354
michael@0 355 add_test(function test_put_string() {
michael@0 356 _("PUT to a resource (string)");
michael@0 357 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 358 res_upload.put(JSON.stringify(sample_data), function(error, content) {
michael@0 359 do_check_eq(error, null);
michael@0 360 do_check_eq(content, "Valid data upload via PUT");
michael@0 361 do_check_eq(content.status, 200);
michael@0 362 do_check_eq(res_upload.data, content);
michael@0 363 run_next_test();
michael@0 364 });
michael@0 365 });
michael@0 366
michael@0 367 add_test(function test_put_object() {
michael@0 368 _("PUT to a resource (object)");
michael@0 369 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 370 res_upload.put(sample_data, function (error, content) {
michael@0 371 do_check_eq(error, null);
michael@0 372 do_check_eq(content, "Valid data upload via PUT");
michael@0 373 do_check_eq(content.status, 200);
michael@0 374 do_check_eq(res_upload.data, content);
michael@0 375 run_next_test();
michael@0 376 });
michael@0 377 });
michael@0 378
michael@0 379 add_test(function test_put_data_string() {
michael@0 380 _("PUT without data arg (uses resource.data) (string)");
michael@0 381 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 382 res_upload.data = JSON.stringify(sample_data);
michael@0 383 res_upload.put(function (error, content) {
michael@0 384 do_check_eq(error, null);
michael@0 385 do_check_eq(content, "Valid data upload via PUT");
michael@0 386 do_check_eq(content.status, 200);
michael@0 387 do_check_eq(res_upload.data, content);
michael@0 388 run_next_test();
michael@0 389 });
michael@0 390 });
michael@0 391
michael@0 392 add_test(function test_put_data_object() {
michael@0 393 _("PUT without data arg (uses resource.data) (object)");
michael@0 394 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 395 res_upload.data = sample_data;
michael@0 396 res_upload.put(function (error, content) {
michael@0 397 do_check_eq(error, null);
michael@0 398 do_check_eq(content, "Valid data upload via PUT");
michael@0 399 do_check_eq(content.status, 200);
michael@0 400 do_check_eq(res_upload.data, content);
michael@0 401 run_next_test();
michael@0 402 });
michael@0 403 });
michael@0 404
michael@0 405 add_test(function test_post_string() {
michael@0 406 _("POST to a resource (string)");
michael@0 407 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 408 res_upload.post(JSON.stringify(sample_data), function (error, content) {
michael@0 409 do_check_eq(error, null);
michael@0 410 do_check_eq(content, "Valid data upload via POST");
michael@0 411 do_check_eq(content.status, 200);
michael@0 412 do_check_eq(res_upload.data, content);
michael@0 413 run_next_test();
michael@0 414 });
michael@0 415 });
michael@0 416
michael@0 417 add_test(function test_post_object() {
michael@0 418 _("POST to a resource (object)");
michael@0 419 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 420 res_upload.post(sample_data, function (error, content) {
michael@0 421 do_check_eq(error, null);
michael@0 422 do_check_eq(content, "Valid data upload via POST");
michael@0 423 do_check_eq(content.status, 200);
michael@0 424 do_check_eq(res_upload.data, content);
michael@0 425 run_next_test();
michael@0 426 });
michael@0 427 });
michael@0 428
michael@0 429 add_test(function test_post_data_string() {
michael@0 430 _("POST without data arg (uses resource.data) (string)");
michael@0 431 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 432 res_upload.data = JSON.stringify(sample_data);
michael@0 433 res_upload.post(function (error, content) {
michael@0 434 do_check_eq(error, null);
michael@0 435 do_check_eq(content, "Valid data upload via POST");
michael@0 436 do_check_eq(content.status, 200);
michael@0 437 do_check_eq(res_upload.data, content);
michael@0 438 run_next_test();
michael@0 439 });
michael@0 440 });
michael@0 441
michael@0 442 add_test(function test_post_data_object() {
michael@0 443 _("POST without data arg (uses resource.data) (object)");
michael@0 444 let res_upload = new AsyncResource(server.baseURI + "/upload");
michael@0 445 res_upload.data = sample_data;
michael@0 446 res_upload.post(function (error, content) {
michael@0 447 do_check_eq(error, null);
michael@0 448 do_check_eq(content, "Valid data upload via POST");
michael@0 449 do_check_eq(content.status, 200);
michael@0 450 do_check_eq(res_upload.data, content);
michael@0 451 run_next_test();
michael@0 452 });
michael@0 453 });
michael@0 454
michael@0 455 add_test(function test_delete() {
michael@0 456 _("DELETE a resource");
michael@0 457 let res6 = new AsyncResource(server.baseURI + "/delete");
michael@0 458 res6.delete(function (error, content) {
michael@0 459 do_check_eq(error, null);
michael@0 460 do_check_eq(content, "This resource has been deleted");
michael@0 461 do_check_eq(content.status, 200);
michael@0 462 run_next_test();
michael@0 463 });
michael@0 464 });
michael@0 465
michael@0 466 add_test(function test_json_body() {
michael@0 467 _("JSON conversion of response body");
michael@0 468 let res7 = new AsyncResource(server.baseURI + "/json");
michael@0 469 res7.get(function (error, content) {
michael@0 470 do_check_eq(error, null);
michael@0 471 do_check_eq(content, JSON.stringify(sample_data));
michael@0 472 do_check_eq(content.status, 200);
michael@0 473 do_check_eq(JSON.stringify(content.obj), JSON.stringify(sample_data));
michael@0 474 run_next_test();
michael@0 475 });
michael@0 476 });
michael@0 477
michael@0 478 add_test(function test_weave_timestamp() {
michael@0 479 _("X-Weave-Timestamp header updates AsyncResource.serverTime");
michael@0 480 // Before having received any response containing the
michael@0 481 // X-Weave-Timestamp header, AsyncResource.serverTime is null.
michael@0 482 do_check_eq(AsyncResource.serverTime, null);
michael@0 483 let res8 = new AsyncResource(server.baseURI + "/timestamp");
michael@0 484 res8.get(function (error, content) {
michael@0 485 do_check_eq(error, null);
michael@0 486 do_check_eq(AsyncResource.serverTime, TIMESTAMP);
michael@0 487 run_next_test();
michael@0 488 });
michael@0 489 });
michael@0 490
michael@0 491 add_test(function test_get_no_headers() {
michael@0 492 _("GET: no special request headers");
michael@0 493 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 494 res_headers.get(function (error, content) {
michael@0 495 do_check_eq(error, null);
michael@0 496 do_check_eq(content, '{}');
michael@0 497 run_next_test();
michael@0 498 });
michael@0 499 });
michael@0 500
michael@0 501 add_test(function test_put_default_content_type() {
michael@0 502 _("PUT: Content-Type defaults to text/plain");
michael@0 503 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 504 res_headers.put('data', function (error, content) {
michael@0 505 do_check_eq(error, null);
michael@0 506 do_check_eq(content, JSON.stringify({"content-type": "text/plain"}));
michael@0 507 run_next_test();
michael@0 508 });
michael@0 509 });
michael@0 510
michael@0 511 add_test(function test_post_default_content_type() {
michael@0 512 _("POST: Content-Type defaults to text/plain");
michael@0 513 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 514 res_headers.post('data', function (error, content) {
michael@0 515 do_check_eq(error, null);
michael@0 516 do_check_eq(content, JSON.stringify({"content-type": "text/plain"}));
michael@0 517 run_next_test();
michael@0 518 });
michael@0 519 });
michael@0 520
michael@0 521 add_test(function test_setHeader() {
michael@0 522 _("setHeader(): setting simple header");
michael@0 523 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 524 res_headers.setHeader('X-What-Is-Weave', 'awesome');
michael@0 525 do_check_eq(res_headers.headers['x-what-is-weave'], 'awesome');
michael@0 526 res_headers.get(function (error, content) {
michael@0 527 do_check_eq(error, null);
michael@0 528 do_check_eq(content, JSON.stringify({"x-what-is-weave": "awesome"}));
michael@0 529 run_next_test();
michael@0 530 });
michael@0 531 });
michael@0 532
michael@0 533 add_test(function test_setHeader_overwrite() {
michael@0 534 _("setHeader(): setting multiple headers, overwriting existing header");
michael@0 535 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 536 res_headers.setHeader('X-WHAT-is-Weave', 'more awesomer');
michael@0 537 res_headers.setHeader('X-Another-Header', 'hello world');
michael@0 538 do_check_eq(res_headers.headers['x-what-is-weave'], 'more awesomer');
michael@0 539 do_check_eq(res_headers.headers['x-another-header'], 'hello world');
michael@0 540 res_headers.get(function (error, content) {
michael@0 541 do_check_eq(error, null);
michael@0 542 do_check_eq(content, JSON.stringify({"x-another-header": "hello world",
michael@0 543 "x-what-is-weave": "more awesomer"}));
michael@0 544
michael@0 545 run_next_test();
michael@0 546 });
michael@0 547 });
michael@0 548
michael@0 549 add_test(function test_headers_object() {
michael@0 550 _("Setting headers object");
michael@0 551 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 552 res_headers.headers = {};
michael@0 553 res_headers.get(function (error, content) {
michael@0 554 do_check_eq(error, null);
michael@0 555 do_check_eq(content, "{}");
michael@0 556 run_next_test();
michael@0 557 });
michael@0 558 });
michael@0 559
michael@0 560 add_test(function test_put_override_content_type() {
michael@0 561 _("PUT: override default Content-Type");
michael@0 562 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 563 res_headers.setHeader('Content-Type', 'application/foobar');
michael@0 564 do_check_eq(res_headers.headers['content-type'], 'application/foobar');
michael@0 565 res_headers.put('data', function (error, content) {
michael@0 566 do_check_eq(error, null);
michael@0 567 do_check_eq(content, JSON.stringify({"content-type": "application/foobar"}));
michael@0 568 run_next_test();
michael@0 569 });
michael@0 570 });
michael@0 571
michael@0 572 add_test(function test_post_override_content_type() {
michael@0 573 _("POST: override default Content-Type");
michael@0 574 let res_headers = new AsyncResource(server.baseURI + "/headers");
michael@0 575 res_headers.setHeader('Content-Type', 'application/foobar');
michael@0 576 res_headers.post('data', function (error, content) {
michael@0 577 do_check_eq(error, null);
michael@0 578 do_check_eq(content, JSON.stringify({"content-type": "application/foobar"}));
michael@0 579 run_next_test();
michael@0 580 });
michael@0 581 });
michael@0 582
michael@0 583 add_test(function test_weave_backoff() {
michael@0 584 _("X-Weave-Backoff header notifies observer");
michael@0 585 let backoffInterval;
michael@0 586 function onBackoff(subject, data) {
michael@0 587 backoffInterval = subject;
michael@0 588 }
michael@0 589 Observers.add("weave:service:backoff:interval", onBackoff);
michael@0 590
michael@0 591 let res10 = new AsyncResource(server.baseURI + "/backoff");
michael@0 592 res10.get(function (error, content) {
michael@0 593 do_check_eq(error, null);
michael@0 594 do_check_eq(backoffInterval, 600);
michael@0 595 run_next_test();
michael@0 596 });
michael@0 597 });
michael@0 598
michael@0 599 add_test(function test_quota_error() {
michael@0 600 _("X-Weave-Quota-Remaining header notifies observer on successful requests.");
michael@0 601 let res10 = new AsyncResource(server.baseURI + "/quota-error");
michael@0 602 res10.get(function (error, content) {
michael@0 603 do_check_eq(error, null);
michael@0 604 do_check_eq(content.status, 400);
michael@0 605 do_check_eq(quotaValue, undefined); // HTTP 400, so no observer notification.
michael@0 606 run_next_test();
michael@0 607 });
michael@0 608 });
michael@0 609
michael@0 610 add_test(function test_quota_notice() {
michael@0 611 let res10 = new AsyncResource(server.baseURI + "/quota-notice");
michael@0 612 res10.get(function (error, content) {
michael@0 613 do_check_eq(error, null);
michael@0 614 do_check_eq(content.status, 200);
michael@0 615 do_check_eq(quotaValue, 1048576);
michael@0 616 run_next_test();
michael@0 617 });
michael@0 618 });
michael@0 619
michael@0 620 add_test(function test_preserve_exceptions() {
michael@0 621 _("Error handling in ChannelListener etc. preserves exception information");
michael@0 622 let res11 = new AsyncResource("http://localhost:12345/does/not/exist");
michael@0 623 res11.get(function (error, content) {
michael@0 624 do_check_neq(error, null);
michael@0 625 do_check_eq(error.result, Cr.NS_ERROR_CONNECTION_REFUSED);
michael@0 626 do_check_eq(error.message, "NS_ERROR_CONNECTION_REFUSED");
michael@0 627 run_next_test();
michael@0 628 });
michael@0 629 });
michael@0 630
michael@0 631 add_test(function test_xpc_exception_handling() {
michael@0 632 _("Exception handling inside fetches.");
michael@0 633 let res14 = new AsyncResource(server.baseURI + "/json");
michael@0 634 res14._onProgress = function(rec) {
michael@0 635 // Provoke an XPC exception without a Javascript wrapper.
michael@0 636 Services.io.newURI("::::::::", null, null);
michael@0 637 };
michael@0 638 let warnings = [];
michael@0 639 res14._log.warn = function(msg) { warnings.push(msg); };
michael@0 640
michael@0 641 res14.get(function (error, content) {
michael@0 642 do_check_eq(error.result, Cr.NS_ERROR_MALFORMED_URI);
michael@0 643 do_check_eq(error.message, "NS_ERROR_MALFORMED_URI");
michael@0 644 do_check_eq(content, null);
michael@0 645 do_check_eq(warnings.pop(),
michael@0 646 "Got exception calling onProgress handler during fetch of " +
michael@0 647 server.baseURI + "/json");
michael@0 648
michael@0 649 run_next_test();
michael@0 650 });
michael@0 651 });
michael@0 652
michael@0 653 add_test(function test_js_exception_handling() {
michael@0 654 _("JS exception handling inside fetches.");
michael@0 655 let res15 = new AsyncResource(server.baseURI + "/json");
michael@0 656 res15._onProgress = function(rec) {
michael@0 657 throw "BOO!";
michael@0 658 };
michael@0 659 let warnings = [];
michael@0 660 res15._log.warn = function(msg) { warnings.push(msg); };
michael@0 661
michael@0 662 res15.get(function (error, content) {
michael@0 663 do_check_eq(error.result, Cr.NS_ERROR_XPC_JS_THREW_STRING);
michael@0 664 do_check_eq(error.message, "NS_ERROR_XPC_JS_THREW_STRING");
michael@0 665 do_check_eq(content, null);
michael@0 666 do_check_eq(warnings.pop(),
michael@0 667 "Got exception calling onProgress handler during fetch of " +
michael@0 668 server.baseURI + "/json");
michael@0 669
michael@0 670 run_next_test();
michael@0 671 });
michael@0 672 });
michael@0 673
michael@0 674 add_test(function test_timeout() {
michael@0 675 _("Ensure channel timeouts are thrown appropriately.");
michael@0 676 let res19 = new AsyncResource(server.baseURI + "/json");
michael@0 677 res19.ABORT_TIMEOUT = 0;
michael@0 678 res19.get(function (error, content) {
michael@0 679 do_check_eq(error.result, Cr.NS_ERROR_NET_TIMEOUT);
michael@0 680 run_next_test();
michael@0 681 });
michael@0 682 });
michael@0 683
michael@0 684 add_test(function test_uri_construction() {
michael@0 685 _("Testing URI construction.");
michael@0 686 let args = [];
michael@0 687 args.push("newer=" + 1234);
michael@0 688 args.push("limit=" + 1234);
michael@0 689 args.push("sort=" + 1234);
michael@0 690
michael@0 691 let query = "?" + args.join("&");
michael@0 692
michael@0 693 let uri1 = Utils.makeURI("http://foo/" + query)
michael@0 694 .QueryInterface(Ci.nsIURL);
michael@0 695 let uri2 = Utils.makeURI("http://foo/")
michael@0 696 .QueryInterface(Ci.nsIURL);
michael@0 697 uri2.query = query;
michael@0 698 do_check_eq(uri1.query, uri2.query);
michael@0 699
michael@0 700 run_next_test();
michael@0 701 });
michael@0 702
michael@0 703 add_test(function test_not_sending_cookie() {
michael@0 704 function handler(metadata, response) {
michael@0 705 let body = "COOKIE!";
michael@0 706 response.setStatusLine(metadata.httpVersion, 200, "OK");
michael@0 707 response.bodyOutputStream.write(body, body.length);
michael@0 708 do_check_false(metadata.hasHeader("Cookie"));
michael@0 709 }
michael@0 710 let cookieSer = Cc["@mozilla.org/cookieService;1"]
michael@0 711 .getService(Ci.nsICookieService);
michael@0 712 let uri = CommonUtils.makeURI(server.baseURI);
michael@0 713 cookieSer.setCookieString(uri, null, "test=test; path=/;", null);
michael@0 714
michael@0 715 let res = new AsyncResource(server.baseURI + "/test");
michael@0 716 res.get(function (error) {
michael@0 717 do_check_null(error);
michael@0 718 do_check_true(this.response.success);
michael@0 719 do_check_eq("COOKIE!", this.response.body);
michael@0 720 server.stop(run_next_test);
michael@0 721 });
michael@0 722 });
michael@0 723
michael@0 724 /**
michael@0 725 * End of tests that rely on a single HTTP server.
michael@0 726 * All tests after this point must begin and end their own.
michael@0 727 */
michael@0 728 add_test(function eliminate_server() {
michael@0 729 server.stop(run_next_test);
michael@0 730 });

mercurial