services/common/tests/unit/test_tokenserverclient.js

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

mercurial