mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Merge m-c to inbound.
This commit is contained in:
commit
8b9c9fea4d
@ -16,7 +16,6 @@ let gSyncUI = {
|
||||
"weave:ui:sync:error",
|
||||
"weave:ui:sync:finish",
|
||||
"weave:ui:clear-error",
|
||||
"weave:engine:clients:display-uri",
|
||||
],
|
||||
|
||||
_unloaded: false,
|
||||
@ -397,21 +396,6 @@ let gSyncUI = {
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
/**
|
||||
* Observer called when display URI command is received.
|
||||
*/
|
||||
onDisplayURI: function onDisplayURI(data) {
|
||||
if (!gBrowser) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
gBrowser.addTab(data.wrappedJSObject.object.uri);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Error displaying tab received by Sync: " + ex);
|
||||
}
|
||||
},
|
||||
|
||||
observe: function SUI_observe(subject, topic, data) {
|
||||
if (this._unloaded) {
|
||||
Cu.reportError("SyncUI observer called after unload: " + topic);
|
||||
@ -461,9 +445,6 @@ let gSyncUI = {
|
||||
case "weave:ui:clear-error":
|
||||
this.clearError();
|
||||
break;
|
||||
case "weave:engine:clients:display-uri":
|
||||
this.onDisplayURI(subject);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -182,6 +182,9 @@ BrowserGlue.prototype = {
|
||||
case "weave:service:ready":
|
||||
this._setSyncAutoconnectDelay();
|
||||
break;
|
||||
case "weave:engine:clients:display-uri":
|
||||
this._onDisplaySyncURI(subject);
|
||||
break;
|
||||
#endif
|
||||
case "session-save":
|
||||
this._setPrefToSaveSession(true);
|
||||
@ -265,6 +268,7 @@ BrowserGlue.prototype = {
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
os.addObserver(this, "weave:service:ready", false);
|
||||
os.addObserver(this, "weave:engine:clients:display-uri", false);
|
||||
#endif
|
||||
os.addObserver(this, "session-save", false);
|
||||
os.addObserver(this, "places-init-complete", false);
|
||||
@ -292,6 +296,7 @@ BrowserGlue.prototype = {
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
os.removeObserver(this, "weave:service:ready", false);
|
||||
os.removeObserver(this, "weave:engine:clients:display-uri", false);
|
||||
#endif
|
||||
os.removeObserver(this, "session-save");
|
||||
if (this._isIdleObserver)
|
||||
@ -1507,6 +1512,29 @@ BrowserGlue.prototype = {
|
||||
#endif
|
||||
},
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
/**
|
||||
* Called as an observer when Sync's "display URI" notification is fired.
|
||||
*
|
||||
* We open the received URI in a background tab.
|
||||
*
|
||||
* Eventually, this will likely be replaced by a more robust tab syncing
|
||||
* feature. This functionality is considered somewhat evil by UX because it
|
||||
* opens a new tab automatically without any prompting. However, it is a
|
||||
* lesser evil than sending a tab to a specific device (from e.g. Fennec)
|
||||
* and having nothing happen on the receiving end.
|
||||
*/
|
||||
_onDisplaySyncURI: function _onDisplaySyncURI(data) {
|
||||
try {
|
||||
let tabbrowser = this.getMostRecentBrowserWindow().gBrowser;
|
||||
|
||||
// The payload is wrapped weirdly because of how Sync does notifications.
|
||||
tabbrowser.addTab(data.wrappedJSObject.object.uri);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Error displaying tab received by Sync: " + ex);
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
// for XPCOM
|
||||
classID: Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
|
||||
|
@ -133,24 +133,15 @@ nsDOMMutationRecord::GetOldValue(nsAString& aPrevValue)
|
||||
|
||||
// Observer
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsMutationReceiver)
|
||||
NS_IMPL_ADDREF(nsMutationReceiver)
|
||||
NS_IMPL_RELEASE(nsMutationReceiver)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsMutationReceiver)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsMutationReceiver)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsMutationReceiver)
|
||||
NS_INTERFACE_MAP_BEGIN(nsMutationReceiver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsMutationReceiver)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsMutationReceiver)
|
||||
tmp->Disconnect(false);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsMutationReceiver)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
void
|
||||
nsMutationReceiver::Disconnect(bool aRemoveFromObserver)
|
||||
{
|
||||
|
@ -265,8 +265,7 @@ public:
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMUTATION_OBSERVER_IID)
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsMutationReceiver)
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE
|
||||
|
@ -69,9 +69,6 @@ nsDOMParser::ParseFromString(const PRUnichar *str,
|
||||
rv = SetUpDocument(DocumentFlavorHTML, getter_AddRefs(domDocument));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
|
||||
nsDependentString sourceBuffer(str);
|
||||
rv = nsContentUtils::ParseDocumentHTML(sourceBuffer, document, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Keep the XULXBL state, base URL and principal setting in sync with the
|
||||
// XML case
|
||||
@ -85,6 +82,10 @@ nsDOMParser::ParseFromString(const PRUnichar *str,
|
||||
// And the right principal
|
||||
document->SetPrincipal(mPrincipal);
|
||||
|
||||
nsDependentString sourceBuffer(str);
|
||||
rv = nsContentUtils::ParseDocumentHTML(sourceBuffer, document, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
domDocument.forget(aResult);
|
||||
return rv;
|
||||
}
|
||||
|
@ -143,6 +143,10 @@ let DOMApplicationRegistry = {
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
// nsIPrefBranch throws if pref does not exist, faster to simply write
|
||||
// the pref instead of first checking if it is false.
|
||||
Services.prefs.setBoolPref("dom.mozApps.used", true);
|
||||
|
||||
let msg = aMessage.json;
|
||||
|
||||
switch (aMessage.name) {
|
||||
|
@ -1603,7 +1603,7 @@ nsEditor::RemoveContainer(nsINode* aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsINode* parent = aNode->GetNodeParent();
|
||||
nsCOMPtr<nsINode> parent = aNode->GetNodeParent();
|
||||
NS_ENSURE_STATE(parent);
|
||||
|
||||
PRInt32 offset = parent->IndexOf(aNode);
|
||||
@ -1616,7 +1616,7 @@ nsEditor::RemoveContainer(nsINode* aNode)
|
||||
nsAutoRemoveContainerSelNotify selNotify(mRangeUpdater, aNode, parent, offset, nodeOrigLen);
|
||||
|
||||
while (aNode->HasChildren()) {
|
||||
nsIContent* child = aNode->GetLastChild();
|
||||
nsCOMPtr<nsIContent> child = aNode->GetLastChild();
|
||||
nsresult rv = DeleteNode(child->AsDOMNode());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
$(warning httpserver XPI_NAME=$(XPI_NAME))
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = netwerk/test/httpserver
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
@ -36,4 +36,6 @@ XPIDLSRCS = \
|
||||
|
||||
XPCSHELL_TESTS = test
|
||||
|
||||
TESTING_JS_MODULES = httpd.js
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -10,6 +10,34 @@
|
||||
* httpd.js.
|
||||
*/
|
||||
|
||||
const EXPORTED_SYMBOLS = [
|
||||
"HTTP_400",
|
||||
"HTTP_401",
|
||||
"HTTP_402",
|
||||
"HTTP_403",
|
||||
"HTTP_404",
|
||||
"HTTP_405",
|
||||
"HTTP_406",
|
||||
"HTTP_407",
|
||||
"HTTP_408",
|
||||
"HTTP_409",
|
||||
"HTTP_410",
|
||||
"HTTP_411",
|
||||
"HTTP_412",
|
||||
"HTTP_413",
|
||||
"HTTP_414",
|
||||
"HTTP_415",
|
||||
"HTTP_417",
|
||||
"HTTP_500",
|
||||
"HTTP_501",
|
||||
"HTTP_502",
|
||||
"HTTP_503",
|
||||
"HTTP_504",
|
||||
"HTTP_505",
|
||||
"HttpError",
|
||||
"HttpServer",
|
||||
];
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
@ -762,7 +790,7 @@ nsHttpServer.prototype =
|
||||
// Bug 508125: Add a GC here else we'll use gigabytes of memory running
|
||||
// mochitests. We can't rely on xpcshell doing an automated GC, as that
|
||||
// would interfere with testing GC stuff...
|
||||
gc();
|
||||
Components.utils.forceGC();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -776,6 +804,7 @@ nsHttpServer.prototype =
|
||||
}
|
||||
};
|
||||
|
||||
var HttpServer = nsHttpServer;
|
||||
|
||||
//
|
||||
// RFC 2396 section 3.2.2:
|
||||
|
16
netwerk/test/httpserver/test/test_load_module.js
Normal file
16
netwerk/test/httpserver/test/test_load_module.js
Normal file
@ -0,0 +1,16 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Ensure httpd.js can be imported as a module and that a server starts.
|
||||
*/
|
||||
function run_test() {
|
||||
Components.utils.import("resource://testing-common/httpd.js");
|
||||
|
||||
let server = new HttpServer();
|
||||
server.start(8080);
|
||||
|
||||
do_test_pending();
|
||||
|
||||
server.stop(do_test_finished);
|
||||
}
|
@ -14,6 +14,7 @@ tail =
|
||||
[test_headers.js]
|
||||
[test_host.js]
|
||||
[test_linedata.js]
|
||||
[test_load_module.js]
|
||||
[test_name_scheme.js]
|
||||
[test_processasync.js]
|
||||
[test_qi.js]
|
||||
|
@ -8,9 +8,9 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
|
||||
function AitcService() {
|
||||
this.aitc = null;
|
||||
@ -20,7 +20,6 @@ AitcService.prototype = {
|
||||
classID: Components.ID("{a3d387ca-fd26-44ca-93be-adb5fda5a78d}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsINavHistoryObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
observe: function observe(subject, topic, data) {
|
||||
@ -34,7 +33,6 @@ AitcService.prototype = {
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
|
||||
// Don't start AITC if classic sync is on.
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
if (Preferences.get("services.sync.engine.apps", false)) {
|
||||
return;
|
||||
}
|
||||
@ -43,43 +41,32 @@ AitcService.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start AITC service if apps.enabled is true. If false, we look
|
||||
// in the browser history to determine if they're an "apps user". If
|
||||
// an entry wasn't found, we'll watch for navigation to either the
|
||||
// marketplace or dashboard and switch ourselves on then.
|
||||
|
||||
if (Preferences.get("apps.enabled", false)) {
|
||||
this.start();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set commonly used URLs.
|
||||
this.DASHBOARD_URL = CommonUtils.makeURI(
|
||||
Preferences.get("services.aitc.dashboard.url")
|
||||
);
|
||||
this.MARKETPLACE_URL = CommonUtils.makeURI(
|
||||
Preferences.get("services.aitc.marketplace.url")
|
||||
);
|
||||
|
||||
if (this.hasUsedApps()) {
|
||||
Preferences.set("apps.enabled", true);
|
||||
// Start AITC service only if apps.enabled is true. If false, setup
|
||||
// an observer in case the value changes as a result of an access to
|
||||
// the DOM API.
|
||||
if (Preferences.get("dom.mozApps.used", false)) {
|
||||
this.start();
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait and see if the user wants anything apps related.
|
||||
PlacesUtils.history.addObserver(this, true);
|
||||
Preferences.observe("dom.mozApps.used", function checkIfEnabled() {
|
||||
if (Preferences.get("dom.mozApps.used", false)) {
|
||||
Preferences.ignore("dom.mozApps.used", checkIfEnabled, this);
|
||||
this.start();
|
||||
}
|
||||
}, this);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
start: function start() {
|
||||
Cu.import("resource://services-aitc/main.js");
|
||||
if (this.aitc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Log to stdout if enabled.
|
||||
Cu.import("resource://services-aitc/main.js");
|
||||
Cu.import("resource://services-common/log4moz.js");
|
||||
let root = Log4Moz.repository.getLogger("Service.AITC");
|
||||
root.level = Log4Moz.Level[Preferences.get("services.aitc.log.level")];
|
||||
@ -87,44 +74,31 @@ AitcService.prototype = {
|
||||
root.addAppender(new Log4Moz.DumpAppender());
|
||||
}
|
||||
this.aitc = new Aitc();
|
||||
Services.obs.notifyObservers(null, "service:aitc:started", null);
|
||||
},
|
||||
|
||||
hasUsedApps: function hasUsedApps() {
|
||||
// There is no easy way to determine whether a user is "using apps".
|
||||
// The best we can do right now is to see if they have visited either
|
||||
// the Mozilla dashboard or Marketplace. See bug 760898.
|
||||
let gh = PlacesUtils.ghistory2;
|
||||
if (gh.isVisited(this.DASHBOARD_URL)) {
|
||||
return true;
|
||||
}
|
||||
if (gh.isVisited(this.MARKETPLACE_URL)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// nsINavHistoryObserver. We are only interested in onVisit().
|
||||
onBeforeDeleteURI: function() {},
|
||||
onBeginUpdateBatch: function() {},
|
||||
onClearHistory: function() {},
|
||||
onDeleteURI: function() {},
|
||||
onDeleteVisits: function() {},
|
||||
onEndUpdateBatch: function() {},
|
||||
onPageChanged: function() {},
|
||||
onPageExpired: function() {},
|
||||
onTitleChanged: function() {},
|
||||
|
||||
onVisit: function onVisit(uri) {
|
||||
if (!uri.equals(this.MARKETPLACE_URL) && !uri.equals(this.DASHBOARD_URL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlacesUtils.history.removeObserver(this);
|
||||
Preferences.set("apps.enabled", true);
|
||||
this.start();
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
const components = [AitcService];
|
||||
function AboutApps() {
|
||||
}
|
||||
AboutApps.prototype = {
|
||||
classID: Components.ID("{1de7cbe8-60f1-493e-b56b-9d099b3c018e}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIAboutModule]),
|
||||
|
||||
getURIFlags: function(aURI) {
|
||||
return Ci.nsIAboutModule.ALLOW_SCRIPT;
|
||||
},
|
||||
|
||||
newChannel: function(aURI) {
|
||||
let channel = Services.io.newChannel(
|
||||
Preferences.get("services.aitc.dashboard.url"), null, null
|
||||
);
|
||||
channel.originalURI = aURI;
|
||||
return channel;
|
||||
}
|
||||
};
|
||||
|
||||
const components = [AitcService, AboutApps];
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
|
||||
|
@ -2,5 +2,9 @@
|
||||
component {a3d387ca-fd26-44ca-93be-adb5fda5a78d} Aitc.js
|
||||
contract @mozilla.org/services/aitc;1 {a3d387ca-fd26-44ca-93be-adb5fda5a78d}
|
||||
category app-startup AitcService service,@mozilla.org/services/aitc;1
|
||||
|
||||
component {1de7cbe8-60f1-493e-b56b-9d099b3c018e} Aitc.js
|
||||
contract @mozilla.org/network/protocol/about;1?what=apps {1de7cbe8-60f1-493e-b56b-9d099b3c018e}
|
||||
|
||||
# Register resource aliases
|
||||
resource services-aitc resource:///modules/services-aitc/
|
||||
|
@ -16,6 +16,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://services-common/log4moz.js");
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
Cu.import("resource://services-common/rest.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
|
||||
/**
|
||||
* Provides a file-backed queue. Currently used by manager.js as persistent
|
||||
@ -43,23 +44,17 @@ function AitcQueue(filename, cb) {
|
||||
|
||||
this._queue = [];
|
||||
this._writeLock = false;
|
||||
this._file = FileUtils.getFile("ProfD", ["webapps", filename], true);
|
||||
this._filePath = "webapps/" + filename;
|
||||
|
||||
this._log.info("AitcQueue instance loading");
|
||||
|
||||
let self = this;
|
||||
if (this._file.exists()) {
|
||||
this._getFile(function gotFile(data) {
|
||||
if (data && Array.isArray(data)) {
|
||||
self._queue = data;
|
||||
}
|
||||
self._log.info("AitcQueue instance created");
|
||||
cb(true);
|
||||
});
|
||||
} else {
|
||||
self._log.info("AitcQueue instance created");
|
||||
CommonUtils.jsonLoad(this._filePath, this, function jsonLoaded(data) {
|
||||
if (data && Array.isArray(data)) {
|
||||
this._queue = data;
|
||||
}
|
||||
this._log.info("AitcQueue instance created");
|
||||
cb(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
AitcQueue.prototype = {
|
||||
/**
|
||||
@ -144,36 +139,6 @@ AitcQueue.prototype = {
|
||||
return this._queue.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get contents of cache file and parse it into an array. Will throw an
|
||||
* exception if there is an error while reading the file.
|
||||
*/
|
||||
_getFile: function _getFile(cb) {
|
||||
let channel = NetUtil.newChannel(this._file);
|
||||
channel.contentType = "application/json";
|
||||
|
||||
let self = this;
|
||||
NetUtil.asyncFetch(channel, function _asyncFetched(stream, res) {
|
||||
if (!Components.isSuccessCode(res)) {
|
||||
self._log.error("Could not read from json file " + this._file.path);
|
||||
cb(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = [];
|
||||
try {
|
||||
data = JSON.parse(
|
||||
NetUtil.readInputStreamToString(stream, stream.available())
|
||||
);
|
||||
stream.close();
|
||||
cb(data);
|
||||
} catch (e) {
|
||||
self._log.error("Could not parse JSON " + e);
|
||||
cb(null);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Put an array into the cache file. Will throw an exception if there is
|
||||
* an error while trying to write to the file.
|
||||
@ -184,32 +149,18 @@ AitcQueue.prototype = {
|
||||
}
|
||||
|
||||
this._writeLock = true;
|
||||
try {
|
||||
let ostream = FileUtils.openSafeFileOutputStream(this._file);
|
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let istream = converter.convertToInputStream(JSON.stringify(value));
|
||||
|
||||
// Asynchronously copy the data to the file.
|
||||
let self = this;
|
||||
this._log.info("Writing queue to disk");
|
||||
NetUtil.asyncCopy(istream, ostream, function _asyncCopied(result) {
|
||||
self._writeLock = false;
|
||||
if (Components.isSuccessCode(result)) {
|
||||
self._log.info("asyncCopy succeeded");
|
||||
cb(null);
|
||||
} else {
|
||||
let msg = new Error("asyncCopy failed with " + result);
|
||||
self._log.info(msg);
|
||||
cb(msg);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
this._log.info("Writing queue to disk");
|
||||
CommonUtils.jsonSave(this._filePath, this, value, function jsonSaved(err) {
|
||||
if (err) {
|
||||
let msg = new Error("_putFile failed with " + err);
|
||||
this._writeLock = false;
|
||||
cb(msg);
|
||||
return;
|
||||
}
|
||||
this._log.info("_putFile succeeded");
|
||||
this._writeLock = false;
|
||||
cb(msg);
|
||||
}
|
||||
cb(null);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Root logger
|
||||
pref("services.aitc.log.dump", false);
|
||||
pref("dom.mozApps.used", false); // Set to true by DOMApplicationRegistry
|
||||
|
||||
pref("services.aitc.log.dump", false); // Root logger
|
||||
pref("services.aitc.log.level", "All");
|
||||
|
||||
pref("services.aitc.browserid.url", "https://browserid.org/sign_in");
|
||||
|
@ -7,6 +7,7 @@ Cu.import("resource://services-common/async.js");
|
||||
let queue = null;
|
||||
|
||||
function run_test() {
|
||||
initTestLogging();
|
||||
queue = new AitcQueue("test", run_next_test);
|
||||
}
|
||||
|
||||
@ -97,7 +98,6 @@ add_test(function test_queue_multiaddremove() {
|
||||
});
|
||||
});
|
||||
|
||||
/* TODO Bug 760905 - Temporarily disabled for orange.
|
||||
add_test(function test_queue_writelock() {
|
||||
// Queue should not enqueue or dequeue if lock is enabled.
|
||||
queue._writeLock = true;
|
||||
@ -114,4 +114,3 @@ add_test(function test_queue_writelock() {
|
||||
});
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
@ -17,6 +17,7 @@ modules := \
|
||||
observers.js \
|
||||
preferences.js \
|
||||
rest.js \
|
||||
storageservice.js \
|
||||
stringbundle.js \
|
||||
tokenserverclient.js \
|
||||
utils.js \
|
||||
@ -31,9 +32,8 @@ libs::
|
||||
|
||||
TEST_DIRS += tests
|
||||
|
||||
# TODO enable once build infra supports testing modules.
|
||||
#TESTING_JS_MODULES := aitcserver.js storageserver.js
|
||||
#TESTING_JS_MODULE_DIR := services-common
|
||||
TESTING_JS_MODULES := aitcserver.js storageserver.js
|
||||
TESTING_JS_MODULE_DIR := services-common
|
||||
|
||||
# What follows is a helper to launch a standalone storage server instance.
|
||||
# Most of the code lives in a Python script in the tests directory. If we
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// TODO enable once build infra supports test modules.
|
||||
/*
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
const EXPORTED_SYMBOLS = [
|
||||
@ -14,7 +12,6 @@ const EXPORTED_SYMBOLS = [
|
||||
];
|
||||
|
||||
Cu.import("resource://testing-common/httpd.js");
|
||||
*/
|
||||
Cu.import("resource://services-crypto/utils.js");
|
||||
Cu.import("resource://services-common/log4moz.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
@ -133,7 +130,7 @@ AITCServer10User.prototype = {
|
||||
function AITCServer10Server() {
|
||||
this._log = Log4Moz.repository.getLogger("Services.Common.AITCServer");
|
||||
|
||||
this.server = new nsHttpServer();
|
||||
this.server = new HttpServer();
|
||||
this.port = null;
|
||||
this.users = {};
|
||||
this.autoCreateUsers = false;
|
@ -8,4 +8,5 @@
|
||||
pref("services.common.log.logger.rest.request", "Debug");
|
||||
pref("services.common.log.logger.rest.response", "Debug");
|
||||
|
||||
pref("services.common.storageservice.sendVersionInfo", true);
|
||||
pref("services.common.tokenserverclient.logger.level", "Info");
|
||||
|
@ -8,8 +8,6 @@
|
||||
* The server should not be used for any production purposes.
|
||||
*/
|
||||
|
||||
// TODO enable once build infra supports testing modules.
|
||||
/*
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
const EXPORTED_SYMBOLS = [
|
||||
@ -17,11 +15,10 @@ const EXPORTED_SYMBOLS = [
|
||||
"StorageServerCallback",
|
||||
"StorageServerCollection",
|
||||
"StorageServer",
|
||||
|
||||
"storageServerForUsers",
|
||||
];
|
||||
|
||||
Cu.import("resource://testing-common/httpd.js");
|
||||
*/
|
||||
Cu.import("resource://services-common/async.js");
|
||||
Cu.import("resource://services-common/log4moz.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
@ -240,7 +237,6 @@ ServerBSO.prototype = {
|
||||
}
|
||||
|
||||
this.modified = request.timestamp;
|
||||
response.newModified = request.timestamp;
|
||||
response.setHeader("X-Last-Modified", "" + this.modified, false);
|
||||
|
||||
response.setStatusLine(request.httpVersion, code, status);
|
||||
@ -265,7 +261,7 @@ ServerBSO.prototype = {
|
||||
* An optional timestamp value to initialize the modified time of the
|
||||
* collection. This should be in the format returned by new_timestamp().
|
||||
*/
|
||||
function StorageServerCollection(bsos, acceptNew, timestamp) {
|
||||
function StorageServerCollection(bsos, acceptNew, timestamp=new_timestamp()) {
|
||||
this._bsos = bsos || {};
|
||||
this.acceptNew = acceptNew || false;
|
||||
|
||||
@ -275,8 +271,8 @@ function StorageServerCollection(bsos, acceptNew, timestamp) {
|
||||
* has a modified time.
|
||||
*/
|
||||
CommonUtils.ensureMillisecondsTimestamp(timestamp);
|
||||
this._timestamp = timestamp;
|
||||
|
||||
this.timestamp = timestamp || new_timestamp();
|
||||
this._log = Log4Moz.repository.getLogger(STORAGE_HTTP_LOGGER);
|
||||
}
|
||||
StorageServerCollection.prototype = {
|
||||
@ -404,13 +400,13 @@ StorageServerCollection.prototype = {
|
||||
}
|
||||
|
||||
if (options.newer) {
|
||||
if (bso.modified < options.newer) {
|
||||
if (bso.modified <= options.newer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.older) {
|
||||
if (bso.modified > options.older) {
|
||||
if (bso.modified >= options.older) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -720,7 +716,6 @@ StorageServerCollection.prototype = {
|
||||
});
|
||||
|
||||
body = normalized.join("\n") + "\n";
|
||||
_(body);
|
||||
} else {
|
||||
response.setHeader("Content-Type", "application/json", false);
|
||||
body = JSON.stringify({items: data});
|
||||
@ -776,6 +771,10 @@ StorageServerCollection.prototype = {
|
||||
throw HTTP_415;
|
||||
}
|
||||
|
||||
if (this._ensureUnmodifiedSince(request, response)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let res = this.post(input, request.timestamp);
|
||||
let body = JSON.stringify(res);
|
||||
response.setHeader("Content-Type", "application/json", false);
|
||||
@ -791,6 +790,10 @@ StorageServerCollection.prototype = {
|
||||
|
||||
let options = this.parseOptions(request);
|
||||
|
||||
if (this._ensureUnmodifiedSince(request, response)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let deleted = this.delete(options);
|
||||
response.deleted = deleted;
|
||||
this.timestamp = request.timestamp;
|
||||
@ -817,7 +820,28 @@ StorageServerCollection.prototype = {
|
||||
request.setHeader("Allow", "GET,POST,DELETE");
|
||||
response.setStatusLine(request.httpVersion, 405, "Method Not Allowed");
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
_ensureUnmodifiedSince: function _ensureUnmodifiedSince(request, response) {
|
||||
if (!request.hasHeader("x-if-unmodified-since")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let requestModified = parseInt(request.getHeader("x-if-unmodified-since"),
|
||||
10);
|
||||
let serverModified = this.timestamp;
|
||||
|
||||
this._log.debug("Request modified time: " + requestModified +
|
||||
"; Server modified time: " + serverModified);
|
||||
if (serverModified <= requestModified) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._log.info("Conditional request rejected because client time older " +
|
||||
"than collection timestamp.");
|
||||
response.setStatusLine(request.httpVersion, 412, "Precondition Failed");
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -853,7 +877,7 @@ let StorageServerCallback = {
|
||||
*/
|
||||
function StorageServer(callback) {
|
||||
this.callback = callback || {__proto__: StorageServerCallback};
|
||||
this.server = new nsHttpServer();
|
||||
this.server = new HttpServer();
|
||||
this.started = false;
|
||||
this.users = {};
|
||||
this._log = Log4Moz.repository.getLogger(STORAGE_HTTP_LOGGER);
|
||||
@ -1220,6 +1244,7 @@ StorageServer.prototype = {
|
||||
* HTTP response utility.
|
||||
*/
|
||||
respond: function respond(req, resp, code, status, body, headers, timestamp) {
|
||||
this._log.info("Response: " + code + " " + status);
|
||||
resp.setStatusLine(req.httpVersion, code, status);
|
||||
for each (let [header, value] in Iterator(headers || this.defaultHeaders)) {
|
||||
resp.setHeader(header, value, false);
|
||||
@ -1504,7 +1529,7 @@ StorageServer.prototype = {
|
||||
|
||||
bso.putHandler(req, resp);
|
||||
|
||||
coll.timestamp = resp.newModified;
|
||||
coll.timestamp = req.timestamp;
|
||||
return resp;
|
||||
}
|
||||
|
1795
services/common/storageservice.js
Normal file
1795
services/common/storageservice.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,11 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} = Components;
|
||||
|
||||
// Where to bind test HTTP servers to.
|
||||
const TEST_SERVER_URL = "http://localhost:8080/";
|
||||
|
||||
// This has the side-effect of populating Cc, Ci, Cu, Cr. It's best not to
|
||||
// ask questions and just accept it.
|
||||
do_load_httpd_js();
|
||||
const Cm = Components.manager;
|
||||
|
||||
let gSyncProfile = do_get_profile();
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
@ -54,4 +51,4 @@ function addResourceAlias() {
|
||||
handler.setSubstitution("services-" + module, uri);
|
||||
}
|
||||
}
|
||||
addResourceAlias();
|
||||
addResourceAlias();
|
||||
|
@ -2,6 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource://testing-common/httpd.js");
|
||||
Cu.import("resource://services-common/log4moz.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
|
||||
@ -93,7 +94,7 @@ function get_server_port() {
|
||||
|
||||
function httpd_setup (handlers, port) {
|
||||
let port = port || 8080;
|
||||
let server = new nsHttpServer();
|
||||
let server = new HttpServer();
|
||||
for (let path in handlers) {
|
||||
server.registerPathHandler(path, handlers[path]);
|
||||
}
|
||||
|
@ -6,8 +6,7 @@
|
||||
Cu.import("resource://services-common/rest.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
|
||||
// TODO enable once build infra supports testing modules.
|
||||
//Cu.import("resource://testing-common/services-common/aitcserver.js");
|
||||
Cu.import("resource://testing-common/services-common/aitcserver.js");
|
||||
|
||||
function run_test() {
|
||||
initTestLogging("Trace");
|
||||
|
@ -6,6 +6,7 @@ const modules = [
|
||||
"log4moz.js",
|
||||
"preferences.js",
|
||||
"rest.js",
|
||||
"storageservice.js",
|
||||
"stringbundle.js",
|
||||
"tokenserverclient.js",
|
||||
"utils.js",
|
||||
@ -22,11 +23,8 @@ function run_test() {
|
||||
Components.utils.import(resource, {});
|
||||
}
|
||||
|
||||
// TODO enable once build infra supports testing modules.
|
||||
/*
|
||||
for each (let m in test_modules) {
|
||||
let resource = "resource://testing-common/services-common/" + m;
|
||||
Components.utils.import(resource, {});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -616,7 +616,7 @@ add_test(function test_abort() {
|
||||
* channel activity until the request is automatically canceled.
|
||||
*/
|
||||
add_test(function test_timeout() {
|
||||
let server = new nsHttpServer();
|
||||
let server = new HttpServer();
|
||||
let server_connection;
|
||||
server._handler.handleResponse = function(connection) {
|
||||
// This is a handler that doesn't do anything, just keeps the connection
|
||||
@ -633,7 +633,9 @@ add_test(function test_timeout() {
|
||||
do_check_eq(error.result, Cr.NS_ERROR_NET_TIMEOUT);
|
||||
do_check_eq(this.status, this.ABORTED);
|
||||
|
||||
_("Closing connection.");
|
||||
server_connection.close();
|
||||
_("Shutting down server.");
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
@ -4,8 +4,7 @@
|
||||
Cu.import("resource://services-common/async.js");
|
||||
Cu.import("resource://services-common/rest.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
// TODO enable once build infra supports testing modules.
|
||||
//Cu.import("resource://testing-common/services-common/storageserver.js");
|
||||
Cu.import("resource://testing-common/services-common/storageserver.js");
|
||||
|
||||
const PORT = 8080;
|
||||
const DEFAULT_USER = "123";
|
||||
|
124
services/common/tests/unit/test_storageservice_bso.js
Normal file
124
services/common/tests/unit/test_storageservice_bso.js
Normal file
@ -0,0 +1,124 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://services-common/storageservice.js");
|
||||
|
||||
function run_test() {
|
||||
initTestLogging("Trace");
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_bso_constructor() {
|
||||
_("Ensure created BSO instances are initialized properly.");
|
||||
|
||||
let bso = new BasicStorageObject();
|
||||
do_check_eq(bso.id, null);
|
||||
do_check_eq(bso.collection, null);
|
||||
do_check_attribute_count(bso.data, 0);
|
||||
do_check_eq(bso.payload, null);
|
||||
do_check_eq(bso.modified, null);
|
||||
do_check_eq(bso.sortindex, 0);
|
||||
do_check_eq(bso.ttl, null);
|
||||
|
||||
let bso = new BasicStorageObject("foobar");
|
||||
do_check_eq(bso.id, "foobar");
|
||||
do_check_eq(bso.collection, null);
|
||||
do_check_attribute_count(bso.data, 0);
|
||||
|
||||
let bso = new BasicStorageObject("foo", "coll");
|
||||
do_check_eq(bso.id, "foo");
|
||||
do_check_eq(bso.collection, "coll");
|
||||
do_check_attribute_count(bso.data, 0);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_bso_attributes() {
|
||||
_("Ensure attribute getters and setters work.");
|
||||
|
||||
let bso = new BasicStorageObject("foobar");
|
||||
bso.payload = "pay";
|
||||
do_check_eq(bso.payload, "pay");
|
||||
|
||||
bso.modified = 35423;
|
||||
do_check_eq(bso.modified, 35423);
|
||||
|
||||
bso.sortindex = 10;
|
||||
do_check_eq(bso.sortindex, 10);
|
||||
|
||||
bso.ttl = 60;
|
||||
do_check_eq(bso.ttl, 60);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_bso_deserialize() {
|
||||
_("Ensure that deserialize() works.");
|
||||
|
||||
_("A simple working test.");
|
||||
let json = '{"id": "foobar", "payload": "pay", "modified": 1223145532}';
|
||||
let bso = new BasicStorageObject();
|
||||
bso.deserialize(json);
|
||||
do_check_neq(bso, null);
|
||||
do_check_eq(bso.id, "foobar");
|
||||
do_check_eq(bso.payload, "pay");
|
||||
do_check_eq(bso.modified, 1223145532);
|
||||
|
||||
_("Invalid JSON.");
|
||||
let json = '{id: "foobar}';
|
||||
let bso = new BasicStorageObject();
|
||||
try {
|
||||
bso.deserialize(json);
|
||||
do_check_true(false);
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.name, "SyntaxError");
|
||||
}
|
||||
|
||||
_("Invalid key in JSON.");
|
||||
let json = '{"id": "foo", "payload": "pay", "BADKEY": "irrelevant"}';
|
||||
let bso = new BasicStorageObject();
|
||||
try {
|
||||
bso.deserialize(json);
|
||||
do_check_true(false);
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.name, "Error");
|
||||
do_check_eq(ex.message.indexOf("Invalid key"), 0);
|
||||
}
|
||||
|
||||
_("Loading native JS objects works.");
|
||||
let bso = new BasicStorageObject();
|
||||
bso.deserialize({id: "foo", payload: "pay"});
|
||||
do_check_neq(bso, null);
|
||||
do_check_eq(bso.id, "foo");
|
||||
do_check_eq(bso.payload, "pay");
|
||||
|
||||
_("Passing invalid type is caught.");
|
||||
let bso = new BasicStorageObject();
|
||||
try {
|
||||
bso.deserialize(["foo", "bar"]);
|
||||
do_check_true(false);
|
||||
} catch (ex) {
|
||||
do_check_eq(ex.name, "Error");
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_bso_toJSON() {
|
||||
_("Ensure JSON serialization works.");
|
||||
|
||||
let bso = new BasicStorageObject();
|
||||
do_check_attribute_count(bso.toJSON(), 0);
|
||||
|
||||
bso.id = "foo";
|
||||
bso.payload = "pay";
|
||||
let json = bso.toJSON();
|
||||
let original = json;
|
||||
|
||||
do_check_attribute_count(original, 2);
|
||||
do_check_eq(original.id, "foo");
|
||||
do_check_eq(original.payload, "pay");
|
||||
|
||||
run_next_test();
|
||||
});
|
939
services/common/tests/unit/test_storageservice_client.js
Normal file
939
services/common/tests/unit/test_storageservice_client.js
Normal file
@ -0,0 +1,939 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://services-common/storageservice.js");
|
||||
Cu.import("resource://testing-common/services-common/storageserver.js");
|
||||
|
||||
const BASE_URI = "http://localhost:8080/2.0";
|
||||
|
||||
function run_test() {
|
||||
initTestLogging("Trace");
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function getEmptyServer(user="765", password="password") {
|
||||
let users = {};
|
||||
users[user] = password;
|
||||
|
||||
return storageServerForUsers(users, {
|
||||
meta: {},
|
||||
clients: {},
|
||||
crypto: {},
|
||||
});
|
||||
}
|
||||
|
||||
function getClient(user="765", password="password") {
|
||||
let client = new StorageServiceClient(BASE_URI + "/" + user);
|
||||
client.addListener({
|
||||
onDispatch: function onDispatch(request) {
|
||||
let up = user + ":" + password;
|
||||
request.request.setHeader("authorization", "Basic " + btoa(up));
|
||||
}
|
||||
});
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
function getServerAndClient(user="765", password="password") {
|
||||
let server = getEmptyServer(user, password);
|
||||
let client = getClient(user, password);
|
||||
|
||||
return [server, client, user, password];
|
||||
}
|
||||
|
||||
add_test(function test_auth_failure_listener() {
|
||||
_("Ensure the onAuthFailure listener is invoked.");
|
||||
|
||||
let server = getEmptyServer();
|
||||
let client = getClient("324", "INVALID");
|
||||
client.addListener({
|
||||
onAuthFailure: function onAuthFailure(client, request) {
|
||||
_("onAuthFailure");
|
||||
server.stop(run_next_test);
|
||||
}
|
||||
});
|
||||
|
||||
let request = client.getCollectionInfo();
|
||||
request.dispatch();
|
||||
});
|
||||
|
||||
add_test(function test_duplicate_listeners() {
|
||||
_("Ensure that duplicate listeners aren't installed multiple times.");
|
||||
|
||||
let server = getEmptyServer();
|
||||
let client = getClient("1234567", "BAD_PASSWORD");
|
||||
|
||||
let invokeCount = 0;
|
||||
let listener = {
|
||||
onAuthFailure: function onAuthFailure() {
|
||||
invokeCount++;
|
||||
}
|
||||
};
|
||||
|
||||
client.addListener(listener);
|
||||
// No error expected.
|
||||
client.addListener(listener);
|
||||
|
||||
let request = client.getCollectionInfo();
|
||||
request.dispatch(function onComplete() {
|
||||
do_check_eq(invokeCount, 1);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handler_object() {
|
||||
_("Ensure that installed handlers get their callbacks invoked.");
|
||||
|
||||
let [server, client] = getServerAndClient();
|
||||
|
||||
let onCompleteCount = 0;
|
||||
let onDispatchCount = 0;
|
||||
|
||||
let handler = {
|
||||
onComplete: function onComplete() {
|
||||
onCompleteCount++;
|
||||
|
||||
do_check_eq(onDispatchCount, 1);
|
||||
do_check_eq(onCompleteCount, 1);
|
||||
|
||||
server.stop(run_next_test);
|
||||
},
|
||||
|
||||
onDispatch: function onDispatch() {
|
||||
onDispatchCount++;
|
||||
},
|
||||
};
|
||||
let request = client.getCollectionInfo();
|
||||
request.handler = handler;
|
||||
request.dispatch();
|
||||
});
|
||||
|
||||
add_test(function test_info_collections() {
|
||||
_("Ensure requests to /info/collections work as expected.");
|
||||
|
||||
let [server, client] = getServerAndClient();
|
||||
|
||||
let request = client.getCollectionInfo();
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_eq("object", typeof req.resultObj);
|
||||
do_check_attribute_count(req.resultObj, 3);
|
||||
do_check_true("meta" in req.resultObj);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_info_collections_conditional_not_modified() {
|
||||
_("Ensure conditional getCollectionInfo requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getCollectionInfo();
|
||||
request.locallyModifiedVersion = now + 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_true(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_info_collections_conditional_modified() {
|
||||
_("Ensure conditional getCollectionInfo requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getCollectionInfo();
|
||||
request.locallyModifiedVersion = now - 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_false(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_quota() {
|
||||
_("Ensure quota requests work.");
|
||||
|
||||
let [server, client] = getServerAndClient();
|
||||
|
||||
let request = client.getQuota();
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(req.resultObj.quota, 1048576);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_quota_conditional_not_modified() {
|
||||
_("Ensure conditional getQuota requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getQuota();
|
||||
request.locallyModifiedVersion = now + 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_true(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_quota_conditional_modified() {
|
||||
_("Ensure conditional getQuota requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getQuota();
|
||||
request.locallyModifiedVersion = now - 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_false(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_collection_usage() {
|
||||
_("Ensure info/collection_usage requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
abc123: new ServerBSO("abc123", "payload", Date.now())
|
||||
});
|
||||
|
||||
let request = client.getCollectionUsage();
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
let usage = req.resultObj;
|
||||
do_check_true("testcoll" in usage);
|
||||
do_check_eq(usage.testcoll, "payload".length);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_usage_conditional_not_modified() {
|
||||
_("Ensure conditional getCollectionUsage requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getCollectionUsage();
|
||||
request.locallyModifiedVersion = now + 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_true(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_usage_conditional_modified() {
|
||||
_("Ensure conditional getCollectionUsage requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getCollectionUsage();
|
||||
request.locallyModifiedVersion = now - 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_false(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_collection_counts() {
|
||||
_("Ensure info/collection_counts requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", Date.now()),
|
||||
bar: new ServerBSO("bar", "payload1", Date.now())
|
||||
});
|
||||
|
||||
let request = client.getCollectionCounts();
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
let counts = req.resultObj;
|
||||
do_check_true("testcoll" in counts);
|
||||
do_check_eq(counts.testcoll, 2);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_counts_conditional_not_modified() {
|
||||
_("Ensure conditional getCollectionCounts requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getCollectionCounts();
|
||||
request.locallyModifiedVersion = now + 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_true(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_counts_conditional_modified() {
|
||||
_("Ensure conditional getCollectionCounts requests work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getCollectionCounts();
|
||||
request.locallyModifiedVersion = now - 10;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_false(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_collection_simple() {
|
||||
_("Ensure basic collection retrieval works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", Date.now()),
|
||||
bar: new ServerBSO("bar", "payload1", Date.now())
|
||||
});
|
||||
|
||||
let request = client.getCollection("testcoll");
|
||||
let bsos = [];
|
||||
request.handler = {
|
||||
onBSORecord: function onBSORecord(request, bso) {
|
||||
bsos.push(bso);
|
||||
},
|
||||
|
||||
onComplete: function onComplete(error, request) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(bsos.length, 2);
|
||||
do_check_eq(bsos[0], "foo");
|
||||
do_check_eq(bsos[1], "bar");
|
||||
|
||||
server.stop(run_next_test);
|
||||
}
|
||||
};
|
||||
request.dispatch();
|
||||
});
|
||||
|
||||
add_test(function test_get_collection_conditional_not_modified() {
|
||||
_("Ensure conditional requests with no new data to getCollection work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.getCollection("testcoll");
|
||||
request.locallyModifiedVersion = now + 1;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_true(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_get_collection_conditional_modified() {
|
||||
_("Ensure conditional requests with new data to getCollection work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.getCollection("testcoll");
|
||||
request.locallyModifiedVersion = now - 1;
|
||||
|
||||
let bsoCount = 0;
|
||||
request.handler = {
|
||||
onBSORecord: function onBSORecord() {
|
||||
bsoCount++;
|
||||
},
|
||||
|
||||
onComplete: function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_false(req.notModified);
|
||||
do_check_eq(bsoCount, 1);
|
||||
|
||||
server.stop(run_next_test);
|
||||
}
|
||||
};
|
||||
request.dispatch();
|
||||
});
|
||||
|
||||
// This is effectively a sanity test for query string generation.
|
||||
add_test(function test_get_collection_newer() {
|
||||
_("Ensure query string for newer and full work together.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
|
||||
let date0 = Date.now();
|
||||
let date1 = date0 + 500;
|
||||
|
||||
let user = server.user(username);
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", date0),
|
||||
bar: new ServerBSO("bar", "payload1", date1)
|
||||
});
|
||||
|
||||
let request = client.getCollection("testcoll");
|
||||
request.full = true;
|
||||
request.newer = date0;
|
||||
|
||||
let bsos = [];
|
||||
request.handler = {
|
||||
onBSORecord: function onBSORecord(request, bso) {
|
||||
bsos.push(bso);
|
||||
},
|
||||
|
||||
onComplete: function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(bsos.length, 1);
|
||||
let bso = bsos[0];
|
||||
|
||||
do_check_eq(bso.id, "bar");
|
||||
do_check_eq(bso.payload, "payload1");
|
||||
|
||||
server.stop(run_next_test);
|
||||
}
|
||||
};
|
||||
request.dispatch();
|
||||
});
|
||||
|
||||
add_test(function test_get_bso() {
|
||||
_("Ensure that simple BSO fetches work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
|
||||
server.createCollection(username, "testcoll", {
|
||||
abc123: new ServerBSO("abc123", "payload", Date.now())
|
||||
});
|
||||
|
||||
let request = client.getBSO("testcoll", "abc123");
|
||||
request.dispatch(function(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_true(req.resultObj instanceof BasicStorageObject);
|
||||
|
||||
let bso = req.resultObj;
|
||||
do_check_eq(bso.id, "abc123");
|
||||
do_check_eq(bso.payload, "payload");
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_bso_conditional() {
|
||||
_("Ensure conditional requests for an individual BSO work.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
|
||||
let user = server.user(username);
|
||||
let now = Date.now();
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload", now)
|
||||
});
|
||||
|
||||
let request = client.getBSO("testcoll", "foo");
|
||||
request.locallyModifiedVersion = now;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_true(req.notModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_set_bso() {
|
||||
_("Ensure simple BSO PUT works.");
|
||||
|
||||
let [server, client] = getServerAndClient();
|
||||
|
||||
let id = "mnas08h3f3r2351";
|
||||
|
||||
let bso = new BasicStorageObject(id, "testcoll");
|
||||
bso.payload = "my test payload";
|
||||
|
||||
let request = client.setBSO(bso);
|
||||
request.dispatch(function(error, req) {
|
||||
do_check_eq(error, null);
|
||||
do_check_eq(req.resultObj, null);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
add_test(function test_set_bso_conditional() {
|
||||
_("Ensure conditional setting a BSO is properly rejected.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now + 1000)
|
||||
});
|
||||
|
||||
// Should get an mtime newer than server's.
|
||||
let bso = new BasicStorageObject("foo", "testcoll");
|
||||
bso.payload = "payload1";
|
||||
|
||||
let request = client.setBSO(bso);
|
||||
request.locallyModifiedVersion = now;
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_true(error instanceof StorageServiceRequestError);
|
||||
do_check_true(error.serverModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_set_bso_argument_errors() {
|
||||
_("Ensure BSO set detects invalid arguments.");
|
||||
|
||||
let bso = new BasicStorageObject();
|
||||
let client = getClient();
|
||||
|
||||
let threw = false;
|
||||
try {
|
||||
client.setBSO(bso);
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
do_check_eq(ex.name, "Error");
|
||||
do_check_neq(ex.message.indexOf("does not have collection defined"), -1);
|
||||
} finally {
|
||||
do_check_true(threw);
|
||||
threw = false;
|
||||
}
|
||||
|
||||
bso = new BasicStorageObject("id");
|
||||
try {
|
||||
client.setBSO(bso);
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
do_check_eq(ex.name, "Error");
|
||||
do_check_neq(ex.message.indexOf("does not have collection defined"), -1);
|
||||
} finally {
|
||||
do_check_true(threw);
|
||||
threw = false;
|
||||
}
|
||||
|
||||
bso = new BasicStorageObject(null, "coll");
|
||||
try {
|
||||
client.setBSO(bso);
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
do_check_eq(ex.name, "Error");
|
||||
do_check_neq(ex.message.indexOf("does not have ID defined"), -1);
|
||||
} finally {
|
||||
do_check_true(threw);
|
||||
threw = false;
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_set_bsos_simple() {
|
||||
_("Ensure setBSOs with basic options works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let bso0 = new BasicStorageObject("foo");
|
||||
bso0.payload = "payload0";
|
||||
|
||||
let bso1 = new BasicStorageObject("bar");
|
||||
bso1.payload = "payload1";
|
||||
|
||||
let request = client.setBSOs("testcollection");
|
||||
request.addBSO(bso0);
|
||||
request.addBSO(bso1);
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
let successful = req.successfulIDs;
|
||||
do_check_eq(successful.size(), 2);
|
||||
do_check_true(successful.has(bso0.id));
|
||||
do_check_true(successful.has(bso1.id));
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_set_bsos_invalid_bso() {
|
||||
_("Ensure that adding an invalid BSO throws.");
|
||||
|
||||
let client = getClient();
|
||||
let request = client.setBSOs("testcoll");
|
||||
|
||||
let threw = false;
|
||||
|
||||
// Empty argument is invalid.
|
||||
try {
|
||||
request.addBSO(null);
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
} finally {
|
||||
do_check_true(threw);
|
||||
threw = false;
|
||||
}
|
||||
|
||||
try {
|
||||
let bso = new BasicStorageObject();
|
||||
request.addBSO(bso);
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
} finally {
|
||||
do_check_true(threw);
|
||||
threw = false;
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_delete_bso_simple() {
|
||||
_("Ensure deletion of individual BSOs works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
|
||||
let user = server.user(username);
|
||||
let coll = user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", Date.now()),
|
||||
bar: new ServerBSO("bar", "payload1", Date.now())
|
||||
});
|
||||
|
||||
let request = client.deleteBSO("testcoll", "foo");
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_eq(req.statusCode, 204);
|
||||
|
||||
do_check_eq(coll.count(), 1);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_bso_conditional_failed() {
|
||||
_("Ensure deletion of an individual BSO with older modification fails.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.deleteBSO("testcoll", "foo");
|
||||
request.locallyModifiedVersion = now - 10;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_true(error instanceof StorageServiceRequestError);
|
||||
do_check_true(error.serverModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_bso_conditional_success() {
|
||||
_("Ensure deletion of an individual BSO with newer modification works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.deleteBSO("testcoll", "foo");
|
||||
request.locallyModifiedVersion = now;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_eq(req.statusCode, 204);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_bsos_simple() {
|
||||
_("Ensure deletion of multiple BSOs works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let coll = user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", Date.now()),
|
||||
bar: new ServerBSO("bar", "payload1", Date.now()),
|
||||
baz: new ServerBSO("baz", "payload2", Date.now())
|
||||
});
|
||||
|
||||
let request = client.deleteBSOs("testcoll", ["foo", "baz"]);
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
do_check_eq(req.statusCode, 204);
|
||||
|
||||
do_check_eq(coll.count(), 1);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_bsos_conditional_failed() {
|
||||
_("Ensure deletion of BSOs with server modifications fails.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
let coll = user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.deleteBSOs("testcoll", ["foo"]);
|
||||
request.locallyModifiedVersion = coll.timestamp - 1;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_true(error instanceof StorageServiceRequestError);
|
||||
do_check_true(error.serverModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_bsos_conditional_success() {
|
||||
_("Ensure conditional deletion of BSOs without server modifications works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
let coll = user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now),
|
||||
bar: new ServerBSO("bar", "payload1", now - 10)
|
||||
});
|
||||
|
||||
let request = client.deleteBSOs("testcoll", ["bar"]);
|
||||
request.locallyModifiedVersion = coll.timestamp;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(req.statusCode, 204);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_collection() {
|
||||
_("Ensure deleteCollection() works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", Date.now())
|
||||
});
|
||||
|
||||
let request = client.deleteCollection("testcoll");
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(user.collection("testcoll", undefined));
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_collection_conditional_failed() {
|
||||
_("Ensure conditional deletes with server modifications fail.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
let coll = user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.deleteCollection("testcoll");
|
||||
request.locallyModifiedVersion = coll.timestamp - 1;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_true(error instanceof StorageServiceRequestError);
|
||||
do_check_true(error.serverModified);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_collection_conditional_success() {
|
||||
_("Ensure conditional delete of collection works when it's supposed to.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
let coll = user.createCollection("testcoll", {
|
||||
foo: new ServerBSO("foo", "payload0", now)
|
||||
});
|
||||
|
||||
let request = client.deleteCollection("testcoll");
|
||||
request.locallyModifiedVersion = coll.timestamp;
|
||||
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(user.collection("testcoll"), undefined);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_delete_collections() {
|
||||
_("Ensure deleteCollections() works.");
|
||||
|
||||
let [server, client, username] = getServerAndClient();
|
||||
let user = server.user(username);
|
||||
|
||||
user.createCollection("testColl", {
|
||||
foo: new ServerBSO("foo", "payload0", Date.now())
|
||||
});
|
||||
|
||||
let request = client.deleteCollections();
|
||||
request.dispatch(function onComplete(error, req) {
|
||||
do_check_null(error);
|
||||
|
||||
do_check_eq(user.collection("testcoll"), undefined);
|
||||
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_network_error_captured() {
|
||||
_("Ensure network errors are captured.");
|
||||
|
||||
// Network errors should result in .networkError being set on request.
|
||||
let client = new StorageServiceClient("http://rnewman-is-splendid.badtld/");
|
||||
|
||||
let request = client.getCollectionInfo();
|
||||
request.dispatch(function(error, req) {
|
||||
do_check_neq(error, null);
|
||||
do_check_neq(error.network, null);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_network_error_listener() {
|
||||
_("Ensure the onNetworkError listener is invoked on network errors.");
|
||||
|
||||
let listenerCalled = false;
|
||||
|
||||
let client = new StorageServiceClient("http://philikon-is-too.badtld/");
|
||||
client.addListener({
|
||||
onNetworkError: function(client, request) {
|
||||
listenerCalled = true;
|
||||
}
|
||||
});
|
||||
let request = client.getCollectionInfo();
|
||||
request.dispatch(function() {
|
||||
do_check_true(listenerCalled);
|
||||
run_next_test();
|
||||
});
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
[DEFAULT]
|
||||
head = head_global.js head_helpers.js head_http.js aitcserver.js storageserver.js
|
||||
head = head_global.js head_helpers.js head_http.js
|
||||
tail =
|
||||
|
||||
# Test load modules first so syntax failures are caught early.
|
||||
@ -22,6 +22,11 @@ tail =
|
||||
[test_preferences.js]
|
||||
[test_restrequest.js]
|
||||
[test_tokenauthenticatedrequest.js]
|
||||
|
||||
# Storage service APIs
|
||||
[test_storageservice_bso.js]
|
||||
[test_storageservice_client.js]
|
||||
|
||||
[test_tokenserverclient.js]
|
||||
|
||||
[test_storage_server.js]
|
||||
|
@ -527,7 +527,7 @@ let SyncServerCallback = {
|
||||
*/
|
||||
function SyncServer(callback) {
|
||||
this.callback = callback || {__proto__: SyncServerCallback};
|
||||
this.server = new nsHttpServer();
|
||||
this.server = new HttpServer();
|
||||
this.started = false;
|
||||
this.users = {};
|
||||
this._log = Log4Moz.repository.getLogger(SYNC_HTTP_LOGGER);
|
||||
@ -539,7 +539,7 @@ function SyncServer(callback) {
|
||||
}
|
||||
SyncServer.prototype = {
|
||||
port: 8080,
|
||||
server: null, // nsHttpServer.
|
||||
server: null, // HttpServer.
|
||||
users: null, // Map of username => {collections, password}.
|
||||
|
||||
/**
|
||||
@ -775,8 +775,8 @@ SyncServer.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* This is invoked by the nsHttpServer. `this` is bound to the SyncServer;
|
||||
* `handler` is the nsHttpServer's handler.
|
||||
* This is invoked by the HttpServer. `this` is bound to the SyncServer;
|
||||
* `handler` is the HttpServer's handler.
|
||||
*
|
||||
* TODO: need to use the correct Sync API response codes and errors here.
|
||||
* TODO: Basic Auth.
|
||||
|
@ -170,7 +170,7 @@ add_test(function test_disabled_install_semantics() {
|
||||
server.createContents(USER, contents);
|
||||
server.start();
|
||||
|
||||
let amoServer = new nsHttpServer();
|
||||
let amoServer = new HttpServer();
|
||||
amoServer.registerFile("/search/guid:addon1%40tests.mozilla.org",
|
||||
do_get_file("addon1-search.xml"));
|
||||
|
||||
|
@ -42,7 +42,7 @@ function createRecordForThisApp(id, addonId, enabled, deleted) {
|
||||
|
||||
function createAndStartHTTPServer(port) {
|
||||
try {
|
||||
let server = new nsHttpServer();
|
||||
let server = new HttpServer();
|
||||
|
||||
let bootstrap1XPI = ExtensionsTestPath("/addons/test_bootstrap1_1.xpi");
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"talos.zip": {
|
||||
"url": "http://build.mozilla.org/talos/zips/talos.aec9ddd2a04c.zip",
|
||||
"url": "http://build.mozilla.org/talos/zips/talos.18ae2ce2749b.zip",
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +303,16 @@ package-tests: stage-android
|
||||
endif
|
||||
|
||||
make-stage-dir:
|
||||
rm -rf $(PKG_STAGE) && $(NSINSTALL) -D $(PKG_STAGE) && $(NSINSTALL) -D $(PKG_STAGE)/bin && $(NSINSTALL) -D $(PKG_STAGE)/bin/components && $(NSINSTALL) -D $(PKG_STAGE)/certs && $(NSINSTALL) -D $(PKG_STAGE)/jetpack && $(NSINSTALL) -D $(PKG_STAGE)/firebug && $(NSINSTALL) -D $(PKG_STAGE)/peptest && $(NSINSTALL) -D $(PKG_STAGE)/mozbase && $(NSINSTALL) -D $(PKG_STAGE)/modules
|
||||
rm -rf $(PKG_STAGE)
|
||||
$(NSINSTALL) -D $(PKG_STAGE)
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/bin
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/bin/components
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/certs
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/jetpack
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/firebug
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/peptest
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/mozbase
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/modules
|
||||
|
||||
robotium-id-map:
|
||||
ifeq ($(MOZ_BUILD_APP),mobile/android)
|
||||
@ -347,9 +356,9 @@ stage-tps: make-stage-dir
|
||||
@(cd $(topsrcdir)/services/sync/tps && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/tps && tar -xf -)
|
||||
(cd $(topsrcdir)/services/sync/tests/tps && tar $(TAR_CREATE_FLAGS_QUIET) - *) | (cd $(PKG_STAGE)/tps/tests && tar -xf -)
|
||||
|
||||
# This will get replaced by actual logic in a subsequent patch.
|
||||
stage-modules: make-stage-dir
|
||||
$(TOUCH) $(PKG_STAGE)/modules/.dummy
|
||||
$(NSINSTALL) -D $(PKG_STAGE)/modules
|
||||
cp -RL $(DEPTH)/_tests/modules $(PKG_STAGE)
|
||||
|
||||
stage-mozbase: make-stage-dir
|
||||
$(MAKE) -C $(DEPTH)/testing/mozbase stage-package
|
||||
|
@ -281,7 +281,18 @@ function _register_protocol_handlers() {
|
||||
createInstance(Components.interfaces.nsILocalFile);
|
||||
modulesFile.initWithPath(_TESTING_MODULES_DIR);
|
||||
|
||||
if (!modulesFile.exists()) {
|
||||
throw new Error("Specified modules directory does not exist: " +
|
||||
_TESTING_MODULES_DIR);
|
||||
}
|
||||
|
||||
if (!modulesFile.isDirectory()) {
|
||||
throw new Error("Specified modules directory is not a directory: " +
|
||||
_TESTING_MODULES_DIR);
|
||||
}
|
||||
|
||||
let modulesURI = ios.newFileURI(modulesFile);
|
||||
|
||||
protocolHandler.setSubstitution("testing-common", modulesURI);
|
||||
}
|
||||
}
|
||||
@ -814,7 +825,8 @@ function do_load_child_test_harness()
|
||||
+ "const _XPCSHELL_PROCESS='child';";
|
||||
|
||||
if (this._TESTING_MODULES_DIR) {
|
||||
command += "const _TESTING_MODULES_DIR='" + _TESTING_MODULES_DIR + "'; ";
|
||||
normalized = this._TESTING_MODULES_DIR.replace('\\', '\\\\', 'g');
|
||||
command += "const _TESTING_MODULES_DIR='" + normalized + "'; ";
|
||||
}
|
||||
|
||||
command += "load(_HEAD_JS_PATH);";
|
||||
|
@ -202,9 +202,11 @@ class XPCShellTests(object):
|
||||
]
|
||||
|
||||
if self.testingModulesDir:
|
||||
# Escape backslashes in string literal.
|
||||
sanitized = self.testingModulesDir.replace('\\', '\\\\')
|
||||
self.xpcsCmd.extend([
|
||||
'-e',
|
||||
'const _TESTING_MODULES_DIR = "%s";' % self.testingModulesDir
|
||||
'const _TESTING_MODULES_DIR = "%s";' % sanitized
|
||||
])
|
||||
|
||||
self.xpcsCmd.extend(['-f', os.path.join(self.testharnessdir, 'head.js')])
|
||||
@ -587,10 +589,30 @@ class XPCShellTests(object):
|
||||
raise Exception("testsRootDir path does not exists: %s" %
|
||||
testsRootDir)
|
||||
|
||||
# Try to guess modules directory.
|
||||
# This somewhat grotesque hack allows the buildbot machines to find the
|
||||
# modules directory without having to configure the buildbot hosts. This
|
||||
# code path should never be executed in local runs because the build system
|
||||
# should always set this argument.
|
||||
if not testingModulesDir:
|
||||
ourDir = os.path.dirname(__file__)
|
||||
possible = os.path.join(ourDir, os.path.pardir, 'modules')
|
||||
|
||||
if os.path.isdir(possible):
|
||||
testingModulesDir = possible
|
||||
|
||||
if testingModulesDir:
|
||||
# The resource loader expects native paths. Depending on how we were
|
||||
# invoked, a UNIX style path may sneak in on Windows. We try to
|
||||
# normalize that.
|
||||
testingModulesDir = os.path.normpath(testingModulesDir)
|
||||
|
||||
if not os.path.isabs(testingModulesDir):
|
||||
testingModulesDir = os.path.abspath(testingModulesDir)
|
||||
|
||||
if not testingModulesDir.endswith(os.path.sep):
|
||||
testingModulesDir += os.path.sep
|
||||
|
||||
self.xpcshell = xpcshell
|
||||
self.xrePath = xrePath
|
||||
self.appPath = appPath
|
||||
@ -664,6 +686,7 @@ class XPCShellTests(object):
|
||||
# dir and the test with path characters replaced with '.' (using Java
|
||||
# class notation).
|
||||
if testsRootDir is not None:
|
||||
testsRootDir = os.path.normpath(testsRootDir)
|
||||
if test["here"].find(testsRootDir) != 0:
|
||||
raise Exception("testsRootDir is not a parent path of %s" %
|
||||
test["here"])
|
||||
|
Loading…
Reference in New Issue
Block a user