summaryrefslogtreecommitdiffstats
path: root/toolkit/components/contentprefs/tests/unit_cps2
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /toolkit/components/contentprefs/tests/unit_cps2
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'toolkit/components/contentprefs/tests/unit_cps2')
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/.eslintrc.js7
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/AsyncRunner.jsm69
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/head.js401
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_extractDomain.js20
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_getCached.js95
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_getCachedSubdomains.js186
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_getSubdomains.js68
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_migrationToSchema4.js82
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_observers.js178
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_remove.js222
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomains.js87
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomainsSince.js111
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_removeByDomain.js199
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_removeByName.js96
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_service.js12
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/test_setGet.js206
-rw-r--r--toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini19
17 files changed, 2058 insertions, 0 deletions
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/.eslintrc.js b/toolkit/components/contentprefs/tests/unit_cps2/.eslintrc.js
new file mode 100644
index 000000000..d35787cd2
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+ "extends": [
+ "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
+ ]
+};
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/AsyncRunner.jsm b/toolkit/components/contentprefs/tests/unit_cps2/AsyncRunner.jsm
new file mode 100644
index 000000000..ac878c28c
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/AsyncRunner.jsm
@@ -0,0 +1,69 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+var EXPORTED_SYMBOLS = [
+ "AsyncRunner",
+];
+
+const { interfaces: Ci, classes: Cc } = Components;
+
+function AsyncRunner(callbacks) {
+ this._callbacks = callbacks;
+ this._iteratorQueue = [];
+
+ // This catches errors reported to the console, e.g., via Cu.reportError.
+ Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService).
+ registerListener(this);
+}
+
+AsyncRunner.prototype = {
+
+ appendIterator: function AR_appendIterator(iter) {
+ this._iteratorQueue.push(iter);
+ },
+
+ next: function AR_next(arg) {
+ if (!this._iteratorQueue.length) {
+ this.destroy();
+ this._callbacks.done();
+ return;
+ }
+
+ try {
+ var { done, value } = this._iteratorQueue[0].next(arg);
+ if (done) {
+ this._iteratorQueue.shift();
+ this.next();
+ return;
+ }
+ }
+ catch (err) {
+ this._callbacks.error(err);
+ }
+
+ // val is truthy => call next
+ // val is an iterator => prepend it to the queue and start on it
+ if (value) {
+ if (typeof(value) != "boolean")
+ this._iteratorQueue.unshift(value);
+ this.next();
+ }
+ },
+
+ destroy: function AR_destroy() {
+ Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService).
+ unregisterListener(this);
+ this.destroy = function AR_alreadyDestroyed() {};
+ },
+
+ observe: function AR_consoleServiceListener(msg) {
+ if (msg instanceof Ci.nsIScriptError &&
+ !(msg.flags & Ci.nsIScriptError.warningFlag))
+ {
+ this._callbacks.consoleError(msg);
+ }
+ },
+};
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/head.js b/toolkit/components/contentprefs/tests/unit_cps2/head.js
new file mode 100644
index 000000000..b86abe208
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/head.js
@@ -0,0 +1,401 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+var { interfaces: Ci, classes: Cc, results: Cr, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+var cps;
+var asyncRunner;
+var next;
+
+(function init() {
+ // There has to be a profile directory before the CPS service is gotten.
+ do_get_profile();
+})();
+
+function runAsyncTests(tests, dontResetBefore = false) {
+ do_test_pending();
+
+ cps = Cc["@mozilla.org/content-pref/service;1"].
+ getService(Ci.nsIContentPrefService2);
+
+ let s = {};
+ Cu.import("resource://test/AsyncRunner.jsm", s);
+ asyncRunner = new s.AsyncRunner({
+ done: do_test_finished,
+ error: function (err) {
+ // xpcshell test functions like equal throw NS_ERROR_ABORT on
+ // failure. Ignore those and catch only uncaught exceptions.
+ if (err !== Cr.NS_ERROR_ABORT) {
+ if (err.stack) {
+ err = err + "\n\nTraceback (most recent call first):\n" + err.stack +
+ "\nUseless do_throw stack:";
+ }
+ do_throw(err);
+ }
+ },
+ consoleError: function (scriptErr) {
+ // Previously, this code checked for console errors related to the test,
+ // and treated them as failures. This was problematic, because our current
+ // very-broken exception reporting machinery in XPCWrappedJSClass reports
+ // errors to the console even if there's actually JS on the stack above
+ // that will catch them. And a lot of the tests here intentionally trigger
+ // error conditions on the JS-implemented XPCOM component (see erroneous()
+ // in test_getSubdomains.js, for example). In the old world, we got lucky,
+ // and the errors were never reported to the console due to happenstantial
+ // JSContext reasons that aren't really worth going into.
+ //
+ // So. We make sure to dump this stuff so that it shows up in the logs, but
+ // don't turn them into duplicate failures of the exception that was already
+ // propagated to the caller.
+ dump("AsyncRunner.jsm observed console error: " + scriptErr + "\n");
+ }
+ });
+
+ next = asyncRunner.next.bind(asyncRunner);
+
+ do_register_cleanup(function () {
+ asyncRunner.destroy();
+ asyncRunner = null;
+ });
+
+ tests.forEach(function (test) {
+ function* gen() {
+ do_print("Running " + test.name);
+ yield test();
+ yield reset();
+ }
+ asyncRunner.appendIterator(gen());
+ });
+
+ // reset() ends up calling asyncRunner.next(), starting the tests.
+ if (dontResetBefore) {
+ next();
+ } else {
+ reset();
+ }
+}
+
+function makeCallback(callbacks, success = null) {
+ callbacks = callbacks || {};
+ if (!callbacks.handleError) {
+ callbacks.handleError = function (error) {
+ do_throw("handleError call was not expected, error: " + error);
+ };
+ }
+ if (!callbacks.handleResult) {
+ callbacks.handleResult = function() {
+ do_throw("handleResult call was not expected");
+ };
+ }
+ if (!callbacks.handleCompletion)
+ callbacks.handleCompletion = function (reason) {
+ equal(reason, Ci.nsIContentPrefCallback2.COMPLETE_OK);
+ if (success) {
+ success();
+ } else {
+ next();
+ }
+ };
+ return callbacks;
+}
+
+function do_check_throws(fn) {
+ let threw = false;
+ try {
+ fn();
+ }
+ catch (err) {
+ threw = true;
+ }
+ ok(threw);
+}
+
+function sendMessage(msg, callback) {
+ let obj = callback || {};
+ let ref = Cu.getWeakReference(obj);
+ cps.QueryInterface(Ci.nsIObserver).observe(ref, "test:" + msg, null);
+ return "value" in obj ? obj.value : undefined;
+}
+
+function reset() {
+ sendMessage("reset", next);
+}
+
+function setWithDate(group, name, val, timestamp, context) {
+ function updateDate() {
+ let db = sendMessage("db");
+ let stmt = db.createAsyncStatement(`
+ UPDATE prefs SET timestamp = :timestamp
+ WHERE
+ settingID = (SELECT id FROM settings WHERE name = :name)
+ AND groupID = (SELECT id FROM groups WHERE name = :group)
+ `);
+ stmt.params.timestamp = timestamp / 1000;
+ stmt.params.name = name;
+ stmt.params.group = group;
+
+ stmt.executeAsync({
+ handleCompletion: function (reason) {
+ next();
+ },
+ handleError: function (err) {
+ do_throw(err);
+ }
+ });
+ stmt.finalize();
+ }
+
+ cps.set(group, name, val, context, makeCallback(null, updateDate));
+}
+
+function getDate(group, name, context) {
+ let db = sendMessage("db");
+ let stmt = db.createAsyncStatement(`
+ SELECT timestamp FROM prefs
+ WHERE
+ settingID = (SELECT id FROM settings WHERE name = :name)
+ AND groupID = (SELECT id FROM groups WHERE name = :group)
+ `);
+ stmt.params.name = name;
+ stmt.params.group = group;
+
+ let res;
+ stmt.executeAsync({
+ handleResult: function (results) {
+ let row = results.getNextRow();
+ res = row.getResultByName("timestamp");
+ },
+ handleCompletion: function (reason) {
+ next(res * 1000);
+ },
+ handleError: function (err) {
+ do_throw(err);
+ }
+ });
+ stmt.finalize();
+}
+
+function set(group, name, val, context) {
+ cps.set(group, name, val, context, makeCallback());
+}
+
+function setGlobal(name, val, context) {
+ cps.setGlobal(name, val, context, makeCallback());
+}
+
+function prefOK(actual, expected, strict) {
+ ok(actual instanceof Ci.nsIContentPref);
+ equal(actual.domain, expected.domain);
+ equal(actual.name, expected.name);
+ if (strict)
+ strictEqual(actual.value, expected.value);
+ else
+ equal(actual.value, expected.value);
+}
+
+function* getOK(args, expectedVal, expectedGroup, strict) {
+ if (args.length == 2)
+ args.push(undefined);
+ let expectedPrefs = expectedVal === undefined ? [] :
+ [{ domain: expectedGroup || args[0],
+ name: args[1],
+ value: expectedVal }];
+ yield getOKEx("getByDomainAndName", args, expectedPrefs, strict);
+}
+
+function* getSubdomainsOK(args, expectedGroupValPairs) {
+ if (args.length == 2)
+ args.push(undefined);
+ let expectedPrefs = expectedGroupValPairs.map(function ([group, val]) {
+ return { domain: group, name: args[1], value: val };
+ });
+ yield getOKEx("getBySubdomainAndName", args, expectedPrefs);
+}
+
+function* getGlobalOK(args, expectedVal) {
+ if (args.length == 1)
+ args.push(undefined);
+ let expectedPrefs = expectedVal === undefined ? [] :
+ [{ domain: null, name: args[0], value: expectedVal }];
+ yield getOKEx("getGlobal", args, expectedPrefs);
+}
+
+function* getOKEx(methodName, args, expectedPrefs, strict, context) {
+ let actualPrefs = [];
+ args.push(makeCallback({
+ handleResult: pref => actualPrefs.push(pref)
+ }));
+ yield cps[methodName].apply(cps, args);
+ arraysOfArraysOK([actualPrefs], [expectedPrefs], function (actual, expected) {
+ prefOK(actual, expected, strict);
+ });
+}
+
+function getCachedOK(args, expectedIsCached, expectedVal, expectedGroup,
+ strict) {
+ if (args.length == 2)
+ args.push(undefined);
+ let expectedPref = !expectedIsCached ? null : {
+ domain: expectedGroup || args[0],
+ name: args[1],
+ value: expectedVal
+ };
+ getCachedOKEx("getCachedByDomainAndName", args, expectedPref, strict);
+}
+
+function getCachedSubdomainsOK(args, expectedGroupValPairs) {
+ if (args.length == 2)
+ args.push(undefined);
+ let len = {};
+ args.push(len);
+ let actualPrefs = cps.getCachedBySubdomainAndName.apply(cps, args);
+ actualPrefs = actualPrefs.sort(function (a, b) {
+ return a.domain.localeCompare(b.domain);
+ });
+ equal(actualPrefs.length, len.value);
+ let expectedPrefs = expectedGroupValPairs.map(function ([group, val]) {
+ return { domain: group, name: args[1], value: val };
+ });
+ arraysOfArraysOK([actualPrefs], [expectedPrefs], prefOK);
+}
+
+function getCachedGlobalOK(args, expectedIsCached, expectedVal) {
+ if (args.length == 1)
+ args.push(undefined);
+ let expectedPref = !expectedIsCached ? null : {
+ domain: null,
+ name: args[0],
+ value: expectedVal
+ };
+ getCachedOKEx("getCachedGlobal", args, expectedPref);
+}
+
+function getCachedOKEx(methodName, args, expectedPref, strict) {
+ let actualPref = cps[methodName].apply(cps, args);
+ if (expectedPref)
+ prefOK(actualPref, expectedPref, strict);
+ else
+ strictEqual(actualPref, null);
+}
+
+function arraysOK(actual, expected, cmp) {
+ if (actual.length != expected.length) {
+ do_throw("Length is not equal: " + JSON.stringify(actual) + "==" + JSON.stringify(expected));
+ } else {
+ actual.forEach(function (actualElt, j) {
+ let expectedElt = expected[j];
+ cmp(actualElt, expectedElt);
+ });
+ }
+}
+
+function arraysOfArraysOK(actual, expected, cmp) {
+ cmp = cmp || equal;
+ arraysOK(actual, expected, function (act, exp) {
+ arraysOK(act, exp, cmp)
+ });
+}
+
+function dbOK(expectedRows) {
+ let db = sendMessage("db");
+ let stmt = db.createAsyncStatement(`
+ SELECT groups.name AS grp, settings.name AS name, prefs.value AS value
+ FROM prefs
+ LEFT JOIN groups ON groups.id = prefs.groupID
+ LEFT JOIN settings ON settings.id = prefs.settingID
+ UNION
+
+ /*
+ These second two SELECTs get the rows of the groups and settings tables
+ that aren't referenced by the prefs table. Neither should return any
+ rows if the component is working properly.
+ */
+ SELECT groups.name AS grp, NULL AS name, NULL AS value
+ FROM groups
+ WHERE id NOT IN (
+ SELECT DISTINCT groupID
+ FROM prefs
+ WHERE groupID NOTNULL
+ )
+ UNION
+ SELECT NULL AS grp, settings.name AS name, NULL AS value
+ FROM settings
+ WHERE id NOT IN (
+ SELECT DISTINCT settingID
+ FROM prefs
+ WHERE settingID NOTNULL
+ )
+
+ ORDER BY value ASC, grp ASC, name ASC
+ `);
+
+ let actualRows = [];
+ let cols = ["grp", "name", "value"];
+
+ db.executeAsync([stmt], 1, {
+ handleCompletion: function (reason) {
+ arraysOfArraysOK(actualRows, expectedRows);
+ next();
+ },
+ handleResult: function (results) {
+ let row = null;
+ while (row = results.getNextRow()) {
+ actualRows.push(cols.map(c => row.getResultByName(c)));
+ }
+ },
+ handleError: function (err) {
+ do_throw(err);
+ }
+ });
+ stmt.finalize();
+}
+
+function on(event, names, dontRemove) {
+ let args = {
+ reset: function () {
+ for (let prop in this) {
+ if (Array.isArray(this[prop]))
+ this[prop].splice(0, this[prop].length);
+ }
+ },
+ };
+
+ let observers = {};
+
+ names.forEach(function (name) {
+ let obs = {};
+ ["onContentPrefSet", "onContentPrefRemoved"].forEach(function (meth) {
+ obs[meth] = () => do_throw(meth + " should not be called");
+ });
+ obs["onContentPref" + event] = function () {
+ args[name].push(Array.slice(arguments));
+ };
+ observers[name] = obs;
+ args[name] = [];
+ args[name].observer = obs;
+ cps.addObserverForName(name, obs);
+ });
+
+ do_execute_soon(function () {
+ if (!dontRemove)
+ names.forEach(n => cps.removeObserverForName(n, observers[n]));
+ next(args);
+ });
+}
+
+function schemaVersionIs(expectedVersion) {
+ let db = sendMessage("db");
+ equal(db.schemaVersion, expectedVersion);
+}
+
+function wait() {
+ do_execute_soon(next);
+}
+
+function observerArgsOK(actualArgs, expectedArgs) {
+ notEqual(actualArgs, undefined);
+ arraysOfArraysOK(actualArgs, expectedArgs);
+}
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_extractDomain.js b/toolkit/components/contentprefs/tests/unit_cps2/test_extractDomain.js
new file mode 100644
index 000000000..2ec3d6878
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_extractDomain.js
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ let tests = {
+ "http://example.com": "example.com",
+ "http://example.com/": "example.com",
+ "http://example.com/foo/bar/baz": "example.com",
+ "http://subdomain.example.com/foo/bar/baz": "subdomain.example.com",
+ "http://qix.quux.example.com/foo/bar/baz": "qix.quux.example.com",
+ "file:///home/foo/bar": "file:///home/foo/bar",
+ "not a url": "not a url",
+ };
+ let cps = Cc["@mozilla.org/content-pref/service;1"].
+ getService(Ci.nsIContentPrefService2);
+ for (let url in tests) {
+ do_check_eq(cps.extractDomain(url), tests[url]);
+ }
+}
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_getCached.js b/toolkit/components/contentprefs/tests/unit_cps2/test_getCached.js
new file mode 100644
index 000000000..33a965b7f
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_getCached.js
@@ -0,0 +1,95 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ getCachedOK(["a.com", "foo"], false, undefined);
+ getCachedGlobalOK(["foo"], false, undefined);
+ yield true;
+ },
+
+ function* isomorphicDomains() {
+ yield set("a.com", "foo", 1);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["http://a.com/huh", "foo"], true, 1, "a.com");
+ },
+
+ function* names() {
+ yield set("a.com", "foo", 1);
+ getCachedOK(["a.com", "foo"], true, 1);
+
+ yield set("a.com", "bar", 2);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["a.com", "bar"], true, 2);
+
+ yield setGlobal("foo", 3);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["a.com", "bar"], true, 2);
+ getCachedGlobalOK(["foo"], true, 3);
+
+ yield setGlobal("bar", 4);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["a.com", "bar"], true, 2);
+ getCachedGlobalOK(["foo"], true, 3);
+ getCachedGlobalOK(["bar"], true, 4);
+ },
+
+ function* subdomains() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["b.a.com", "foo"], true, 2);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield setGlobal("foo", 7, context);
+ getCachedOK(["a.com", "foo", context], true, 6);
+ getCachedOK(["a.com", "bar", context], true, 2);
+ getCachedGlobalOK(["foo", context], true, 7);
+ getCachedGlobalOK(["bar", context], true, 4);
+ getCachedOK(["b.com", "foo", context], true, 5);
+
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["a.com", "bar"], true, 2);
+ getCachedGlobalOK(["foo"], true, 3);
+ getCachedGlobalOK(["bar"], true, 4);
+ getCachedOK(["b.com", "foo"], true, 5);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.getCachedByDomainAndName(null, "foo", null));
+ do_check_throws(() => cps.getCachedByDomainAndName("", "foo", null));
+ do_check_throws(() => cps.getCachedByDomainAndName("a.com", "", null));
+ do_check_throws(() => cps.getCachedByDomainAndName("a.com", null, null));
+ do_check_throws(() => cps.getCachedGlobal("", null));
+ do_check_throws(() => cps.getCachedGlobal(null, null));
+ yield true;
+ },
+
+ function* casts() {
+ // SQLite casts booleans to integers. This makes sure the values stored in
+ // the cache are the same as the casted values in the database.
+
+ yield set("a.com", "foo", false);
+ yield getOK(["a.com", "foo"], 0, "a.com", true);
+ getCachedOK(["a.com", "foo"], true, 0, "a.com", true);
+
+ yield set("a.com", "bar", true);
+ yield getOK(["a.com", "bar"], 1, "a.com", true);
+ getCachedOK(["a.com", "bar"], true, 1, "a.com", true);
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_getCachedSubdomains.js b/toolkit/components/contentprefs/tests/unit_cps2/test_getCachedSubdomains.js
new file mode 100644
index 000000000..9f2599708
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_getCachedSubdomains.js
@@ -0,0 +1,186 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ getCachedSubdomainsOK(["a.com", "foo"], []);
+ yield true;
+ },
+
+ function* isomorphicDomains() {
+ yield set("a.com", "foo", 1);
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ getCachedSubdomainsOK(["http://a.com/huh", "foo"], [["a.com", 1]]);
+ },
+
+ function* names() {
+ yield set("a.com", "foo", 1);
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+
+ yield set("a.com", "bar", 2);
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+
+ yield setGlobal("foo", 3);
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+ getCachedGlobalOK(["foo"], true, 3);
+
+ yield setGlobal("bar", 4);
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+ getCachedGlobalOK(["foo"], true, 3);
+ getCachedGlobalOK(["bar"], true, 4);
+ },
+
+ function* subdomains() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1], ["b.a.com", 2]]);
+ getCachedSubdomainsOK(["b.a.com", "foo"], [["b.a.com", 2]]);
+ },
+
+ function* populateViaGet() {
+ yield cps.getByDomainAndName("a.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+
+ yield cps.getGlobal("foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+ },
+
+ function* populateViaGetSubdomains() {
+ yield cps.getBySubdomainAndName("a.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ },
+
+ function* populateViaRemove() {
+ yield cps.removeByDomainAndName("a.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+
+ yield cps.removeBySubdomainAndName("b.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", undefined]]);
+
+ yield cps.removeGlobal("foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", undefined]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+
+ yield set("a.com", "foo", 1);
+ yield cps.removeByDomainAndName("a.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", undefined]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+
+ yield set("a.com", "foo", 2);
+ yield set("b.a.com", "foo", 3);
+ yield cps.removeBySubdomainAndName("a.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"],
+ [["a.com", undefined], ["b.a.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", undefined]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+ getCachedSubdomainsOK(["b.a.com", "foo"], [["b.a.com", undefined]]);
+
+ yield setGlobal("foo", 4);
+ yield cps.removeGlobal("foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"],
+ [["a.com", undefined], ["b.a.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", undefined]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+ getCachedSubdomainsOK(["b.a.com", "foo"], [["b.a.com", undefined]]);
+ },
+
+ function* populateViaRemoveByDomain() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield set("b.a.com", "foo", 3);
+ yield set("b.a.com", "bar", 4);
+ yield cps.removeByDomain("a.com", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"],
+ [["a.com", undefined], ["b.a.com", 3]]);
+ getCachedSubdomainsOK(["a.com", "bar"],
+ [["a.com", undefined], ["b.a.com", 4]]);
+
+ yield set("a.com", "foo", 5);
+ yield set("a.com", "bar", 6);
+ yield cps.removeBySubdomain("a.com", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"],
+ [["a.com", undefined], ["b.a.com", undefined]]);
+ getCachedSubdomainsOK(["a.com", "bar"],
+ [["a.com", undefined], ["b.a.com", undefined]]);
+
+ yield setGlobal("foo", 7);
+ yield setGlobal("bar", 8);
+ yield cps.removeAllGlobals(null, makeCallback());
+ getCachedGlobalOK(["foo"], true, undefined);
+ getCachedGlobalOK(["bar"], true, undefined);
+ },
+
+ function* populateViaRemoveAllDomains() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield set("b.com", "foo", 3);
+ yield set("b.com", "bar", 4);
+ yield cps.removeAllDomains(null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", undefined]]);
+ getCachedSubdomainsOK(["b.com", "bar"], [["b.com", undefined]]);
+ },
+
+ function* populateViaRemoveByName() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield cps.removeByName("foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+ getCachedGlobalOK(["bar"], true, 4);
+
+ yield cps.removeByName("bar", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", undefined]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", undefined]]);
+ getCachedGlobalOK(["foo"], true, undefined);
+ getCachedGlobalOK(["bar"], true, undefined);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield setGlobal("foo", 7, context);
+ getCachedSubdomainsOK(["a.com", "foo", context], [["a.com", 6]]);
+ getCachedSubdomainsOK(["a.com", "bar", context], [["a.com", 2]]);
+ getCachedGlobalOK(["foo", context], true, 7);
+ getCachedGlobalOK(["bar", context], true, 4);
+ getCachedSubdomainsOK(["b.com", "foo", context], [["b.com", 5]]);
+
+ getCachedSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ getCachedSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+ getCachedGlobalOK(["foo"], true, 3);
+ getCachedGlobalOK(["bar"], true, 4);
+ getCachedSubdomainsOK(["b.com", "foo"], [["b.com", 5]]);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.getCachedBySubdomainAndName(null, "foo", null));
+ do_check_throws(() => cps.getCachedBySubdomainAndName("", "foo", null));
+ do_check_throws(() => cps.getCachedBySubdomainAndName("a.com", "", null));
+ do_check_throws(() => cps.getCachedBySubdomainAndName("a.com", null, null));
+ yield true;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_getSubdomains.js b/toolkit/components/contentprefs/tests/unit_cps2/test_getSubdomains.js
new file mode 100644
index 000000000..d08d6fe69
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_getSubdomains.js
@@ -0,0 +1,68 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* get_nonexistent() {
+ yield getSubdomainsOK(["a.com", "foo"], []);
+ },
+
+ function* isomorphicDomains() {
+ yield set("a.com", "foo", 1);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ yield getSubdomainsOK(["http://a.com/huh", "foo"], [["a.com", 1]]);
+ },
+
+ function* names() {
+ yield set("a.com", "foo", 1);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+
+ yield set("a.com", "bar", 2);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ yield getSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+
+ yield setGlobal("foo", 3);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ yield getSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+ },
+
+ function* subdomains() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 1], ["b.a.com", 2]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], [["b.a.com", 2]]);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield setGlobal("foo", 7, context);
+ yield getSubdomainsOK(["a.com", "foo", context], [["a.com", 6]]);
+ yield getSubdomainsOK(["a.com", "bar", context], [["a.com", 2]]);
+ yield getSubdomainsOK(["b.com", "foo", context], [["b.com", 5]]);
+
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 1]]);
+ yield getSubdomainsOK(["a.com", "bar"], [["a.com", 2]]);
+ yield getSubdomainsOK(["b.com", "foo"], [["b.com", 5]]);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.getBySubdomainAndName(null, "foo", null, {}));
+ do_check_throws(() => cps.getBySubdomainAndName("", "foo", null, {}));
+ do_check_throws(() => cps.getBySubdomainAndName("a.com", "", null, {}));
+ do_check_throws(() => cps.getBySubdomainAndName("a.com", null, null, {}));
+ do_check_throws(() => cps.getBySubdomainAndName("a.com", "foo", null, null));
+ yield true;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_migrationToSchema4.js b/toolkit/components/contentprefs/tests/unit_cps2/test_migrationToSchema4.js
new file mode 100644
index 000000000..85d23e355
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_migrationToSchema4.js
@@ -0,0 +1,82 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+// Dump of version we migrate from
+var schema_version3 = `
+PRAGMA foreign_keys=OFF;
+BEGIN TRANSACTION;
+ CREATE TABLE groups (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
+ INSERT INTO "groups" VALUES(1,'foo.com');
+ INSERT INTO "groups" VALUES(2,'bar.com');
+
+ CREATE TABLE settings (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
+ INSERT INTO "settings" VALUES(1,'zoom-setting');
+ INSERT INTO "settings" VALUES(2,'dir-setting');
+
+ CREATE TABLE prefs (id INTEGER PRIMARY KEY, groupID INTEGER REFERENCES groups(id), settingID INTEGER NOT NULL REFERENCES settings(id), value BLOB);
+ INSERT INTO "prefs" VALUES(1,1,1,0.5);
+ INSERT INTO "prefs" VALUES(2,1,2,'/download/dir');
+ INSERT INTO "prefs" VALUES(3,2,1,0.3);
+ INSERT INTO "prefs" VALUES(4,NULL,1,0.1);
+
+ CREATE INDEX groups_idx ON groups(name);
+ CREATE INDEX settings_idx ON settings(name);
+ CREATE INDEX prefs_idx ON prefs(groupID, settingID);
+COMMIT;`;
+
+function prepareVersion3Schema(callback) {
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+
+ var dbFile = dirService.get("ProfD", Ci.nsIFile);
+ dbFile.append("content-prefs.sqlite");
+
+ var dbService = Cc["@mozilla.org/storage/service;1"].
+ getService(Ci.mozIStorageService);
+ ok(!dbFile.exists(), "Db should not exist yet.");
+
+ var dbConnection = dbService.openDatabase(dbFile);
+ equal(dbConnection.schemaVersion, 0);
+
+ dbConnection.executeSimpleSQL(schema_version3);
+ dbConnection.schemaVersion = 3;
+
+ dbConnection.close();
+}
+
+function run_test() {
+ prepareVersion3Schema();
+ runAsyncTests(tests, true);
+}
+
+
+// WARNING: Database will reset after every test. This limitation comes from
+// the fact that we ContentPrefService constructor is run only once per test file
+// and so migration will be run only once.
+var tests = [
+ function* testMigration() {
+ // Test migrated db content.
+ schemaVersionIs(4);
+ let dbExpectedState = [
+ [null, "zoom-setting", 0.1],
+ ["bar.com", "zoom-setting", 0.3],
+ ["foo.com", "zoom-setting", 0.5],
+ ["foo.com", "dir-setting", "/download/dir"],
+ ];
+ yield dbOK(dbExpectedState);
+
+ // Migrated fields should have timestamp set to 0.
+ yield cps.removeAllDomainsSince(1000, null, makeCallback());
+ yield dbOK(dbExpectedState);
+
+ yield cps.removeAllDomainsSince(0, null, makeCallback());
+ yield dbOK([[null, "zoom-setting", 0.1]]);
+
+ // Test that dates are present after migration (column is added).
+ const timestamp = 1234;
+ yield setWithDate("a.com", "pref-name", "val", timestamp);
+ let actualTimestamp = yield getDate("a.com", "pref-name");
+ equal(actualTimestamp, timestamp);
+ }
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_observers.js b/toolkit/components/contentprefs/tests/unit_cps2/test_observers.js
new file mode 100644
index 000000000..c48918cd9
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_observers.js
@@ -0,0 +1,178 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+let global = this;
+
+function run_test() {
+ var allTests = [];
+ for (var i = 0; i < tests.length; i++) {
+ // Generate two wrappers of each test function that invoke the original test with an
+ // appropriate privacy context.
+ var pub = eval('var f = function* ' + tests[i].name + '() { yield tests[' + i + ']({ usePrivateBrowsing: false }); }; f');
+ var priv = eval('var f = function* ' + tests[i].name + '_private() { yield tests[' + i + ']({ usePrivateBrowsing: true }); }; f');
+ allTests.push(pub);
+ allTests.push(priv);
+ }
+ allTests = allTests.concat(specialTests);
+ runAsyncTests(allTests);
+}
+
+var tests = [
+
+ function* observerForName_set(context) {
+ yield set("a.com", "foo", 1, context);
+ let args = yield on("Set", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [["a.com", "foo", 1, context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [["a.com", "foo", 1, context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+
+ yield setGlobal("foo", 2, context);
+ args = yield on("Set", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [[null, "foo", 2, context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [[null, "foo", 2, context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+ },
+
+ function* observerForName_remove(context) {
+ yield set("a.com", "foo", 1, context);
+ yield setGlobal("foo", 2, context);
+
+ yield cps.removeByDomainAndName("a.com", "bogus", context, makeCallback());
+ let args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, []);
+ observerArgsOK(args.null, []);
+ observerArgsOK(args.bar, []);
+
+ yield cps.removeByDomainAndName("a.com", "foo", context, makeCallback());
+ args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [["a.com", "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [["a.com", "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+
+ yield cps.removeGlobal("foo", context, makeCallback());
+ args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [[null, "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [[null, "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+ },
+
+ function* observerForName_removeByDomain(context) {
+ yield set("a.com", "foo", 1, context);
+ yield set("b.a.com", "bar", 2, context);
+ yield setGlobal("foo", 3, context);
+
+ yield cps.removeByDomain("bogus", context, makeCallback());
+ let args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, []);
+ observerArgsOK(args.null, []);
+ observerArgsOK(args.bar, []);
+
+ yield cps.removeBySubdomain("a.com", context, makeCallback());
+ args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [["a.com", "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [["a.com", "foo", context.usePrivateBrowsing], ["b.a.com", "bar", context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, [["b.a.com", "bar", context.usePrivateBrowsing]]);
+
+ yield cps.removeAllGlobals(context, makeCallback());
+ args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [[null, "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [[null, "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+ },
+
+ function* observerForName_removeAllDomains(context) {
+ yield set("a.com", "foo", 1, context);
+ yield setGlobal("foo", 2, context);
+ yield set("b.com", "bar", 3, context);
+
+ yield cps.removeAllDomains(context, makeCallback());
+ let args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [["a.com", "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [["a.com", "foo", context.usePrivateBrowsing], ["b.com", "bar", context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, [["b.com", "bar", context.usePrivateBrowsing]]);
+ },
+
+ function* observerForName_removeByName(context) {
+ yield set("a.com", "foo", 1, context);
+ yield set("a.com", "bar", 2, context);
+ yield setGlobal("foo", 3, context);
+
+ yield cps.removeByName("bogus", context, makeCallback());
+ let args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, []);
+ observerArgsOK(args.null, []);
+ observerArgsOK(args.bar, []);
+
+ yield cps.removeByName("foo", context, makeCallback());
+ args = yield on("Removed", ["foo", null, "bar"]);
+ observerArgsOK(args.foo, [["a.com", "foo", context.usePrivateBrowsing], [null, "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.null, [["a.com", "foo", context.usePrivateBrowsing], [null, "foo", context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+ },
+
+ function* removeObserverForName(context) {
+ let args = yield on("Set", ["foo", null, "bar"], true);
+
+ cps.removeObserverForName("foo", args.foo.observer);
+ yield set("a.com", "foo", 1, context);
+ yield wait();
+ observerArgsOK(args.foo, []);
+ observerArgsOK(args.null, [["a.com", "foo", 1, context.usePrivateBrowsing]]);
+ observerArgsOK(args.bar, []);
+ args.reset();
+
+ cps.removeObserverForName(null, args.null.observer);
+ yield set("a.com", "foo", 2, context);
+ yield wait();
+ observerArgsOK(args.foo, []);
+ observerArgsOK(args.null, []);
+ observerArgsOK(args.bar, []);
+ args.reset();
+ },
+];
+
+// These tests are for functionality that doesn't behave the same way in private and public
+// contexts, so the expected results cannot be automatically generated like the previous tests.
+var specialTests = [
+ function* observerForName_removeAllDomainsSince() {
+ yield setWithDate("a.com", "foo", 1, 100, null);
+ yield setWithDate("b.com", "foo", 2, 200, null);
+ yield setWithDate("c.com", "foo", 3, 300, null);
+
+ yield setWithDate("a.com", "bar", 1, 0, null);
+ yield setWithDate("b.com", "bar", 2, 100, null);
+ yield setWithDate("c.com", "bar", 3, 200, null);
+ yield setGlobal("foo", 2, null);
+
+ yield cps.removeAllDomainsSince(200, null, makeCallback());
+
+ let args = yield on("Removed", ["foo", "bar", null]);
+
+ observerArgsOK(args.foo, [["b.com", "foo", false], ["c.com", "foo", false]]);
+ observerArgsOK(args.bar, [["c.com", "bar", false]]);
+ observerArgsOK(args.null, [["b.com", "foo", false], ["c.com", "bar", false], ["c.com", "foo", false]]);
+ },
+
+ function* observerForName_removeAllDomainsSince_private() {
+ let context = {usePrivateBrowsing: true};
+ yield setWithDate("a.com", "foo", 1, 100, context);
+ yield setWithDate("b.com", "foo", 2, 200, context);
+ yield setWithDate("c.com", "foo", 3, 300, context);
+
+ yield setWithDate("a.com", "bar", 1, 0, context);
+ yield setWithDate("b.com", "bar", 2, 100, context);
+ yield setWithDate("c.com", "bar", 3, 200, context);
+ yield setGlobal("foo", 2, context);
+
+ yield cps.removeAllDomainsSince(200, context, makeCallback());
+
+ let args = yield on("Removed", ["foo", "bar", null]);
+
+ observerArgsOK(args.foo, [["a.com", "foo", true], ["b.com", "foo", true], ["c.com", "foo", true]]);
+ observerArgsOK(args.bar, [["a.com", "bar", true], ["b.com", "bar", true], ["c.com", "bar", true]]);
+ observerArgsOK(args.null, [["a.com", "foo", true], ["a.com", "bar", true],
+ ["b.com", "foo", true], ["b.com", "bar", true],
+ ["c.com", "foo", true], ["c.com", "bar", true]]);
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_remove.js b/toolkit/components/contentprefs/tests/unit_cps2/test_remove.js
new file mode 100644
index 000000000..9853293fc
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_remove.js
@@ -0,0 +1,222 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ yield set("a.com", "foo", 1);
+ yield setGlobal("foo", 2);
+
+ yield cps.removeByDomainAndName("a.com", "bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+
+ yield cps.removeBySubdomainAndName("a.com", "bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+
+ yield cps.removeGlobal("bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+
+ yield cps.removeByDomainAndName("bogus", "bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+ },
+
+ function* isomorphicDomains() {
+ yield set("a.com", "foo", 1);
+ yield cps.removeByDomainAndName("a.com", "foo", null, makeCallback());
+ yield dbOK([]);
+ yield getOK(["a.com", "foo"], undefined);
+
+ yield set("a.com", "foo", 2);
+ yield cps.removeByDomainAndName("http://a.com/huh", "foo", null,
+ makeCallback());
+ yield dbOK([]);
+ yield getOK(["a.com", "foo"], undefined);
+ },
+
+ function* names() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+
+ yield cps.removeByDomainAndName("a.com", "foo", null, makeCallback());
+ yield dbOK([
+ ["a.com", "bar", 2],
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+
+ yield cps.removeGlobal("foo", null, makeCallback());
+ yield dbOK([
+ ["a.com", "bar", 2],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], 4);
+
+ yield cps.removeByDomainAndName("a.com", "bar", null, makeCallback());
+ yield dbOK([
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], 4);
+
+ yield cps.removeGlobal("bar", null, makeCallback());
+ yield dbOK([
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], undefined);
+ },
+
+ function* subdomains() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ yield cps.removeByDomainAndName("a.com", "foo", null, makeCallback());
+ yield dbOK([
+ ["b.a.com", "foo", 2],
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], [["b.a.com", 2]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], [["b.a.com", 2]]);
+
+ yield set("a.com", "foo", 3);
+ yield cps.removeBySubdomainAndName("a.com", "foo", null, makeCallback());
+ yield dbOK([
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], []);
+ yield getSubdomainsOK(["b.a.com", "foo"], []);
+
+ yield set("a.com", "foo", 4);
+ yield set("b.a.com", "foo", 5);
+ yield cps.removeByDomainAndName("b.a.com", "foo", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 4],
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 4]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], []);
+
+ yield set("b.a.com", "foo", 6);
+ yield cps.removeBySubdomainAndName("b.a.com", "foo", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 4],
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 4]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], []);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield setGlobal("qux", 5);
+ yield set("b.com", "foo", 6);
+ yield set("b.com", "bar", 7);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 8, context);
+ yield setGlobal("foo", 9, context);
+ yield cps.removeByDomainAndName("a.com", "foo", context, makeCallback());
+ yield cps.removeGlobal("foo", context, makeCallback());
+ yield cps.removeGlobal("qux", context, makeCallback());
+ yield cps.removeByDomainAndName("b.com", "foo", context, makeCallback());
+ yield dbOK([
+ ["a.com", "bar", 2],
+ [null, "bar", 4],
+ ["b.com", "bar", 7],
+ ]);
+ yield getOK(["a.com", "foo", context], undefined);
+ yield getOK(["a.com", "bar", context], 2);
+ yield getGlobalOK(["foo", context], undefined);
+ yield getGlobalOK(["bar", context], 4);
+ yield getGlobalOK(["qux", context], undefined);
+ yield getOK(["b.com", "foo", context], undefined);
+ yield getOK(["b.com", "bar", context], 7);
+
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], 4);
+ yield getGlobalOK(["qux"], undefined);
+ yield getOK(["b.com", "foo"], undefined);
+ yield getOK(["b.com", "bar"], 7);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.removeByDomainAndName(null, "foo", null));
+ do_check_throws(() => cps.removeByDomainAndName("", "foo", null));
+ do_check_throws(() => cps.removeByDomainAndName("a.com", "foo", null,
+ "bogus"));
+ do_check_throws(() => cps.removeBySubdomainAndName(null, "foo",
+ null));
+ do_check_throws(() => cps.removeBySubdomainAndName("", "foo", null));
+ do_check_throws(() => cps.removeBySubdomainAndName("a.com", "foo",
+ null, "bogus"));
+ do_check_throws(() => cps.removeGlobal("", null));
+ do_check_throws(() => cps.removeGlobal(null, null));
+ do_check_throws(() => cps.removeGlobal("foo", null, "bogus"));
+ yield true;
+ },
+
+ function* removeByDomainAndName_invalidateCache() {
+ yield set("a.com", "foo", 1);
+ getCachedOK(["a.com", "foo"], true, 1);
+ cps.removeByDomainAndName("a.com", "foo", null, makeCallback());
+ getCachedOK(["a.com", "foo"], false);
+ yield;
+ },
+
+ function* removeBySubdomainAndName_invalidateCache() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ getCachedSubdomainsOK(["a.com", "foo"], [
+ ["a.com", 1],
+ ["b.a.com", 2],
+ ]);
+ cps.removeBySubdomainAndName("a.com", "foo", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], []);
+ yield;
+ },
+
+ function* removeGlobal_invalidateCache() {
+ yield setGlobal("foo", 1);
+ getCachedGlobalOK(["foo"], true, 1);
+ cps.removeGlobal("foo", null, makeCallback());
+ getCachedGlobalOK(["foo"], false);
+ yield;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomains.js b/toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomains.js
new file mode 100644
index 000000000..63e1b0552
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomains.js
@@ -0,0 +1,87 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ yield setGlobal("foo", 1);
+ yield cps.removeAllDomains(null, makeCallback());
+ yield dbOK([
+ [null, "foo", 1],
+ ]);
+ yield getGlobalOK(["foo"], 1);
+ },
+
+ function* domains() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+ yield set("b.com", "bar", 6);
+
+ yield cps.removeAllDomains(null, makeCallback());
+ yield dbOK([
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], undefined);
+ yield getOK(["b.com", "bar"], undefined);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield setGlobal("foo", 7, context);
+ yield cps.removeAllDomains(context, makeCallback());
+ yield dbOK([
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo", context], undefined);
+ yield getOK(["a.com", "bar", context], undefined);
+ yield getGlobalOK(["foo", context], 7);
+ yield getGlobalOK(["bar", context], 4);
+ yield getOK(["b.com", "foo", context], undefined);
+
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], undefined);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.removeAllDomains(null, "bogus"));
+ yield true;
+ },
+
+ function* invalidateCache() {
+ yield set("a.com", "foo", 1);
+ yield set("b.com", "bar", 2);
+ yield setGlobal("baz", 3);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["b.com", "bar"], true, 2);
+ getCachedGlobalOK(["baz"], true, 3);
+ cps.removeAllDomains(null, makeCallback());
+ getCachedOK(["a.com", "foo"], false);
+ getCachedOK(["b.com", "bar"], false);
+ getCachedGlobalOK(["baz"], true, 3);
+ yield;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomainsSince.js b/toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomainsSince.js
new file mode 100644
index 000000000..fa0bf31c3
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_removeAllDomainsSince.js
@@ -0,0 +1,111 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ yield setGlobal("foo", 1);
+ yield cps.removeAllDomainsSince(0, null, makeCallback());
+ yield getGlobalOK(["foo"], 1);
+ },
+
+ function* domainsAll() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+ yield set("b.com", "bar", 6);
+
+ yield cps.removeAllDomainsSince(0, null, makeCallback());
+ yield dbOK([
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], undefined);
+ yield getOK(["b.com", "bar"], undefined);
+ },
+
+ function* domainsWithDate() {
+ yield setWithDate("a.com", "foobar", 0, 0);
+ yield setWithDate("a.com", "foo", 1, 1000);
+ yield setWithDate("a.com", "bar", 2, 4000);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield setWithDate("b.com", "foo", 5, 2000);
+ yield setWithDate("b.com", "bar", 6, 3000);
+ yield setWithDate("b.com", "foobar", 7, 1000);
+
+ yield cps.removeAllDomainsSince(2000, null, makeCallback());
+ yield dbOK([
+ ["a.com", "foobar", 0],
+ ["a.com", "foo", 1],
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ["b.com", "foobar", 7],
+ ]);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield setGlobal("foo", 7, context);
+ yield cps.removeAllDomainsSince(0, context, makeCallback());
+ yield dbOK([
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo", context], undefined);
+ yield getOK(["a.com", "bar", context], undefined);
+ yield getGlobalOK(["foo", context], 7);
+ yield getGlobalOK(["bar", context], 4);
+ yield getOK(["b.com", "foo", context], undefined);
+
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], undefined);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.removeAllDomainsSince(null, "bogus"));
+ yield true;
+ },
+
+ function* invalidateCache() {
+ yield setWithDate("a.com", "foobar", 0, 0);
+ yield setWithDate("a.com", "foo", 1, 1000);
+ yield setWithDate("a.com", "bar", 2, 4000);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield setWithDate("b.com", "foo", 5, 2000);
+ yield setWithDate("b.com", "bar", 6, 3000);
+ yield setWithDate("b.com", "foobar", 7, 1000);
+ cps.removeAllDomainsSince(0, null, makeCallback());
+ getCachedOK(["a.com", "foobar"], false);
+ getCachedOK(["a.com", "foo"], false);
+ getCachedOK(["a.com", "bar"], false);
+ getCachedGlobalOK(["foo"], true, 3);
+ getCachedGlobalOK(["bar"], true, 4);
+ getCachedOK(["b.com", "foo"], false);
+ getCachedOK(["b.com", "bar"], false);
+ getCachedOK(["b.com", "foobar"], false);
+ yield true;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_removeByDomain.js b/toolkit/components/contentprefs/tests/unit_cps2/test_removeByDomain.js
new file mode 100644
index 000000000..1cf6bd8f2
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_removeByDomain.js
@@ -0,0 +1,199 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ yield set("a.com", "foo", 1);
+ yield setGlobal("foo", 2);
+
+ yield cps.removeByDomain("bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+
+ yield cps.removeBySubdomain("bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+ },
+
+ function* isomorphicDomains() {
+ yield set("a.com", "foo", 1);
+ yield cps.removeByDomain("a.com", null, makeCallback());
+ yield dbOK([]);
+ yield getOK(["a.com", "foo"], undefined);
+
+ yield set("a.com", "foo", 2);
+ yield cps.removeByDomain("http://a.com/huh", null, makeCallback());
+ yield dbOK([]);
+ yield getOK(["a.com", "foo"], undefined);
+ },
+
+ function* domains() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+ yield set("b.com", "bar", 6);
+
+ yield cps.removeByDomain("a.com", null, makeCallback());
+ yield dbOK([
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ["b.com", "foo", 5],
+ ["b.com", "bar", 6],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], 5);
+ yield getOK(["b.com", "bar"], 6);
+
+ yield cps.removeAllGlobals(null, makeCallback());
+ yield dbOK([
+ ["b.com", "foo", 5],
+ ["b.com", "bar", 6],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], undefined);
+ yield getOK(["b.com", "foo"], 5);
+ yield getOK(["b.com", "bar"], 6);
+
+ yield cps.removeByDomain("b.com", null, makeCallback());
+ yield dbOK([
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], undefined);
+ yield getOK(["b.com", "foo"], undefined);
+ yield getOK(["b.com", "bar"], undefined);
+ },
+
+ function* subdomains() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ yield cps.removeByDomain("a.com", null, makeCallback());
+ yield dbOK([
+ ["b.a.com", "foo", 2],
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], [["b.a.com", 2]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], [["b.a.com", 2]]);
+
+ yield set("a.com", "foo", 3);
+ yield cps.removeBySubdomain("a.com", null, makeCallback());
+ yield dbOK([
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], []);
+ yield getSubdomainsOK(["b.a.com", "foo"], []);
+
+ yield set("a.com", "foo", 4);
+ yield set("b.a.com", "foo", 5);
+ yield cps.removeByDomain("b.a.com", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 4],
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 4]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], []);
+
+ yield set("b.a.com", "foo", 6);
+ yield cps.removeBySubdomain("b.a.com", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 4],
+ ]);
+ yield getSubdomainsOK(["a.com", "foo"], [["a.com", 4]]);
+ yield getSubdomainsOK(["b.a.com", "foo"], []);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield set("b.com", "foo", 7, context);
+ yield setGlobal("foo", 8, context);
+ yield cps.removeByDomain("a.com", context, makeCallback());
+ yield getOK(["b.com", "foo", context], 7);
+ yield getGlobalOK(["foo", context], 8);
+ yield cps.removeAllGlobals(context, makeCallback());
+ yield dbOK([
+ ["b.com", "foo", 5],
+ ]);
+ yield getOK(["a.com", "foo", context], undefined);
+ yield getOK(["a.com", "bar", context], undefined);
+ yield getGlobalOK(["foo", context], undefined);
+ yield getGlobalOK(["bar", context], undefined);
+ yield getOK(["b.com", "foo", context], 5);
+
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], undefined);
+ yield getOK(["b.com", "foo"], 5);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.removeByDomain(null, null));
+ do_check_throws(() => cps.removeByDomain("", null));
+ do_check_throws(() => cps.removeByDomain("a.com", null, "bogus"));
+ do_check_throws(() => cps.removeBySubdomain(null, null));
+ do_check_throws(() => cps.removeBySubdomain("", null));
+ do_check_throws(() => cps.removeBySubdomain("a.com", null, "bogus"));
+ do_check_throws(() => cps.removeAllGlobals(null, "bogus"));
+ yield true;
+ },
+
+ function* removeByDomain_invalidateCache() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["a.com", "bar"], true, 2);
+ cps.removeByDomain("a.com", null, makeCallback());
+ getCachedOK(["a.com", "foo"], false);
+ getCachedOK(["a.com", "bar"], false);
+ yield;
+ },
+
+ function* removeBySubdomain_invalidateCache() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ getCachedSubdomainsOK(["a.com", "foo"], [
+ ["a.com", 1],
+ ["b.a.com", 2],
+ ]);
+ cps.removeBySubdomain("a.com", null, makeCallback());
+ getCachedSubdomainsOK(["a.com", "foo"], []);
+ yield;
+ },
+
+ function* removeAllGlobals_invalidateCache() {
+ yield setGlobal("foo", 1);
+ yield setGlobal("bar", 2);
+ getCachedGlobalOK(["foo"], true, 1);
+ getCachedGlobalOK(["bar"], true, 2);
+ cps.removeAllGlobals(null, makeCallback());
+ getCachedGlobalOK(["foo"], false);
+ getCachedGlobalOK(["bar"], false);
+ yield;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_removeByName.js b/toolkit/components/contentprefs/tests/unit_cps2/test_removeByName.js
new file mode 100644
index 000000000..fa04656e2
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_removeByName.js
@@ -0,0 +1,96 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* nonexistent() {
+ yield set("a.com", "foo", 1);
+ yield setGlobal("foo", 2);
+
+ yield cps.removeByName("bogus", null, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getGlobalOK(["foo"], 2);
+ },
+
+ function* names() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+ yield set("b.com", "bar", 6);
+
+ yield cps.removeByName("foo", null, makeCallback());
+ yield dbOK([
+ ["a.com", "bar", 2],
+ [null, "bar", 4],
+ ["b.com", "bar", 6],
+ ]);
+ yield getOK(["a.com", "foo"], undefined);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], undefined);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], undefined);
+ yield getOK(["b.com", "bar"], 6);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+ yield set("b.com", "bar", 6);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 7, context);
+ yield setGlobal("foo", 8, context);
+ yield set("b.com", "bar", 9, context);
+ yield cps.removeByName("bar", context, makeCallback());
+ yield dbOK([
+ ["a.com", "foo", 1],
+ [null, "foo", 3],
+ ["b.com", "foo", 5],
+ ]);
+ yield getOK(["a.com", "foo", context], 7);
+ yield getOK(["a.com", "bar", context], undefined);
+ yield getGlobalOK(["foo", context], 8);
+ yield getGlobalOK(["bar", context], undefined);
+ yield getOK(["b.com", "foo", context], 5);
+ yield getOK(["b.com", "bar", context], undefined);
+
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["a.com", "bar"], undefined);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], undefined);
+ yield getOK(["b.com", "foo"], 5);
+ yield getOK(["b.com", "bar"], undefined);
+ },
+
+ function* erroneous() {
+ do_check_throws(() => cps.removeByName("", null));
+ do_check_throws(() => cps.removeByName(null, null));
+ do_check_throws(() => cps.removeByName("foo", null, "bogus"));
+ yield true;
+ },
+
+ function* invalidateCache() {
+ yield set("a.com", "foo", 1);
+ yield set("b.com", "foo", 2);
+ getCachedOK(["a.com", "foo"], true, 1);
+ getCachedOK(["b.com", "foo"], true, 2);
+ cps.removeByName("foo", null, makeCallback());
+ getCachedOK(["a.com", "foo"], false);
+ getCachedOK(["b.com", "foo"], false);
+ yield;
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_service.js b/toolkit/components/contentprefs/tests/unit_cps2/test_service.js
new file mode 100644
index 000000000..75292063e
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_service.js
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ let serv = Cc["@mozilla.org/content-pref/service;1"].
+ getService(Ci.nsIContentPrefService2);
+ do_check_eq(serv.QueryInterface(Ci.nsIContentPrefService2), serv);
+ do_check_eq(serv.QueryInterface(Ci.nsISupports), serv);
+ let val = serv.QueryInterface(Ci.nsIContentPrefService);
+ do_check_true(val instanceof Ci.nsIContentPrefService);
+}
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/test_setGet.js b/toolkit/components/contentprefs/tests/unit_cps2/test_setGet.js
new file mode 100644
index 000000000..b10a05bbc
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/test_setGet.js
@@ -0,0 +1,206 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+function run_test() {
+ runAsyncTests(tests);
+}
+
+var tests = [
+
+ function* get_nonexistent() {
+ yield getOK(["a.com", "foo"], undefined);
+ yield getGlobalOK(["foo"], undefined);
+ },
+
+ function* isomorphicDomains() {
+ yield set("a.com", "foo", 1);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["http://a.com/huh", "foo"], 1, "a.com");
+
+ yield set("http://a.com/huh", "foo", 2);
+ yield dbOK([
+ ["a.com", "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 2);
+ yield getOK(["http://a.com/yeah", "foo"], 2, "a.com");
+ },
+
+ function* names() {
+ yield set("a.com", "foo", 1);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+
+ yield set("a.com", "bar", 2);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ["a.com", "bar", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["a.com", "bar"], 2);
+
+ yield setGlobal("foo", 3);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ["a.com", "bar", 2],
+ [null, "foo", 3],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], 3);
+
+ yield setGlobal("bar", 4);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ["a.com", "bar", 2],
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ },
+
+ function* subdomains() {
+ yield set("a.com", "foo", 1);
+ yield set("b.a.com", "foo", 2);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ["b.a.com", "foo", 2],
+ ]);
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["b.a.com", "foo"], 2);
+ },
+
+ function* privateBrowsing() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield setGlobal("foo", 3);
+ yield setGlobal("bar", 4);
+ yield set("b.com", "foo", 5);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("a.com", "foo", 6, context);
+ yield setGlobal("foo", 7, context);
+ yield dbOK([
+ ["a.com", "foo", 1],
+ ["a.com", "bar", 2],
+ [null, "foo", 3],
+ [null, "bar", 4],
+ ["b.com", "foo", 5],
+ ]);
+ yield getOK(["a.com", "foo", context], 6, "a.com");
+ yield getOK(["a.com", "bar", context], 2);
+ yield getGlobalOK(["foo", context], 7);
+ yield getGlobalOK(["bar", context], 4);
+ yield getOK(["b.com", "foo", context], 5);
+
+ yield getOK(["a.com", "foo"], 1);
+ yield getOK(["a.com", "bar"], 2);
+ yield getGlobalOK(["foo"], 3);
+ yield getGlobalOK(["bar"], 4);
+ yield getOK(["b.com", "foo"], 5);
+ },
+
+ function* set_erroneous() {
+ do_check_throws(() => cps.set(null, "foo", 1, null));
+ do_check_throws(() => cps.set("", "foo", 1, null));
+ do_check_throws(() => cps.set("a.com", "", 1, null));
+ do_check_throws(() => cps.set("a.com", null, 1, null));
+ do_check_throws(() => cps.set("a.com", "foo", undefined, null));
+ do_check_throws(() => cps.set("a.com", "foo", 1, null, "bogus"));
+ do_check_throws(() => cps.setGlobal("", 1, null));
+ do_check_throws(() => cps.setGlobal(null, 1, null));
+ do_check_throws(() => cps.setGlobal("foo", undefined, null));
+ do_check_throws(() => cps.setGlobal("foo", 1, null, "bogus"));
+ yield true;
+ },
+
+ function* get_erroneous() {
+ do_check_throws(() => cps.getByDomainAndName(null, "foo", null, {}));
+ do_check_throws(() => cps.getByDomainAndName("", "foo", null, {}));
+ do_check_throws(() => cps.getByDomainAndName("a.com", "", null, {}));
+ do_check_throws(() => cps.getByDomainAndName("a.com", null, null, {}));
+ do_check_throws(() => cps.getByDomainAndName("a.com", "foo", null, null));
+ do_check_throws(() => cps.getGlobal("", null, {}));
+ do_check_throws(() => cps.getGlobal(null, null, {}));
+ do_check_throws(() => cps.getGlobal("foo", null, null));
+ yield true;
+ },
+
+ function* set_invalidateCache() {
+ // (1) Set a pref and wait for it to finish.
+ yield set("a.com", "foo", 1);
+
+ // (2) It should be cached.
+ getCachedOK(["a.com", "foo"], true, 1);
+
+ // (3) Set the pref to a new value but don't wait for it to finish.
+ cps.set("a.com", "foo", 2, null, {
+ handleCompletion: function () {
+ // (6) The pref should be cached after setting it.
+ getCachedOK(["a.com", "foo"], true, 2);
+ },
+ });
+
+ // (4) Group "a.com" and name "foo" should no longer be cached.
+ getCachedOK(["a.com", "foo"], false);
+
+ // (5) Call getByDomainAndName.
+ var fetchedPref;
+ cps.getByDomainAndName("a.com", "foo", null, {
+ handleResult: function (pref) {
+ fetchedPref = pref;
+ },
+ handleCompletion: function () {
+ // (7) Finally, this callback should be called after set's above.
+ do_check_true(!!fetchedPref);
+ do_check_eq(fetchedPref.value, 2);
+ next();
+ },
+ });
+
+ yield;
+ },
+
+ function* get_nameOnly() {
+ yield set("a.com", "foo", 1);
+ yield set("a.com", "bar", 2);
+ yield set("b.com", "foo", 3);
+ yield setGlobal("foo", 4);
+
+ yield getOKEx("getByName", ["foo", undefined], [
+ {"domain": "a.com", "name": "foo", "value": 1},
+ {"domain": "b.com", "name": "foo", "value": 3},
+ {"domain": null, "name": "foo", "value": 4}
+ ]);
+
+ let context = { usePrivateBrowsing: true };
+ yield set("b.com", "foo", 5, context);
+
+ yield getOKEx("getByName", ["foo", context], [
+ {"domain": "a.com", "name": "foo", "value": 1},
+ {"domain": null, "name": "foo", "value": 4},
+ {"domain": "b.com", "name": "foo", "value": 5}
+ ]);
+ },
+
+ function* setSetsCurrentDate() {
+ // Because Date.now() is not guaranteed to be monotonically increasing
+ // we just do here rough sanity check with one minute tolerance.
+ const MINUTE = 60 * 1000;
+ let now = Date.now();
+ let start = now - MINUTE;
+ let end = now + MINUTE;
+ yield set("a.com", "foo", 1);
+ let timestamp = yield getDate("a.com", "foo");
+ ok(start <= timestamp, "Timestamp is not too early (" + start + "<=" + timestamp + ").");
+ ok(timestamp <= end, "Timestamp is not too late (" + timestamp + "<=" + end + ").");
+ },
+];
diff --git a/toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini b/toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini
new file mode 100644
index 000000000..bdbcaf8fd
--- /dev/null
+++ b/toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini
@@ -0,0 +1,19 @@
+[DEFAULT]
+head = head.js
+tail =
+skip-if = toolkit == 'android'
+support-files = AsyncRunner.jsm
+
+[test_service.js]
+[test_setGet.js]
+[test_getSubdomains.js]
+[test_remove.js]
+[test_removeByDomain.js]
+[test_removeAllDomains.js]
+[test_removeByName.js]
+[test_getCached.js]
+[test_getCachedSubdomains.js]
+[test_observers.js]
+[test_extractDomain.js]
+[test_migrationToSchema4.js]
+[test_removeAllDomainsSince.js]