зеркало из https://github.com/mozilla/gecko-dev.git
Bug 693864 - Implement /storage DELETE handling in test JS Sync server. r=philikon
This commit is contained in:
Родитель
315945275a
Коммит
5f005e7509
|
@ -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);
|
||||
}))));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче