Bug 669913 - Viewing Sync quota blocks the entire Options window. r=rnewman

Part 1: Implement Service.getStorageInfo as an async method using RESTRequest.

--HG--
rename : services/sync/tests/unit/test_service_quota.js => services/sync/tests/unit/test_service_getStorageInfo.js
This commit is contained in:
Philipp von Weitershausen 2011-07-14 12:11:42 -07:00
parent e7c4344a1a
commit 8c873ad9c4
5 changed files with 144 additions and 55 deletions

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Dan Mills <thunder@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
* Richard Newman <rnewman@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
@ -196,6 +197,12 @@ JPAKE_ERROR_KEYMISMATCH: "jpake.error.keymismatch",
JPAKE_ERROR_WRONGMESSAGE: "jpake.error.wrongmessage",
JPAKE_ERROR_USERABORT: "jpake.error.userabort",
// info types for Service.getStorageInfo
INFO_COLLECTIONS: "collections",
INFO_COLLECTION_USAGE: "collection_usage",
INFO_COLLECTION_COUNTS: "collection_counts",
INFO_QUOTA: "quota",
// Ways that a sync can be disabled (messages only to be printed in debug log)
kSyncMasterPasswordLocked: "User elected to leave Master Password locked",
kSyncWeaveDisabled: "Weave is disabled",

View File

@ -21,6 +21,7 @@
* Dan Mills <thunder@mozilla.com>
* Myk Melez <myk@mozilla.org>
* Anant Narayanan <anant@kix.in>
* Philipp von Weitershausen <philipp@weitershausen.de>
* Richard Newman <rnewman@mozilla.com>
* Marina Samuel <msamuel@mozilla.com>
*
@ -66,11 +67,17 @@ Cu.import("resource://services-sync/ext/Preferences.js");
Cu.import("resource://services-sync/identity.js");
Cu.import("resource://services-sync/log4moz.js");
Cu.import("resource://services-sync/resource.js");
Cu.import("resource://services-sync/rest.js");
Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/main.js");
const STORAGE_INFO_TYPES = [INFO_COLLECTIONS,
INFO_COLLECTION_USAGE,
INFO_COLLECTION_COUNTS,
INFO_QUOTA];
/*
* Service singleton
* Main entry point into Weave's sync framework
@ -1978,19 +1985,53 @@ WeaveSvc.prototype = {
Clients.sendCommand(command, args);
},
_getInfo: function _getInfo(what)
this._catch(this._notify(what, "", function() {
let url = this.userBaseURL + "info/" + what;
let response = new Resource(url).get();
if (response.status != 200)
return null;
return response.obj;
}))(),
/**
* Fetch storage info from the server.
*
* @param type
* String specifying what info to fetch from the server. Must be one
* of the INFO_* values. See Sync Storage Server API spec for details.
* @param callback
* Callback function with signature (error, data) where `data' is
* the return value from the server already parsed as JSON.
*
* @return RESTRequest instance representing the request, allowing callers
* to cancel the request.
*/
getStorageInfo: function getStorageInfo(type, callback) {
if (STORAGE_INFO_TYPES.indexOf(type) == -1) {
throw "Invalid value for 'type': " + type;
}
getCollectionUsage: function getCollectionUsage()
this._getInfo("collection_usage"),
let info_type = "info/" + type;
this._log.trace("Retrieving '" + info_type + "'...");
let url = this.userBaseURL + info_type;
return new SyncStorageRequest(url).get(function onComplete(error) {
// Note: 'this' is the request.
if (error) {
this._log.debug("Failed to retrieve '" + info_type + "': " +
Utils.exceptionStr(error));
return callback(error);
}
if (this.response.status != 200) {
this._log.debug("Failed to retrieve '" + info_type +
"': server responded with HTTP" +
this.response.status);
return callback(this.response);
}
getQuota: function getQuota() this._getInfo("quota")
let result;
try {
result = JSON.parse(this.response.body);
} catch (ex) {
this._log.debug("Server returned invalid JSON for '" + info_type +
"': " + this.response.body);
return callback(ex);
}
this._log.trace("Successfully retrieved '" + info_type + "'.");
return callback(null, result);
});
}
};

View File

@ -0,0 +1,84 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/rest.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/util.js");
let collections = {steam: 65.11328,
petrol: 82.488281,
diesel: 2.25488281};
function run_test() {
Service.username = "johndoe";
Service.password = "ilovejane";
Service.clusterURL = "http://localhost:8080/";
Log4Moz.repository.getLogger("Sync.Service").level = Log4Moz.Level.Trace;
Log4Moz.repository.getLogger("Sync.StorageRequest").level = Log4Moz.Level.Trace;
initTestLogging();
run_next_test();
}
add_test(function test_success() {
let handler = httpd_handler(200, "OK", JSON.stringify(collections));
let server = httpd_setup({"/1.1/johndoe/info/collections": handler});
let request = Service.getStorageInfo("collections", function (error, info) {
do_check_eq(error, null);
do_check_true(Utils.deepEquals(info, collections));
// Ensure that the request is sent off with the right bits.
do_check_true(basic_auth_matches(handler.request, Service.username,
Service.password));
let expectedUA = Services.appinfo.name + "/" + Services.appinfo.version +
" FxSync/" + WEAVE_VERSION + "." +
Services.appinfo.appBuildID + ".desktop";
do_check_eq(handler.request.getHeader("User-Agent"), expectedUA);
server.stop(run_next_test);
});
do_check_true(request instanceof RESTRequest);
});
add_test(function test_invalid_type() {
do_check_throws(function () {
Service.getStorageInfo("invalid", function (error, info) {
do_throw("Shouldn't get here!");
});
});
run_next_test();
});
add_test(function test_network_error() {
Service.getStorageInfo(INFO_COLLECTIONS, function (error, info) {
do_check_eq(error.result, Cr.NS_ERROR_CONNECTION_REFUSED);
do_check_eq(info, null);
run_next_test();
});
});
add_test(function test_http_error() {
let handler = httpd_handler(500, "Oh noez", "Something went wrong!");
let server = httpd_setup({"/1.1/johndoe/info/collections": handler});
let request = Service.getStorageInfo(INFO_COLLECTIONS, function (error, info) {
do_check_eq(error.status, 500);
do_check_eq(info, null);
server.stop(run_next_test);
});
});
add_test(function test_invalid_json() {
let handler = httpd_handler(200, "OK", "Invalid JSON");
let server = httpd_setup({"/1.1/johndoe/info/collections": handler});
let request = Service.getStorageInfo(INFO_COLLECTIONS, function (error, info) {
do_check_eq(error.name, "SyntaxError");
do_check_eq(error.message, "JSON.parse: unexpected character");
do_check_eq(info, null);
server.stop(run_next_test);
});
});

View File

@ -1,43 +0,0 @@
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/util.js");
function run_test() {
let collection_usage = {steam: 65.11328,
petrol: 82.488281,
diesel: 2.25488281};
let quota = [2169.65136, 8192];
do_test_pending();
let server = httpd_setup({
"/1.1/johndoe/info/collection_usage": httpd_handler(200, "OK", JSON.stringify(collection_usage)),
"/1.1/johndoe/info/quota": httpd_handler(200, "OK", JSON.stringify(quota)),
"/1.1/janedoe/info/collection_usage": httpd_handler(200, "OK", "gargabe"),
"/1.1/janedoe/info/quota": httpd_handler(200, "OK", "more garbage")
});
try {
Weave.Service.clusterURL = "http://localhost:8080/";
Weave.Service.username = "johndoe";
_("Test getCollectionUsage().");
let res = Weave.Service.getCollectionUsage();
do_check_true(Utils.deepEquals(res, collection_usage));
_("Test getQuota().");
res = Weave.Service.getQuota();
do_check_true(Utils.deepEquals(res, quota));
_("Both return 'null' for non-200 responses.");
Weave.Service.username = "nonexistent";
do_check_eq(Weave.Service.getCollectionUsage(), null);
do_check_eq(Weave.Service.getQuota(), null);
_("Both return nothing (undefined) if the return value can't be parsed.");
Weave.Service.username = "janedoe";
do_check_eq(Weave.Service.getCollectionUsage(), undefined);
do_check_eq(Weave.Service.getQuota(), undefined);
} finally {
server.stop(do_test_finished);
}
}

View File

@ -61,11 +61,11 @@ skip-if = os == "win"
[test_service_filelog.js]
# Bug 664090: this test persistently fails on Windows opt builds.
skip-if = os == "win" && !debug
[test_service_getStorageInfo.js]
[test_service_login.js]
[test_service_migratePrefs.js]
[test_service_passwordUTF8.js]
[test_service_persistLogin.js]
[test_service_quota.js]
[test_service_startOver.js]
[test_service_startup.js]
[test_service_sync_401.js]