test_tokenserverclient.js (11095B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 const { 5 TokenServerClient, 6 TokenServerClientError, 7 TokenServerClientServerError, 8 } = ChromeUtils.importESModule( 9 "resource://services-common/tokenserverclient.sys.mjs" 10 ); 11 12 initTestLogging("Trace"); 13 14 add_task(async function test_working_token_exchange() { 15 _("Ensure that working OAuth token exchange works as expected."); 16 17 let service = "http://example.com/foo"; 18 let duration = 300; 19 20 let server = httpd_setup({ 21 "/1.0/foo/1.0": function (request, response) { 22 Assert.ok(request.hasHeader("accept")); 23 Assert.equal("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, 34 }); 35 response.bodyOutputStream.write(body, body.length); 36 }, 37 }); 38 39 let client = new TokenServerClient(); 40 let url = server.baseURI + "/1.0/foo/1.0"; 41 let result = await client.getTokenUsingOAuth(url, "access_token"); 42 Assert.equal("object", typeof result); 43 do_check_attribute_count(result, 7); 44 Assert.equal(service, result.endpoint); 45 Assert.equal("id", result.id); 46 Assert.equal("key", result.key); 47 Assert.equal("uid", result.uid); 48 Assert.equal(duration, result.duration); 49 Assert.deepEqual(undefined, result.node_type); 50 await promiseStopServer(server); 51 }); 52 53 add_task(async function test_working_token_exchange_with_nodetype() { 54 _("Ensure that a token response with a node type as expected."); 55 56 let service = "http://example.com/foo"; 57 let duration = 300; 58 let nodeType = "the-node-type"; 59 60 let server = httpd_setup({ 61 "/1.0/foo/1.0": function (request, response) { 62 Assert.ok(request.hasHeader("accept")); 63 Assert.equal("application/json", request.getHeader("accept")); 64 65 response.setStatusLine(request.httpVersion, 200, "OK"); 66 response.setHeader("Content-Type", "application/json"); 67 68 let body = JSON.stringify({ 69 id: "id", 70 key: "key", 71 api_endpoint: service, 72 uid: "uid", 73 duration, 74 node_type: nodeType, 75 }); 76 response.bodyOutputStream.write(body, body.length); 77 }, 78 }); 79 80 let client = new TokenServerClient(); 81 let url = server.baseURI + "/1.0/foo/1.0"; 82 let result = await client.getTokenUsingOAuth(url, "access_token"); 83 Assert.equal("object", typeof result); 84 do_check_attribute_count(result, 7); 85 Assert.equal(service, result.endpoint); 86 Assert.equal("id", result.id); 87 Assert.equal("key", result.key); 88 Assert.equal("uid", result.uid); 89 Assert.equal(duration, result.duration); 90 Assert.equal(nodeType, result.node_type); 91 await promiseStopServer(server); 92 }); 93 94 add_task(async function test_invalid_arguments() { 95 _("Ensure invalid arguments to APIs are rejected."); 96 97 let args = [ 98 [null, "access_token"], 99 ["http://example.com/", null], 100 ]; 101 102 for (let arg of args) { 103 let client = new TokenServerClient(); 104 await Assert.rejects(client.getTokenUsingOAuth(arg[0], arg[1]), ex => { 105 Assert.ok(ex instanceof TokenServerClientError); 106 return true; 107 }); 108 } 109 }); 110 111 add_task(async function test_invalid_403_no_content_type() { 112 _("Ensure that a 403 without content-type is handled properly."); 113 114 let server = httpd_setup({ 115 "/1.0/foo/1.0": function (request, response) { 116 response.setStatusLine(request.httpVersion, 403, "Forbidden"); 117 // No Content-Type header by design. 118 119 let body = JSON.stringify({ 120 errors: [{ description: "irrelevant", location: "body", name: "" }], 121 urls: { foo: "http://bar" }, 122 }); 123 response.bodyOutputStream.write(body, body.length); 124 }, 125 }); 126 127 let client = new TokenServerClient(); 128 let url = server.baseURI + "/1.0/foo/1.0"; 129 130 await Assert.rejects( 131 client.getTokenUsingOAuth(url, "access_token"), 132 error => { 133 Assert.ok(error instanceof TokenServerClientServerError); 134 Assert.equal(error.cause, "malformed-response"); 135 136 Assert.equal(null, error.urls); 137 return true; 138 } 139 ); 140 141 await promiseStopServer(server); 142 }); 143 144 add_task(async function test_send_extra_headers() { 145 _("Ensures that the condition acceptance header is sent when asked."); 146 147 let duration = 300; 148 let server = httpd_setup({ 149 "/1.0/foo/1.0": function (request, response) { 150 Assert.ok(request.hasHeader("x-foo")); 151 Assert.equal(request.getHeader("x-foo"), "42"); 152 153 Assert.ok(request.hasHeader("x-bar")); 154 Assert.equal(request.getHeader("x-bar"), "17"); 155 156 response.setStatusLine(request.httpVersion, 200, "OK"); 157 response.setHeader("Content-Type", "application/json"); 158 159 let body = JSON.stringify({ 160 id: "id", 161 key: "key", 162 api_endpoint: "http://example.com/", 163 uid: "uid", 164 duration, 165 }); 166 response.bodyOutputStream.write(body, body.length); 167 }, 168 }); 169 170 let client = new TokenServerClient(); 171 let url = server.baseURI + "/1.0/foo/1.0"; 172 173 let extra = { 174 "X-Foo": 42, 175 "X-Bar": 17, 176 }; 177 178 await client.getTokenUsingOAuth(url, "access_token", extra); 179 // Other tests validate other things. 180 181 await promiseStopServer(server); 182 }); 183 184 add_task(async function test_error_404_empty() { 185 _("Ensure that 404 responses without proper response are handled properly."); 186 187 let server = httpd_setup(); 188 189 let client = new TokenServerClient(); 190 let url = server.baseURI + "/foo"; 191 192 await Assert.rejects( 193 client.getTokenUsingOAuth(url, "access_token"), 194 error => { 195 Assert.ok(error instanceof TokenServerClientServerError); 196 Assert.equal(error.cause, "malformed-response"); 197 198 Assert.notEqual(null, error.response); 199 return true; 200 } 201 ); 202 203 await promiseStopServer(server); 204 }); 205 206 add_task(async function test_error_404_proper_response() { 207 _("Ensure that a Cornice error report for 404 is handled properly."); 208 209 let server = httpd_setup({ 210 "/1.0/foo/1.0": function (request, response) { 211 response.setStatusLine(request.httpVersion, 404, "Not Found"); 212 response.setHeader("Content-Type", "application/json; charset=utf-8"); 213 214 let body = JSON.stringify({ 215 status: 404, 216 errors: [{ description: "No service", location: "body", name: "" }], 217 }); 218 219 response.bodyOutputStream.write(body, body.length); 220 }, 221 }); 222 223 let client = new TokenServerClient(); 224 let url = server.baseURI + "/1.0/foo/1.0"; 225 226 await Assert.rejects( 227 client.getTokenUsingOAuth(url, "access_token"), 228 error => { 229 Assert.ok(error instanceof TokenServerClientServerError); 230 Assert.equal(error.cause, "unknown-service"); 231 return true; 232 } 233 ); 234 235 await promiseStopServer(server); 236 }); 237 238 add_task(async function test_bad_json() { 239 _("Ensure that malformed JSON is handled properly."); 240 241 let server = httpd_setup({ 242 "/1.0/foo/1.0": function (request, response) { 243 response.setStatusLine(request.httpVersion, 200, "OK"); 244 response.setHeader("Content-Type", "application/json"); 245 246 let body = '{"id": "id", baz}'; 247 response.bodyOutputStream.write(body, body.length); 248 }, 249 }); 250 251 let client = new TokenServerClient(); 252 let url = server.baseURI + "/1.0/foo/1.0"; 253 254 await Assert.rejects( 255 client.getTokenUsingOAuth(url, "access_token"), 256 error => { 257 Assert.notEqual(null, error); 258 Assert.equal("TokenServerClientServerError", error.name); 259 Assert.equal(error.cause, "malformed-response"); 260 Assert.notEqual(null, error.response); 261 return true; 262 } 263 ); 264 265 await promiseStopServer(server); 266 }); 267 268 add_task(async function test_400_response() { 269 _("Ensure HTTP 400 is converted to malformed-request."); 270 271 let server = httpd_setup({ 272 "/1.0/foo/1.0": function (request, response) { 273 response.setStatusLine(request.httpVersion, 400, "Bad Request"); 274 response.setHeader("Content-Type", "application/json; charset=utf-8"); 275 276 let body = "{}"; // Actual content may not be used. 277 response.bodyOutputStream.write(body, body.length); 278 }, 279 }); 280 281 let client = new TokenServerClient(); 282 let url = server.baseURI + "/1.0/foo/1.0"; 283 284 await Assert.rejects( 285 client.getTokenUsingOAuth(url, "access_token"), 286 error => { 287 Assert.notEqual(null, error); 288 Assert.equal("TokenServerClientServerError", error.name); 289 Assert.notEqual(null, error.response); 290 Assert.equal(error.cause, "malformed-request"); 291 return true; 292 } 293 ); 294 295 await promiseStopServer(server); 296 }); 297 298 add_task(async function test_401_with_error_cause() { 299 _("Ensure 401 cause is specified in body.status"); 300 301 let server = httpd_setup({ 302 "/1.0/foo/1.0": function (request, response) { 303 response.setStatusLine(request.httpVersion, 401, "Unauthorized"); 304 response.setHeader("Content-Type", "application/json; charset=utf-8"); 305 306 let body = JSON.stringify({ status: "no-soup-for-you" }); 307 response.bodyOutputStream.write(body, body.length); 308 }, 309 }); 310 311 let client = new TokenServerClient(); 312 let url = server.baseURI + "/1.0/foo/1.0"; 313 314 await Assert.rejects( 315 client.getTokenUsingOAuth(url, "access_token"), 316 error => { 317 Assert.notEqual(null, error); 318 Assert.equal("TokenServerClientServerError", error.name); 319 Assert.notEqual(null, error.response); 320 Assert.equal(error.cause, "no-soup-for-you"); 321 return true; 322 } 323 ); 324 325 await promiseStopServer(server); 326 }); 327 328 add_task(async function test_unhandled_media_type() { 329 _("Ensure that unhandled media types throw an error."); 330 331 let server = httpd_setup({ 332 "/1.0/foo/1.0": function (request, response) { 333 response.setStatusLine(request.httpVersion, 200, "OK"); 334 response.setHeader("Content-Type", "text/plain"); 335 336 let body = "hello, world"; 337 response.bodyOutputStream.write(body, body.length); 338 }, 339 }); 340 341 let url = server.baseURI + "/1.0/foo/1.0"; 342 let client = new TokenServerClient(); 343 344 await Assert.rejects( 345 client.getTokenUsingOAuth(url, "access_token"), 346 error => { 347 Assert.notEqual(null, error); 348 Assert.equal("TokenServerClientServerError", error.name); 349 Assert.notEqual(null, error.response); 350 return true; 351 } 352 ); 353 354 await promiseStopServer(server); 355 }); 356 357 add_task(async function test_rich_media_types() { 358 _("Ensure that extra tokens in the media type aren't rejected."); 359 360 let duration = 300; 361 let server = httpd_setup({ 362 "/foo": function (request, response) { 363 response.setStatusLine(request.httpVersion, 200, "OK"); 364 response.setHeader("Content-Type", "application/json; foo=bar; bar=foo"); 365 366 let body = JSON.stringify({ 367 id: "id", 368 key: "key", 369 api_endpoint: "foo", 370 uid: "uid", 371 duration, 372 }); 373 response.bodyOutputStream.write(body, body.length); 374 }, 375 }); 376 377 let url = server.baseURI + "/foo"; 378 let client = new TokenServerClient(); 379 380 await client.getTokenUsingOAuth(url, "access_token"); 381 await promiseStopServer(server); 382 });