Bug 693864 - Implement /storage DELETE handling in test JS Sync server. r=philikon

This commit is contained in:
Richard Newman 2011-10-12 13:57:39 -07:00
Родитель 315945275a
Коммит 5f005e7509
2 изменённых файлов: 111 добавлений и 11 удалений

Просмотреть файл

@ -710,6 +710,27 @@ SyncServer.prototype = {
return wbo;
},
/**
* Delete all of the collections for the named user.
*
* @param username
* The name of the affected user.
*
* @return a timestamp.
*/
deleteCollections: function deleteCollections(username) {
if (!(username in this.users)) {
throw new Error("Unknown user.");
}
let userCollections = this.users[username].collections;
for each (let [name, coll] in Iterator(userCollections)) {
this._log.trace("Bulk deleting " + name + " for " + username + "...");
coll.delete({});
}
this.users[username].collections = {};
return this.timestamp();
},
/**
* Simple accessor to allow collective binding and abbreviation of a bunch of
* methods. Yay!
@ -727,11 +748,13 @@ SyncServer.prototype = {
let modified = function (collectionName) {
return collection(collectionName).timestamp;
}
let deleteCollections = this.deleteCollections.bind(this, username);
return {
collection: collection,
createCollection: createCollection,
createContents: createContents,
modified: modified
collection: collection,
createCollection: createCollection,
createContents: createContents,
deleteCollections: deleteCollections,
modified: modified
};
},
@ -752,9 +775,9 @@ SyncServer.prototype = {
* server code.
*
* Path: [all, version, username, first, rest]
* Storage: [all, collection, id?]
* Storage: [all, collection?, id?]
*/
pathRE: /^\/([0-9]+(?:\.[0-9]+)?)\/([-._a-zA-Z0-9]+)\/([^\/]+)\/(.*)$/,
pathRE: /^\/([0-9]+(?:\.[0-9]+)?)\/([-._a-zA-Z0-9]+)(?:\/([^\/]+)(?:\/(.+))?)?$/,
storageRE: /^([-_a-zA-Z0-9]+)(?:\/([-_a-zA-Z0-9]+)\/?)?$/,
defaultHeaders: {},
@ -826,6 +849,25 @@ SyncServer.prototype = {
*/
toplevelHandlers: {
"storage": function handleStorage(handler, req, resp, version, username, rest) {
let respond = this.respond.bind(this, req, resp);
if (!rest || !rest.length) {
this._log.debug("SyncServer: top-level storage " +
req.method + " request.");
// TODO: verify if this is spec-compliant.
if (req.method != "DELETE") {
respond(405, "Method Not Allowed", "[]", {"Allow": "DELETE"});
return;
}
// Delete all collections and track the timestamp for the response.
let timestamp = this.user(username).deleteCollections();
// Return timestamp and OK for deletion.
respond(200, "OK", JSON.stringify(timestamp));
return;
}
let match = this.storageRE.exec(rest);
if (!match) {
this._log.warn("SyncServer: Unknown storage operation " + rest);
@ -833,7 +875,6 @@ SyncServer.prototype = {
}
let [all, collection, wboID] = match;
let coll = this.getCollection(username, collection);
let respond = this.respond.bind(this, req, resp);
switch (req.method) {
case "GET":
if (!coll) {

Просмотреть файл

@ -1,4 +1,6 @@
function run_test() {
Log4Moz.repository.getLogger("Sync.Test.Server").level = Log4Moz.Level.Trace;
initTestLogging();
run_next_test();
}
@ -16,13 +18,44 @@ add_test(function test_creation() {
add_test(function test_url_parsing() {
let s = new SyncServer();
// Check that we can parse a WBO URI.
let parts = s.pathRE.exec("/1.1/johnsmith/storage/crypto/keys");
let [all, version, username, first, rest] = parts;
do_check_eq(all, "/1.1/johnsmith/storage/crypto/keys");
do_check_eq(version, "1.1");
do_check_eq(username, "johnsmith");
do_check_eq(first, "storage");
do_check_eq(rest, "crypto/keys");
do_check_eq(null, s.pathRE.exec("/nothing/else"));
// Check that we can parse a collection URI.
parts = s.pathRE.exec("/1.1/johnsmith/storage/crypto");
let [all, version, username, first, rest] = parts;
do_check_eq(all, "/1.1/johnsmith/storage/crypto");
do_check_eq(version, "1.1");
do_check_eq(username, "johnsmith");
do_check_eq(first, "storage");
do_check_eq(rest, "crypto");
// We don't allow trailing slash on storage URI.
parts = s.pathRE.exec("/1.1/johnsmith/storage/");
do_check_eq(parts, undefined);
// storage alone is a valid request.
parts = s.pathRE.exec("/1.1/johnsmith/storage");
let [all, version, username, first, rest] = parts;
do_check_eq(all, "/1.1/johnsmith/storage");
do_check_eq(version, "1.1");
do_check_eq(username, "johnsmith");
do_check_eq(first, "storage");
do_check_eq(rest, undefined);
parts = s.storageRE.exec("storage");
let [all, storage, collection, id] = parts;
do_check_eq(all, "storage");
do_check_eq(collection, undefined);
run_next_test();
});
@ -109,6 +142,8 @@ add_test(function test_info_collections() {
add_test(function test_storage_request() {
let keysURL = "/1.1/john/storage/crypto/keys?foo=bar";
let foosURL = "/1.1/john/storage/crypto/foos";
let storageURL = "/1.1/john/storage";
let s = new SyncServer();
let creation = s.timestamp();
s.registerUser("john", "password");
@ -145,12 +180,36 @@ add_test(function test_storage_request() {
Utils.nextTick(next);
});
}
function deleteStorage(next) {
_("Testing DELETE on /storage.");
let now = s.timestamp();
_("Timestamp: " + now);
let req = localRequest(storageURL);
req.delete(function (err) {
_("Body is " + this.response.body);
_("Modified is " + this.response.newModified);
let parsedBody = JSON.parse(this.response.body);
do_check_true(parsedBody >= now);
do_check_empty(s.users["john"].collections);
Utils.nextTick(next);
});
}
function getStorageFails(next) {
_("Testing that GET on /storage fails.");
let req = localRequest(storageURL);
req.get(function (err) {
do_check_eq(this.response.status, 405);
do_check_eq(this.response.headers["allow"], "DELETE");
Utils.nextTick(next);
});
}
s.start(8080, function () {
retrieveWBONotExists(
retrieveWBOExists.bind(this, function () {
s.stop(run_next_test);
})
);
retrieveWBOExists.bind(this,
getStorageFails.bind(this,
deleteStorage.bind(this, function () {
s.stop(run_next_test);
}))));
});
});