services/common/tests/unit/test_storage_server.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/rest.js");
michael@0 6 Cu.import("resource://services-common/utils.js");
michael@0 7 Cu.import("resource://testing-common/services-common/storageserver.js");
michael@0 8
michael@0 9 const DEFAULT_USER = "123";
michael@0 10 const DEFAULT_PASSWORD = "password";
michael@0 11
michael@0 12 /**
michael@0 13 * Helper function to prepare a RESTRequest against the server.
michael@0 14 */
michael@0 15 function localRequest(server, path, user=DEFAULT_USER, password=DEFAULT_PASSWORD) {
michael@0 16 _("localRequest: " + path);
michael@0 17 let identity = server.server.identity;
michael@0 18 let url = identity.primaryScheme + "://" + identity.primaryHost + ":" +
michael@0 19 identity.primaryPort + path;
michael@0 20 _("url: " + url);
michael@0 21 let req = new RESTRequest(url);
michael@0 22
michael@0 23 let header = basic_auth_header(user, password);
michael@0 24 req.setHeader("Authorization", header);
michael@0 25 req.setHeader("Accept", "application/json");
michael@0 26
michael@0 27 return req;
michael@0 28 }
michael@0 29
michael@0 30 /**
michael@0 31 * Helper function to validate an HTTP response from the server.
michael@0 32 */
michael@0 33 function validateResponse(response) {
michael@0 34 do_check_true("x-timestamp" in response.headers);
michael@0 35
michael@0 36 if ("content-length" in response.headers) {
michael@0 37 let cl = parseInt(response.headers["content-length"]);
michael@0 38
michael@0 39 if (cl != 0) {
michael@0 40 do_check_true("content-type" in response.headers);
michael@0 41 do_check_eq("application/json", response.headers["content-type"]);
michael@0 42 }
michael@0 43 }
michael@0 44
michael@0 45 if (response.status == 204 || response.status == 304) {
michael@0 46 do_check_false("content-type" in response.headers);
michael@0 47
michael@0 48 if ("content-length" in response.headers) {
michael@0 49 do_check_eq(response.headers["content-length"], "0");
michael@0 50 }
michael@0 51 }
michael@0 52
michael@0 53 if (response.status == 405) {
michael@0 54 do_check_true("allow" in response.headers);
michael@0 55 }
michael@0 56 }
michael@0 57
michael@0 58 /**
michael@0 59 * Helper function to synchronously wait for a response and validate it.
michael@0 60 */
michael@0 61 function waitAndValidateResponse(cb, request) {
michael@0 62 let error = cb.wait();
michael@0 63
michael@0 64 if (!error) {
michael@0 65 validateResponse(request.response);
michael@0 66 }
michael@0 67
michael@0 68 return error;
michael@0 69 }
michael@0 70
michael@0 71 /**
michael@0 72 * Helper function to synchronously perform a GET request.
michael@0 73 *
michael@0 74 * @return Error instance or null if no error.
michael@0 75 */
michael@0 76 function doGetRequest(request) {
michael@0 77 let cb = Async.makeSpinningCallback();
michael@0 78 request.get(cb);
michael@0 79
michael@0 80 return waitAndValidateResponse(cb, request);
michael@0 81 }
michael@0 82
michael@0 83 /**
michael@0 84 * Helper function to synchronously perform a PUT request.
michael@0 85 *
michael@0 86 * @return Error instance or null if no error.
michael@0 87 */
michael@0 88 function doPutRequest(request, data) {
michael@0 89 let cb = Async.makeSpinningCallback();
michael@0 90 request.put(data, cb);
michael@0 91
michael@0 92 return waitAndValidateResponse(cb, request);
michael@0 93 }
michael@0 94
michael@0 95 /**
michael@0 96 * Helper function to synchronously perform a DELETE request.
michael@0 97 *
michael@0 98 * @return Error or null if no error was encountered.
michael@0 99 */
michael@0 100 function doDeleteRequest(request) {
michael@0 101 let cb = Async.makeSpinningCallback();
michael@0 102 request.delete(cb);
michael@0 103
michael@0 104 return waitAndValidateResponse(cb, request);
michael@0 105 }
michael@0 106
michael@0 107 function run_test() {
michael@0 108 Log.repository.getLogger("Services.Common.Test.StorageServer").level =
michael@0 109 Log.Level.Trace;
michael@0 110 initTestLogging();
michael@0 111
michael@0 112 run_next_test();
michael@0 113 }
michael@0 114
michael@0 115 add_test(function test_creation() {
michael@0 116 _("Ensure a simple server can be created.");
michael@0 117
michael@0 118 // Explicit callback for this one.
michael@0 119 let server = new StorageServer({
michael@0 120 __proto__: StorageServerCallback,
michael@0 121 });
michael@0 122 do_check_true(!!server);
michael@0 123
michael@0 124 server.start(-1, function () {
michael@0 125 _("Started on " + server.port);
michael@0 126 server.stop(run_next_test);
michael@0 127 });
michael@0 128 });
michael@0 129
michael@0 130 add_test(function test_synchronous_start() {
michael@0 131 _("Ensure starting using startSynchronous works.");
michael@0 132
michael@0 133 let server = new StorageServer();
michael@0 134 server.startSynchronous();
michael@0 135 server.stop(run_next_test);
michael@0 136 });
michael@0 137
michael@0 138 add_test(function test_url_parsing() {
michael@0 139 _("Ensure server parses URLs properly.");
michael@0 140
michael@0 141 let server = new StorageServer();
michael@0 142
michael@0 143 // Check that we can parse a BSO URI.
michael@0 144 let parts = server.pathRE.exec("/2.0/12345/storage/crypto/keys");
michael@0 145 let [all, version, user, first, rest] = parts;
michael@0 146 do_check_eq(all, "/2.0/12345/storage/crypto/keys");
michael@0 147 do_check_eq(version, "2.0");
michael@0 148 do_check_eq(user, "12345");
michael@0 149 do_check_eq(first, "storage");
michael@0 150 do_check_eq(rest, "crypto/keys");
michael@0 151 do_check_eq(null, server.pathRE.exec("/nothing/else"));
michael@0 152
michael@0 153 // Check that we can parse a collection URI.
michael@0 154 parts = server.pathRE.exec("/2.0/123/storage/crypto");
michael@0 155 let [all, version, user, first, rest] = parts;
michael@0 156 do_check_eq(all, "/2.0/123/storage/crypto");
michael@0 157 do_check_eq(version, "2.0");
michael@0 158 do_check_eq(user, "123");
michael@0 159 do_check_eq(first, "storage");
michael@0 160 do_check_eq(rest, "crypto");
michael@0 161
michael@0 162 // We don't allow trailing slash on storage URI.
michael@0 163 parts = server.pathRE.exec("/2.0/1234/storage/");
michael@0 164 do_check_eq(parts, undefined);
michael@0 165
michael@0 166 // storage alone is a valid request.
michael@0 167 parts = server.pathRE.exec("/2.0/123456/storage");
michael@0 168 let [all, version, user, first, rest] = parts;
michael@0 169 do_check_eq(all, "/2.0/123456/storage");
michael@0 170 do_check_eq(version, "2.0");
michael@0 171 do_check_eq(user, "123456");
michael@0 172 do_check_eq(first, "storage");
michael@0 173 do_check_eq(rest, undefined);
michael@0 174
michael@0 175 parts = server.storageRE.exec("storage");
michael@0 176 let [all, storage, collection, id] = parts;
michael@0 177 do_check_eq(all, "storage");
michael@0 178 do_check_eq(collection, undefined);
michael@0 179
michael@0 180 run_next_test();
michael@0 181 });
michael@0 182
michael@0 183 add_test(function test_basic_http() {
michael@0 184 let server = new StorageServer();
michael@0 185 server.registerUser("345", "password");
michael@0 186 do_check_true(server.userExists("345"));
michael@0 187 server.startSynchronous();
michael@0 188
michael@0 189 _("Started on " + server.port);
michael@0 190 do_check_eq(server.requestCount, 0);
michael@0 191 let req = localRequest(server, "/2.0/storage/crypto/keys");
michael@0 192 _("req is " + req);
michael@0 193 req.get(function (err) {
michael@0 194 do_check_eq(null, err);
michael@0 195 do_check_eq(server.requestCount, 1);
michael@0 196 server.stop(run_next_test);
michael@0 197 });
michael@0 198 });
michael@0 199
michael@0 200 add_test(function test_info_collections() {
michael@0 201 let server = new StorageServer();
michael@0 202 server.registerUser("123", "password");
michael@0 203 server.startSynchronous();
michael@0 204
michael@0 205 let path = "/2.0/123/info/collections";
michael@0 206
michael@0 207 _("info/collections on empty server should be empty object.");
michael@0 208 let request = localRequest(server, path, "123", "password");
michael@0 209 let error = doGetRequest(request);
michael@0 210 do_check_eq(error, null);
michael@0 211 do_check_eq(request.response.status, 200);
michael@0 212 do_check_eq(request.response.body, "{}");
michael@0 213
michael@0 214 _("Creating an empty collection should result in collection appearing.");
michael@0 215 let coll = server.createCollection("123", "col1");
michael@0 216 let request = localRequest(server, path, "123", "password");
michael@0 217 let error = doGetRequest(request);
michael@0 218 do_check_eq(error, null);
michael@0 219 do_check_eq(request.response.status, 200);
michael@0 220 let info = JSON.parse(request.response.body);
michael@0 221 do_check_attribute_count(info, 1);
michael@0 222 do_check_true("col1" in info);
michael@0 223 do_check_eq(info.col1, coll.timestamp);
michael@0 224
michael@0 225 server.stop(run_next_test);
michael@0 226 });
michael@0 227
michael@0 228 add_test(function test_bso_get_existing() {
michael@0 229 _("Ensure that BSO retrieval works.");
michael@0 230
michael@0 231 let server = new StorageServer();
michael@0 232 server.registerUser("123", "password");
michael@0 233 server.createContents("123", {
michael@0 234 test: {"bso": {"foo": "bar"}}
michael@0 235 });
michael@0 236 server.startSynchronous();
michael@0 237
michael@0 238 let coll = server.user("123").collection("test");
michael@0 239
michael@0 240 let request = localRequest(server, "/2.0/123/storage/test/bso", "123",
michael@0 241 "password");
michael@0 242 let error = doGetRequest(request);
michael@0 243 do_check_eq(error, null);
michael@0 244 do_check_eq(request.response.status, 200);
michael@0 245 do_check_eq(request.response.headers["content-type"], "application/json");
michael@0 246 let bso = JSON.parse(request.response.body);
michael@0 247 do_check_attribute_count(bso, 3);
michael@0 248 do_check_eq(bso.id, "bso");
michael@0 249 do_check_eq(bso.modified, coll.bso("bso").modified);
michael@0 250 let payload = JSON.parse(bso.payload);
michael@0 251 do_check_attribute_count(payload, 1);
michael@0 252 do_check_eq(payload.foo, "bar");
michael@0 253
michael@0 254 server.stop(run_next_test);
michael@0 255 });
michael@0 256
michael@0 257 add_test(function test_percent_decoding() {
michael@0 258 _("Ensure query string arguments with percent encoded are handled.");
michael@0 259
michael@0 260 let server = new StorageServer();
michael@0 261 server.registerUser("123", "password");
michael@0 262 server.startSynchronous();
michael@0 263
michael@0 264 let coll = server.user("123").createCollection("test");
michael@0 265 coll.insert("001", {foo: "bar"});
michael@0 266 coll.insert("002", {bar: "foo"});
michael@0 267
michael@0 268 let request = localRequest(server, "/2.0/123/storage/test?ids=001%2C002",
michael@0 269 "123", "password");
michael@0 270 let error = doGetRequest(request);
michael@0 271 do_check_null(error);
michael@0 272 do_check_eq(request.response.status, 200);
michael@0 273 let items = JSON.parse(request.response.body).items;
michael@0 274 do_check_attribute_count(items, 2);
michael@0 275
michael@0 276 server.stop(run_next_test);
michael@0 277 });
michael@0 278
michael@0 279 add_test(function test_bso_404() {
michael@0 280 _("Ensure the server responds with a 404 if a BSO does not exist.");
michael@0 281
michael@0 282 let server = new StorageServer();
michael@0 283 server.registerUser("123", "password");
michael@0 284 server.createContents("123", {
michael@0 285 test: {}
michael@0 286 });
michael@0 287 server.startSynchronous();
michael@0 288
michael@0 289 let request = localRequest(server, "/2.0/123/storage/test/foo");
michael@0 290 let error = doGetRequest(request);
michael@0 291 do_check_eq(error, null);
michael@0 292
michael@0 293 do_check_eq(request.response.status, 404);
michael@0 294 do_check_false("content-type" in request.response.headers);
michael@0 295
michael@0 296 server.stop(run_next_test);
michael@0 297 });
michael@0 298
michael@0 299 add_test(function test_bso_if_modified_since_304() {
michael@0 300 _("Ensure the server responds properly to X-If-Modified-Since for BSOs.");
michael@0 301
michael@0 302 let server = new StorageServer();
michael@0 303 server.registerUser("123", "password");
michael@0 304 server.createContents("123", {
michael@0 305 test: {bso: {foo: "bar"}}
michael@0 306 });
michael@0 307 server.startSynchronous();
michael@0 308
michael@0 309 let coll = server.user("123").collection("test");
michael@0 310 do_check_neq(coll, null);
michael@0 311
michael@0 312 // Rewind clock just in case.
michael@0 313 coll.timestamp -= 10000;
michael@0 314 coll.bso("bso").modified -= 10000;
michael@0 315
michael@0 316 let request = localRequest(server, "/2.0/123/storage/test/bso",
michael@0 317 "123", "password");
michael@0 318 request.setHeader("X-If-Modified-Since", "" + server.serverTime());
michael@0 319 let error = doGetRequest(request);
michael@0 320 do_check_eq(null, error);
michael@0 321
michael@0 322 do_check_eq(request.response.status, 304);
michael@0 323 do_check_false("content-type" in request.response.headers);
michael@0 324
michael@0 325 let request = localRequest(server, "/2.0/123/storage/test/bso",
michael@0 326 "123", "password");
michael@0 327 request.setHeader("X-If-Modified-Since", "" + (server.serverTime() - 20000));
michael@0 328 let error = doGetRequest(request);
michael@0 329 do_check_eq(null, error);
michael@0 330 do_check_eq(request.response.status, 200);
michael@0 331 do_check_eq(request.response.headers["content-type"], "application/json");
michael@0 332
michael@0 333 server.stop(run_next_test);
michael@0 334 });
michael@0 335
michael@0 336 add_test(function test_bso_if_unmodified_since() {
michael@0 337 _("Ensure X-If-Unmodified-Since works properly on BSOs.");
michael@0 338
michael@0 339 let server = new StorageServer();
michael@0 340 server.registerUser("123", "password");
michael@0 341 server.createContents("123", {
michael@0 342 test: {bso: {foo: "bar"}}
michael@0 343 });
michael@0 344 server.startSynchronous();
michael@0 345
michael@0 346 let coll = server.user("123").collection("test");
michael@0 347 do_check_neq(coll, null);
michael@0 348
michael@0 349 let time = coll.bso("bso").modified;
michael@0 350
michael@0 351 _("Ensure we get a 412 for specified times older than server time.");
michael@0 352 let request = localRequest(server, "/2.0/123/storage/test/bso",
michael@0 353 "123", "password");
michael@0 354 request.setHeader("X-If-Unmodified-Since", time - 5000);
michael@0 355 request.setHeader("Content-Type", "application/json");
michael@0 356 let payload = JSON.stringify({"payload": "foobar"});
michael@0 357 let error = doPutRequest(request, payload);
michael@0 358 do_check_eq(null, error);
michael@0 359 do_check_eq(request.response.status, 412);
michael@0 360
michael@0 361 _("Ensure we get a 204 if update goes through.");
michael@0 362 let request = localRequest(server, "/2.0/123/storage/test/bso",
michael@0 363 "123", "password");
michael@0 364 request.setHeader("Content-Type", "application/json");
michael@0 365 request.setHeader("X-If-Unmodified-Since", time + 1);
michael@0 366 let error = doPutRequest(request, payload);
michael@0 367 do_check_eq(null, error);
michael@0 368 do_check_eq(request.response.status, 204);
michael@0 369 do_check_true(coll.timestamp > time);
michael@0 370
michael@0 371 // Not sure why a client would send X-If-Unmodified-Since if a BSO doesn't
michael@0 372 // exist. But, why not test it?
michael@0 373 _("Ensure we get a 201 if creation goes through.");
michael@0 374 let request = localRequest(server, "/2.0/123/storage/test/none",
michael@0 375 "123", "password");
michael@0 376 request.setHeader("Content-Type", "application/json");
michael@0 377 request.setHeader("X-If-Unmodified-Since", time);
michael@0 378 let error = doPutRequest(request, payload);
michael@0 379 do_check_eq(null, error);
michael@0 380 do_check_eq(request.response.status, 201);
michael@0 381
michael@0 382 server.stop(run_next_test);
michael@0 383 });
michael@0 384
michael@0 385 add_test(function test_bso_delete_not_exist() {
michael@0 386 _("Ensure server behaves properly when deleting a BSO that does not exist.");
michael@0 387
michael@0 388 let server = new StorageServer();
michael@0 389 server.registerUser("123", "password");
michael@0 390 server.user("123").createCollection("empty");
michael@0 391 server.startSynchronous();
michael@0 392
michael@0 393 server.callback.onItemDeleted = function onItemDeleted(username, collection,
michael@0 394 id) {
michael@0 395 do_throw("onItemDeleted should not have been called.");
michael@0 396 };
michael@0 397
michael@0 398 let request = localRequest(server, "/2.0/123/storage/empty/nada",
michael@0 399 "123", "password");
michael@0 400 let error = doDeleteRequest(request);
michael@0 401 do_check_eq(error, null);
michael@0 402 do_check_eq(request.response.status, 404);
michael@0 403 do_check_false("content-type" in request.response.headers);
michael@0 404
michael@0 405 server.stop(run_next_test);
michael@0 406 });
michael@0 407
michael@0 408 add_test(function test_bso_delete_exists() {
michael@0 409 _("Ensure proper semantics when deleting a BSO that exists.");
michael@0 410
michael@0 411 let server = new StorageServer();
michael@0 412 server.registerUser("123", "password");
michael@0 413 server.startSynchronous();
michael@0 414
michael@0 415 let coll = server.user("123").createCollection("test");
michael@0 416 let bso = coll.insert("myid", {foo: "bar"});
michael@0 417 let timestamp = coll.timestamp;
michael@0 418
michael@0 419 server.callback.onItemDeleted = function onDeleted(username, collection, id) {
michael@0 420 delete server.callback.onItemDeleted;
michael@0 421 do_check_eq(username, "123");
michael@0 422 do_check_eq(collection, "test");
michael@0 423 do_check_eq(id, "myid");
michael@0 424 };
michael@0 425
michael@0 426 let request = localRequest(server, "/2.0/123/storage/test/myid",
michael@0 427 "123", "password");
michael@0 428 let error = doDeleteRequest(request);
michael@0 429 do_check_eq(error, null);
michael@0 430 do_check_eq(request.response.status, 204);
michael@0 431 do_check_eq(coll.bsos().length, 0);
michael@0 432 do_check_true(coll.timestamp > timestamp);
michael@0 433
michael@0 434 _("On next request the BSO should not exist.");
michael@0 435 let request = localRequest(server, "/2.0/123/storage/test/myid",
michael@0 436 "123", "password");
michael@0 437 let error = doGetRequest(request);
michael@0 438 do_check_eq(error, null);
michael@0 439 do_check_eq(request.response.status, 404);
michael@0 440
michael@0 441 server.stop(run_next_test);
michael@0 442 });
michael@0 443
michael@0 444 add_test(function test_bso_delete_unmodified() {
michael@0 445 _("Ensure X-If-Unmodified-Since works when deleting BSOs.");
michael@0 446
michael@0 447 let server = new StorageServer();
michael@0 448 server.startSynchronous();
michael@0 449 server.registerUser("123", "password");
michael@0 450 let coll = server.user("123").createCollection("test");
michael@0 451 let bso = coll.insert("myid", {foo: "bar"});
michael@0 452
michael@0 453 let modified = bso.modified;
michael@0 454
michael@0 455 _("Issuing a DELETE with an older time should fail.");
michael@0 456 let path = "/2.0/123/storage/test/myid";
michael@0 457 let request = localRequest(server, path, "123", "password");
michael@0 458 request.setHeader("X-If-Unmodified-Since", modified - 1000);
michael@0 459 let error = doDeleteRequest(request);
michael@0 460 do_check_eq(error, null);
michael@0 461 do_check_eq(request.response.status, 412);
michael@0 462 do_check_false("content-type" in request.response.headers);
michael@0 463 do_check_neq(coll.bso("myid"), null);
michael@0 464
michael@0 465 _("Issuing a DELETE with a newer time should work.");
michael@0 466 let request = localRequest(server, path, "123", "password");
michael@0 467 request.setHeader("X-If-Unmodified-Since", modified + 1000);
michael@0 468 let error = doDeleteRequest(request);
michael@0 469 do_check_eq(error, null);
michael@0 470 do_check_eq(request.response.status, 204);
michael@0 471 do_check_true(coll.bso("myid").deleted);
michael@0 472
michael@0 473 server.stop(run_next_test);
michael@0 474 });
michael@0 475
michael@0 476 add_test(function test_collection_get_unmodified_since() {
michael@0 477 _("Ensure conditional unmodified get on collection works when it should.");
michael@0 478
michael@0 479 let server = new StorageServer();
michael@0 480 server.registerUser("123", "password");
michael@0 481 server.startSynchronous();
michael@0 482 let collection = server.user("123").createCollection("testcoll");
michael@0 483 collection.insert("bso0", {foo: "bar"});
michael@0 484
michael@0 485 let serverModified = collection.timestamp;
michael@0 486
michael@0 487 let request1 = localRequest(server, "/2.0/123/storage/testcoll",
michael@0 488 "123", "password");
michael@0 489 request1.setHeader("X-If-Unmodified-Since", serverModified);
michael@0 490 let error = doGetRequest(request1);
michael@0 491 do_check_null(error);
michael@0 492 do_check_eq(request1.response.status, 200);
michael@0 493
michael@0 494 let request2 = localRequest(server, "/2.0/123/storage/testcoll",
michael@0 495 "123", "password");
michael@0 496 request2.setHeader("X-If-Unmodified-Since", serverModified - 1);
michael@0 497 let error = doGetRequest(request2);
michael@0 498 do_check_null(error);
michael@0 499 do_check_eq(request2.response.status, 412);
michael@0 500
michael@0 501 server.stop(run_next_test);
michael@0 502 });
michael@0 503
michael@0 504 add_test(function test_bso_get_unmodified_since() {
michael@0 505 _("Ensure conditional unmodified get on BSO works appropriately.");
michael@0 506
michael@0 507 let server = new StorageServer();
michael@0 508 server.registerUser("123", "password");
michael@0 509 server.startSynchronous();
michael@0 510 let collection = server.user("123").createCollection("testcoll");
michael@0 511 let bso = collection.insert("bso0", {foo: "bar"});
michael@0 512
michael@0 513 let serverModified = bso.modified;
michael@0 514
michael@0 515 let request1 = localRequest(server, "/2.0/123/storage/testcoll/bso0",
michael@0 516 "123", "password");
michael@0 517 request1.setHeader("X-If-Unmodified-Since", serverModified);
michael@0 518 let error = doGetRequest(request1);
michael@0 519 do_check_null(error);
michael@0 520 do_check_eq(request1.response.status, 200);
michael@0 521
michael@0 522 let request2 = localRequest(server, "/2.0/123/storage/testcoll/bso0",
michael@0 523 "123", "password");
michael@0 524 request2.setHeader("X-If-Unmodified-Since", serverModified - 1);
michael@0 525 let error = doGetRequest(request2);
michael@0 526 do_check_null(error);
michael@0 527 do_check_eq(request2.response.status, 412);
michael@0 528
michael@0 529 server.stop(run_next_test);
michael@0 530 });
michael@0 531
michael@0 532 add_test(function test_missing_collection_404() {
michael@0 533 _("Ensure a missing collection returns a 404.");
michael@0 534
michael@0 535 let server = new StorageServer();
michael@0 536 server.registerUser("123", "password");
michael@0 537 server.startSynchronous();
michael@0 538
michael@0 539 let request = localRequest(server, "/2.0/123/storage/none", "123", "password");
michael@0 540 let error = doGetRequest(request);
michael@0 541 do_check_eq(error, null);
michael@0 542 do_check_eq(request.response.status, 404);
michael@0 543 do_check_false("content-type" in request.response.headers);
michael@0 544
michael@0 545 server.stop(run_next_test);
michael@0 546 });
michael@0 547
michael@0 548 add_test(function test_get_storage_405() {
michael@0 549 _("Ensure that a GET on /storage results in a 405.");
michael@0 550
michael@0 551 let server = new StorageServer();
michael@0 552 server.registerUser("123", "password");
michael@0 553 server.startSynchronous();
michael@0 554
michael@0 555 let request = localRequest(server, "/2.0/123/storage", "123", "password");
michael@0 556 let error = doGetRequest(request);
michael@0 557 do_check_eq(error, null);
michael@0 558 do_check_eq(request.response.status, 405);
michael@0 559 do_check_eq(request.response.headers["allow"], "DELETE");
michael@0 560
michael@0 561 server.stop(run_next_test);
michael@0 562 });
michael@0 563
michael@0 564 add_test(function test_delete_storage() {
michael@0 565 _("Ensure that deleting all of storage works.");
michael@0 566
michael@0 567 let server = new StorageServer();
michael@0 568 server.registerUser("123", "password");
michael@0 569 server.createContents("123", {
michael@0 570 foo: {a: {foo: "bar"}, b: {bar: "foo"}},
michael@0 571 baz: {c: {bob: "law"}, blah: {law: "blog"}}
michael@0 572 });
michael@0 573
michael@0 574 server.startSynchronous();
michael@0 575
michael@0 576 let request = localRequest(server, "/2.0/123/storage", "123", "password");
michael@0 577 let error = doDeleteRequest(request);
michael@0 578 do_check_eq(error, null);
michael@0 579 do_check_eq(request.response.status, 204);
michael@0 580 do_check_attribute_count(server.users["123"].collections, 0);
michael@0 581
michael@0 582 server.stop(run_next_test);
michael@0 583 });
michael@0 584
michael@0 585 add_test(function test_x_num_records() {
michael@0 586 let server = new StorageServer();
michael@0 587 server.registerUser("123", "password");
michael@0 588
michael@0 589 server.createContents("123", {
michael@0 590 crypto: {foos: {foo: "bar"},
michael@0 591 bars: {foo: "baz"}}
michael@0 592 });
michael@0 593 server.startSynchronous();
michael@0 594 let bso = localRequest(server, "/2.0/123/storage/crypto/foos");
michael@0 595 bso.get(function (err) {
michael@0 596 // BSO fetches don't have one.
michael@0 597 do_check_false("x-num-records" in this.response.headers);
michael@0 598 let col = localRequest(server, "/2.0/123/storage/crypto");
michael@0 599 col.get(function (err) {
michael@0 600 // Collection fetches do.
michael@0 601 do_check_eq(this.response.headers["x-num-records"], "2");
michael@0 602 server.stop(run_next_test);
michael@0 603 });
michael@0 604 });
michael@0 605 });
michael@0 606
michael@0 607 add_test(function test_put_delete_put() {
michael@0 608 _("Bug 790397: Ensure BSO deleted flag is reset on PUT.");
michael@0 609
michael@0 610 let server = new StorageServer();
michael@0 611 server.registerUser("123", "password");
michael@0 612 server.createContents("123", {
michael@0 613 test: {bso: {foo: "bar"}}
michael@0 614 });
michael@0 615 server.startSynchronous();
michael@0 616
michael@0 617 _("Ensure we can PUT an existing record.");
michael@0 618 let request1 = localRequest(server, "/2.0/123/storage/test/bso", "123", "password");
michael@0 619 request1.setHeader("Content-Type", "application/json");
michael@0 620 let payload1 = JSON.stringify({"payload": "foobar"});
michael@0 621 let error1 = doPutRequest(request1, payload1);
michael@0 622 do_check_eq(null, error1);
michael@0 623 do_check_eq(request1.response.status, 204);
michael@0 624
michael@0 625 _("Ensure we can DELETE it.");
michael@0 626 let request2 = localRequest(server, "/2.0/123/storage/test/bso", "123", "password");
michael@0 627 let error2 = doDeleteRequest(request2);
michael@0 628 do_check_eq(error2, null);
michael@0 629 do_check_eq(request2.response.status, 204);
michael@0 630 do_check_false("content-type" in request2.response.headers);
michael@0 631
michael@0 632 _("Ensure we can PUT a previously deleted record.");
michael@0 633 let request3 = localRequest(server, "/2.0/123/storage/test/bso", "123", "password");
michael@0 634 request3.setHeader("Content-Type", "application/json");
michael@0 635 let payload3 = JSON.stringify({"payload": "foobar"});
michael@0 636 let error3 = doPutRequest(request3, payload3);
michael@0 637 do_check_eq(null, error3);
michael@0 638 do_check_eq(request3.response.status, 201);
michael@0 639
michael@0 640 _("Ensure we can GET the re-uploaded record.");
michael@0 641 let request4 = localRequest(server, "/2.0/123/storage/test/bso", "123", "password");
michael@0 642 let error4 = doGetRequest(request4);
michael@0 643 do_check_eq(error4, null);
michael@0 644 do_check_eq(request4.response.status, 200);
michael@0 645 do_check_eq(request4.response.headers["content-type"], "application/json");
michael@0 646
michael@0 647 server.stop(run_next_test);
michael@0 648 });
michael@0 649
michael@0 650 add_test(function test_collection_get_newer() {
michael@0 651 _("Ensure get with newer argument on collection works.");
michael@0 652
michael@0 653 let server = new StorageServer();
michael@0 654 server.registerUser("123", "password");
michael@0 655 server.startSynchronous();
michael@0 656
michael@0 657 let coll = server.user("123").createCollection("test");
michael@0 658 let bso1 = coll.insert("001", {foo: "bar"});
michael@0 659 let bso2 = coll.insert("002", {bar: "foo"});
michael@0 660
michael@0 661 // Don't want both records to have the same timestamp.
michael@0 662 bso2.modified = bso1.modified + 1000;
michael@0 663
michael@0 664 function newerRequest(newer) {
michael@0 665 return localRequest(server, "/2.0/123/storage/test?newer=" + newer,
michael@0 666 "123", "password");
michael@0 667 }
michael@0 668
michael@0 669 let request1 = newerRequest(0);
michael@0 670 let error1 = doGetRequest(request1);
michael@0 671 do_check_null(error1);
michael@0 672 do_check_eq(request1.response.status, 200);
michael@0 673 let items1 = JSON.parse(request1.response.body).items;
michael@0 674 do_check_attribute_count(items1, 2);
michael@0 675
michael@0 676 let request2 = newerRequest(bso1.modified + 1);
michael@0 677 let error2 = doGetRequest(request2);
michael@0 678 do_check_null(error2);
michael@0 679 do_check_eq(request2.response.status, 200);
michael@0 680 let items2 = JSON.parse(request2.response.body).items;
michael@0 681 do_check_attribute_count(items2, 1);
michael@0 682
michael@0 683 let request3 = newerRequest(bso2.modified + 1);
michael@0 684 let error3 = doGetRequest(request3);
michael@0 685 do_check_null(error3);
michael@0 686 do_check_eq(request3.response.status, 200);
michael@0 687 let items3 = JSON.parse(request3.response.body).items;
michael@0 688 do_check_attribute_count(items3, 0);
michael@0 689
michael@0 690 server.stop(run_next_test);
michael@0 691 });

mercurial