services/common/tests/unit/test_tokenserverclient.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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://services-common/async.js");
michael@0 5 Cu.import("resource://services-common/tokenserverclient.js");
michael@0 6
michael@0 7 function run_test() {
michael@0 8 initTestLogging("Trace");
michael@0 9
michael@0 10 run_next_test();
michael@0 11 }
michael@0 12
michael@0 13 add_test(function test_working_bid_exchange() {
michael@0 14 _("Ensure that working BrowserID token exchange works as expected.");
michael@0 15
michael@0 16 let service = "http://example.com/foo";
michael@0 17 let duration = 300;
michael@0 18
michael@0 19 let server = httpd_setup({
michael@0 20 "/1.0/foo/1.0": function(request, response) {
michael@0 21 do_check_true(request.hasHeader("accept"));
michael@0 22 do_check_false(request.hasHeader("x-conditions-accepted"));
michael@0 23 do_check_eq("application/json", request.getHeader("accept"));
michael@0 24
michael@0 25 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 26 response.setHeader("Content-Type", "application/json");
michael@0 27
michael@0 28 let body = JSON.stringify({
michael@0 29 id: "id",
michael@0 30 key: "key",
michael@0 31 api_endpoint: service,
michael@0 32 uid: "uid",
michael@0 33 duration: duration,
michael@0 34 });
michael@0 35 response.bodyOutputStream.write(body, body.length);
michael@0 36 }
michael@0 37 });
michael@0 38
michael@0 39 let client = new TokenServerClient();
michael@0 40 let cb = Async.makeSpinningCallback();
michael@0 41 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 42 client.getTokenFromBrowserIDAssertion(url, "assertion", cb);
michael@0 43 let result = cb.wait();
michael@0 44 do_check_eq("object", typeof(result));
michael@0 45 do_check_attribute_count(result, 5);
michael@0 46 do_check_eq(service, result.endpoint);
michael@0 47 do_check_eq("id", result.id);
michael@0 48 do_check_eq("key", result.key);
michael@0 49 do_check_eq("uid", result.uid);
michael@0 50 do_check_eq(duration, result.duration);
michael@0 51 server.stop(run_next_test);
michael@0 52 });
michael@0 53
michael@0 54 add_test(function test_invalid_arguments() {
michael@0 55 _("Ensure invalid arguments to APIs are rejected.");
michael@0 56
michael@0 57 let args = [
michael@0 58 [null, "assertion", function() {}],
michael@0 59 ["http://example.com/", null, function() {}],
michael@0 60 ["http://example.com/", "assertion", null]
michael@0 61 ];
michael@0 62
michael@0 63 for each (let arg in args) {
michael@0 64 try {
michael@0 65 let client = new TokenServerClient();
michael@0 66 client.getTokenFromBrowserIDAssertion(arg[0], arg[1], arg[2]);
michael@0 67 do_throw("Should never get here.");
michael@0 68 } catch (ex) {
michael@0 69 do_check_true(ex instanceof TokenServerClientError);
michael@0 70 }
michael@0 71 }
michael@0 72
michael@0 73 run_next_test();
michael@0 74 });
michael@0 75
michael@0 76 add_test(function test_conditions_required_response_handling() {
michael@0 77 _("Ensure that a conditions required response is handled properly.");
michael@0 78
michael@0 79 let description = "Need to accept conditions";
michael@0 80 let tosURL = "http://example.com/tos";
michael@0 81
michael@0 82 let server = httpd_setup({
michael@0 83 "/1.0/foo/1.0": function(request, response) {
michael@0 84 do_check_false(request.hasHeader("x-conditions-accepted"));
michael@0 85
michael@0 86 response.setStatusLine(request.httpVersion, 403, "Forbidden");
michael@0 87 response.setHeader("Content-Type", "application/json");
michael@0 88
michael@0 89 let body = JSON.stringify({
michael@0 90 errors: [{description: description, location: "body", name: ""}],
michael@0 91 urls: {tos: tosURL}
michael@0 92 });
michael@0 93 response.bodyOutputStream.write(body, body.length);
michael@0 94 }
michael@0 95 });
michael@0 96
michael@0 97 let client = new TokenServerClient();
michael@0 98 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 99
michael@0 100 function onResponse(error, token) {
michael@0 101 do_check_true(error instanceof TokenServerClientServerError);
michael@0 102 do_check_eq(error.cause, "conditions-required");
michael@0 103 do_check_null(token);
michael@0 104
michael@0 105 do_check_eq(error.urls.tos, tosURL);
michael@0 106
michael@0 107 server.stop(run_next_test);
michael@0 108 }
michael@0 109
michael@0 110 client.getTokenFromBrowserIDAssertion(url, "assertion", onResponse);
michael@0 111 });
michael@0 112
michael@0 113 add_test(function test_invalid_403_no_content_type() {
michael@0 114 _("Ensure that a 403 without content-type is handled properly.");
michael@0 115
michael@0 116 let server = httpd_setup({
michael@0 117 "/1.0/foo/1.0": function(request, response) {
michael@0 118 response.setStatusLine(request.httpVersion, 403, "Forbidden");
michael@0 119 // No Content-Type header by design.
michael@0 120
michael@0 121 let body = JSON.stringify({
michael@0 122 errors: [{description: "irrelevant", location: "body", name: ""}],
michael@0 123 urls: {foo: "http://bar"}
michael@0 124 });
michael@0 125 response.bodyOutputStream.write(body, body.length);
michael@0 126 }
michael@0 127 });
michael@0 128
michael@0 129 let client = new TokenServerClient();
michael@0 130 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 131
michael@0 132 function onResponse(error, token) {
michael@0 133 do_check_true(error instanceof TokenServerClientServerError);
michael@0 134 do_check_eq(error.cause, "malformed-response");
michael@0 135 do_check_null(token);
michael@0 136
michael@0 137 do_check_null(error.urls);
michael@0 138
michael@0 139 server.stop(run_next_test);
michael@0 140 }
michael@0 141
michael@0 142 client.getTokenFromBrowserIDAssertion(url, "assertion", onResponse);
michael@0 143 });
michael@0 144
michael@0 145 add_test(function test_invalid_403_bad_json() {
michael@0 146 _("Ensure that a 403 with JSON that isn't proper is handled properly.");
michael@0 147
michael@0 148 let server = httpd_setup({
michael@0 149 "/1.0/foo/1.0": function(request, response) {
michael@0 150 response.setStatusLine(request.httpVersion, 403, "Forbidden");
michael@0 151 response.setHeader("Content-Type", "application/json; charset=utf-8");
michael@0 152
michael@0 153 let body = JSON.stringify({
michael@0 154 foo: "bar"
michael@0 155 });
michael@0 156 response.bodyOutputStream.write(body, body.length);
michael@0 157 }
michael@0 158 });
michael@0 159
michael@0 160 let client = new TokenServerClient();
michael@0 161 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 162
michael@0 163 function onResponse(error, token) {
michael@0 164 do_check_true(error instanceof TokenServerClientServerError);
michael@0 165 do_check_eq(error.cause, "malformed-response");
michael@0 166 do_check_null(token);
michael@0 167 do_check_null(error.urls);
michael@0 168
michael@0 169 server.stop(run_next_test);
michael@0 170 }
michael@0 171
michael@0 172 client.getTokenFromBrowserIDAssertion(url, "assertion", onResponse);
michael@0 173 });
michael@0 174
michael@0 175 add_test(function test_403_no_urls() {
michael@0 176 _("Ensure that a 403 without a urls field is handled properly.");
michael@0 177
michael@0 178 let server = httpd_setup({
michael@0 179 "/1.0/foo/1.0": function(request, response) {
michael@0 180 response.setStatusLine(request.httpVersion, 403, "Forbidden");
michael@0 181 response.setHeader("Content-Type", "application/json; charset=utf-8");
michael@0 182
michael@0 183 let body = "{}";
michael@0 184 response.bodyOutputStream.write(body, body.length);
michael@0 185 }
michael@0 186 });
michael@0 187
michael@0 188 let client = new TokenServerClient();
michael@0 189 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 190
michael@0 191 client.getTokenFromBrowserIDAssertion(url, "assertion",
michael@0 192 function onResponse(error, result) {
michael@0 193 do_check_true(error instanceof TokenServerClientServerError);
michael@0 194 do_check_eq(error.cause, "malformed-response");
michael@0 195 do_check_null(result);
michael@0 196
michael@0 197 server.stop(run_next_test);
michael@0 198
michael@0 199 });
michael@0 200 });
michael@0 201
michael@0 202 add_test(function test_send_extra_headers() {
michael@0 203 _("Ensures that the condition acceptance header is sent when asked.");
michael@0 204
michael@0 205 let duration = 300;
michael@0 206 let server = httpd_setup({
michael@0 207 "/1.0/foo/1.0": function(request, response) {
michael@0 208 do_check_true(request.hasHeader("x-foo"));
michael@0 209 do_check_eq(request.getHeader("x-foo"), "42");
michael@0 210
michael@0 211 do_check_true(request.hasHeader("x-bar"));
michael@0 212 do_check_eq(request.getHeader("x-bar"), "17");
michael@0 213
michael@0 214 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 215 response.setHeader("Content-Type", "application/json");
michael@0 216
michael@0 217 let body = JSON.stringify({
michael@0 218 id: "id",
michael@0 219 key: "key",
michael@0 220 api_endpoint: "http://example.com/",
michael@0 221 uid: "uid",
michael@0 222 duration: duration,
michael@0 223 });
michael@0 224 response.bodyOutputStream.write(body, body.length);
michael@0 225 }
michael@0 226 });
michael@0 227
michael@0 228 let client = new TokenServerClient();
michael@0 229 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 230
michael@0 231 function onResponse(error, token) {
michael@0 232 do_check_null(error);
michael@0 233
michael@0 234 // Other tests validate other things.
michael@0 235
michael@0 236 server.stop(run_next_test);
michael@0 237 }
michael@0 238
michael@0 239 let extra = {
michael@0 240 "X-Foo": 42,
michael@0 241 "X-Bar": 17
michael@0 242 };
michael@0 243 client.getTokenFromBrowserIDAssertion(url, "assertion", onResponse, extra);
michael@0 244 });
michael@0 245
michael@0 246 add_test(function test_error_404_empty() {
michael@0 247 _("Ensure that 404 responses without proper response are handled properly.");
michael@0 248
michael@0 249 let server = httpd_setup();
michael@0 250
michael@0 251 let client = new TokenServerClient();
michael@0 252 let url = server.baseURI + "/foo";
michael@0 253 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 254 do_check_true(error instanceof TokenServerClientServerError);
michael@0 255 do_check_eq(error.cause, "malformed-response");
michael@0 256
michael@0 257 do_check_neq(null, error.response);
michael@0 258 do_check_null(r);
michael@0 259
michael@0 260 server.stop(run_next_test);
michael@0 261 });
michael@0 262 });
michael@0 263
michael@0 264 add_test(function test_error_404_proper_response() {
michael@0 265 _("Ensure that a Cornice error report for 404 is handled properly.");
michael@0 266
michael@0 267 let server = httpd_setup({
michael@0 268 "/1.0/foo/1.0": function(request, response) {
michael@0 269 response.setStatusLine(request.httpVersion, 404, "Not Found");
michael@0 270 response.setHeader("Content-Type", "application/json; charset=utf-8");
michael@0 271
michael@0 272 let body = JSON.stringify({
michael@0 273 status: 404,
michael@0 274 errors: [{description: "No service", location: "body", name: ""}],
michael@0 275 });
michael@0 276
michael@0 277 response.bodyOutputStream.write(body, body.length);
michael@0 278 }
michael@0 279 });
michael@0 280
michael@0 281 function onResponse(error, token) {
michael@0 282 do_check_true(error instanceof TokenServerClientServerError);
michael@0 283 do_check_eq(error.cause, "unknown-service");
michael@0 284 do_check_null(token);
michael@0 285
michael@0 286 server.stop(run_next_test);
michael@0 287 }
michael@0 288
michael@0 289 let client = new TokenServerClient();
michael@0 290 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 291 client.getTokenFromBrowserIDAssertion(url, "assertion", onResponse);
michael@0 292 });
michael@0 293
michael@0 294 add_test(function test_bad_json() {
michael@0 295 _("Ensure that malformed JSON is handled properly.");
michael@0 296
michael@0 297 let server = httpd_setup({
michael@0 298 "/1.0/foo/1.0": function(request, response) {
michael@0 299 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 300 response.setHeader("Content-Type", "application/json");
michael@0 301
michael@0 302 let body = '{"id": "id", baz}'
michael@0 303 response.bodyOutputStream.write(body, body.length);
michael@0 304 }
michael@0 305 });
michael@0 306
michael@0 307 let client = new TokenServerClient();
michael@0 308 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 309 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 310 do_check_neq(null, error);
michael@0 311 do_check_eq("TokenServerClientServerError", error.name);
michael@0 312 do_check_eq(error.cause, "malformed-response");
michael@0 313 do_check_neq(null, error.response);
michael@0 314 do_check_eq(null, r);
michael@0 315
michael@0 316 server.stop(run_next_test);
michael@0 317 });
michael@0 318 });
michael@0 319
michael@0 320 add_test(function test_400_response() {
michael@0 321 _("Ensure HTTP 400 is converted to malformed-request.");
michael@0 322
michael@0 323 let server = httpd_setup({
michael@0 324 "/1.0/foo/1.0": function(request, response) {
michael@0 325 response.setStatusLine(request.httpVersion, 400, "Bad Request");
michael@0 326 response.setHeader("Content-Type", "application/json; charset=utf-8");
michael@0 327
michael@0 328 let body = "{}"; // Actual content may not be used.
michael@0 329 response.bodyOutputStream.write(body, body.length);
michael@0 330 }
michael@0 331 });
michael@0 332
michael@0 333 let client = new TokenServerClient();
michael@0 334 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 335 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 336 do_check_neq(null, error);
michael@0 337 do_check_eq("TokenServerClientServerError", error.name);
michael@0 338 do_check_neq(null, error.response);
michael@0 339 do_check_eq(error.cause, "malformed-request");
michael@0 340
michael@0 341 server.stop(run_next_test);
michael@0 342 });
michael@0 343 });
michael@0 344
michael@0 345 add_test(function test_401_with_error_cause() {
michael@0 346 _("Ensure 401 cause is specified in body.status");
michael@0 347
michael@0 348 let server = httpd_setup({
michael@0 349 "/1.0/foo/1.0": function(request, response) {
michael@0 350 response.setStatusLine(request.httpVersion, 401, "Unauthorized");
michael@0 351 response.setHeader("Content-Type", "application/json; charset=utf-8");
michael@0 352
michael@0 353 let body = JSON.stringify({status: "no-soup-for-you"});
michael@0 354 response.bodyOutputStream.write(body, body.length);
michael@0 355 }
michael@0 356 });
michael@0 357
michael@0 358 let client = new TokenServerClient();
michael@0 359 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 360 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 361 do_check_neq(null, error);
michael@0 362 do_check_eq("TokenServerClientServerError", error.name);
michael@0 363 do_check_neq(null, error.response);
michael@0 364 do_check_eq(error.cause, "no-soup-for-you");
michael@0 365
michael@0 366 server.stop(run_next_test);
michael@0 367 });
michael@0 368 });
michael@0 369
michael@0 370 add_test(function test_unhandled_media_type() {
michael@0 371 _("Ensure that unhandled media types throw an error.");
michael@0 372
michael@0 373 let server = httpd_setup({
michael@0 374 "/1.0/foo/1.0": function(request, response) {
michael@0 375 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 376 response.setHeader("Content-Type", "text/plain");
michael@0 377
michael@0 378 let body = "hello, world";
michael@0 379 response.bodyOutputStream.write(body, body.length);
michael@0 380 }
michael@0 381 });
michael@0 382
michael@0 383 let url = server.baseURI + "/1.0/foo/1.0";
michael@0 384 let client = new TokenServerClient();
michael@0 385 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 386 do_check_neq(null, error);
michael@0 387 do_check_eq("TokenServerClientServerError", error.name);
michael@0 388 do_check_neq(null, error.response);
michael@0 389 do_check_eq(null, r);
michael@0 390
michael@0 391 server.stop(run_next_test);
michael@0 392 });
michael@0 393 });
michael@0 394
michael@0 395 add_test(function test_rich_media_types() {
michael@0 396 _("Ensure that extra tokens in the media type aren't rejected.");
michael@0 397
michael@0 398 let duration = 300;
michael@0 399 let server = httpd_setup({
michael@0 400 "/foo": function(request, response) {
michael@0 401 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 402 response.setHeader("Content-Type", "application/json; foo=bar; bar=foo");
michael@0 403
michael@0 404 let body = JSON.stringify({
michael@0 405 id: "id",
michael@0 406 key: "key",
michael@0 407 api_endpoint: "foo",
michael@0 408 uid: "uid",
michael@0 409 duration: duration,
michael@0 410 });
michael@0 411 response.bodyOutputStream.write(body, body.length);
michael@0 412 }
michael@0 413 });
michael@0 414
michael@0 415 let url = server.baseURI + "/foo";
michael@0 416 let client = new TokenServerClient();
michael@0 417 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 418 do_check_eq(null, error);
michael@0 419
michael@0 420 server.stop(run_next_test);
michael@0 421 });
michael@0 422 });
michael@0 423
michael@0 424 add_test(function test_exception_during_callback() {
michael@0 425 _("Ensure that exceptions thrown during callback handling are handled.");
michael@0 426
michael@0 427 let duration = 300;
michael@0 428 let server = httpd_setup({
michael@0 429 "/foo": function(request, response) {
michael@0 430 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 431 response.setHeader("Content-Type", "application/json");
michael@0 432
michael@0 433 let body = JSON.stringify({
michael@0 434 id: "id",
michael@0 435 key: "key",
michael@0 436 api_endpoint: "foo",
michael@0 437 uid: "uid",
michael@0 438 duration: duration,
michael@0 439 });
michael@0 440 response.bodyOutputStream.write(body, body.length);
michael@0 441 }
michael@0 442 });
michael@0 443
michael@0 444 let url = server.baseURI + "/foo";
michael@0 445 let client = new TokenServerClient();
michael@0 446 let cb = Async.makeSpinningCallback();
michael@0 447 let callbackCount = 0;
michael@0 448
michael@0 449 client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
michael@0 450 do_check_eq(null, error);
michael@0 451
michael@0 452 cb();
michael@0 453
michael@0 454 callbackCount += 1;
michael@0 455 throw new Error("I am a bad function!");
michael@0 456 });
michael@0 457
michael@0 458 cb.wait();
michael@0 459 // This relies on some heavy event loop magic. The error in the main
michael@0 460 // callback should already have been raised at this point.
michael@0 461 do_check_eq(callbackCount, 1);
michael@0 462
michael@0 463 server.stop(run_next_test);
michael@0 464 });

mercurial