import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,7 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/mochitest/mochitest.eslintrc.js"
]
};

View file

@ -0,0 +1,4 @@
[DEFAULT]
[test_remoteContentPrefs.html]
skip-if = toolkit == 'android' || e10s # bug 783513

View file

@ -0,0 +1,311 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for nsIContentPrefService2 in child processes</title>
<script type="application/javascript"
src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8">
"use strict";
SimpleTest.waitForExplicitFinish();
const childFrameURL =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
function childFrameScript(isFramePrivate) {
"use strict";
function Tester(resultArray) {
this.results = [];
}
Tester.prototype.is =
function(a, b, note) {
this.results.push([a === b, note + " (" + a + ", " + b + ")"]);
};
Tester.prototype.ok =
function(b, note) {
this.results.push([b != false, note]);
};
var cps = Components.classes["@mozilla.org/content-pref/service;1"]
.getService(Components.interfaces.nsIContentPrefService2);
let test = null;
function* test1(message) {
let tester = new Tester();
tester.ok(cps !== null, "got the content pref service");
cps.setGlobal("testing", 42, null, {
handleCompletion: function(reason) {
tester.is(reason, 0, "set a pref?");
test.next();
}
});
yield;
let numResults = 0;
cps.getGlobal("testing", null, {
handleResult: function(pref) {
numResults++;
tester.is(pref.name, "testing", "pref has the right name");
tester.is(pref.value, 42, "pref has the right value");
},
handleCompletion: function(reason) {
tester.is(reason, 0, "get a pref?");
tester.is(numResults, 1, "got the right number of prefs");
tester.is(test.next().done, true, "done with test1");
message.target.sendAsyncMessage("testRemoteContentPrefs:test1Finished",
{ results: tester.results });
}
});
yield;
}
function* test2(message) {
let tester = new Tester();
let observer;
let removed = false;
cps.addObserverForName("testName", observer = {
onContentPrefSet: function(group, name, value, isPrivate) {
if (removed) {
message.target.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: "unexpected notification" });
}
tester.is(group, null, "group should be null");
tester.is(name, "testName", "should only see testName");
tester.is(value, 42, "value should be correct");
tester.is(isPrivate, isFramePrivate, "privacy should match");
message.target.sendAsyncMessage("testRemoteContentPrefs:test2poke2", {})
},
onContentPrefRemoved: function(group, name, isPrivate) {
tester.is(group, null, "group should be null");
tester.is(name, "testName");
tester.is(isPrivate, isFramePrivate, "privacy should match");
tester.is(test.next().done, true, "should be done with test2");
cps.removeObserverForName("testName", observer);
removed = true;
message.target.sendAsyncMessage("testRemoteContentPrefs:test2Finished",
{ results: tester.results });
}
});
message.target.sendAsyncMessage("testRemoteContentPrefs:test2poke", {});
yield;
}
function* test3(message) {
let tester = new Tester();
cps.setGlobal("testName", 42, null, {
handleCompletion: function(reason) {
tester.is(reason, 0, "set a pref");
cps.set("http://mochi.test", "testpref", "str", null, {
handleCompletion: function(reason) {
tester.is(reason, 0, "set a pref");
test.next();
}
});
}
});
yield;
cps.removeByDomain("http://mochi.test", null, {
handleCompletion: function(reason) {
tester.is(reason, 0, "remove succeeded");
cps.getByDomainAndName("http://mochi.test", "testpref", null, {
handleResult: function() {
message.target.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: "got removed pref in test3" });
},
handleCompletion: function() {
test.next();
}
});
}
});
yield;
message.target.sendAsyncMessage("testRemoteContentPrefs:test3Finished",
{ results: tester.results });
}
function* test4(message) {
let tester = new Tester();
let prefObserver = {
onContentPrefSet: function(group, name, value, isPrivate) {
test.next({ group: group, name: name, value: value, isPrivate: isPrivate });
},
onContentPrefRemoved: function(group, name, isPrivate) {
test.next({ group: group, name: name, isPrivate: isPrivate });
}
};
addMessageListener("testRemoteContentPrefs:prefResults", (msg) => {
test.next(msg.data.results);
});
cps.addObserverForName("test", prefObserver);
cps.set("http://mochi.test", "test", 42, { usePrivateBrowsing: true });
let event = yield;
tester.is(event.name, "test");
tester.is(event.isPrivate, true);
message.target.sendAsyncMessage("testRemoteContentPrefs:getPref",
{ group: "http://mochi.test", name: "test" });
let results = yield;
tester.is(results.length, 0, "should not have seen the pb pref");
message.target.sendAsyncMessage("testRemoteContentPrefs:test4Finished",
{ results: tester.results });
}
addMessageListener("testRemoteContentPrefs:test1", function(message) {
test = test1(message);
test.next();
});
addMessageListener("testRemoteContentPrefs:test2", function(message) {
test = test2(message);
test.next();
});
addMessageListener("testRemoteContentPrefs:test3", function(message) {
test = test3(message);
test.next();
});
addMessageListener("testRemoteContentPrefs:test4", function(message) {
test = test4(message);
test.next();
});
}
function processResults(results) {
for (let i of results) {
ok(...i);
}
}
let test;
function* testStructure(mm, isPrivate, callback) {
let lastResult;
function testDone(msg) {
test.next(msg.data);
}
mm.addMessageListener("testRemoteContentPrefs:test1Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test2Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test3Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test4Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:fail", function(msg) {
ok(false, msg.data.reason);
});
mm.sendAsyncMessage("testRemoteContentPrefs:test1", {});
lastResult = yield;
processResults(lastResult.results);
var cps = SpecialPowers.Cc["@mozilla.org/content-pref/service;1"]
.getService(SpecialPowers.Ci.nsIContentPrefService2);
mm.sendAsyncMessage("testRemoteContentPrefs:test2", {});
mm.addMessageListener("testRemoteContentPrefs:test2poke", function() {
cps.setGlobal("testName", 42, {usePrivateBrowsing: isPrivate});
});
mm.addMessageListener("testRemoteContentPrefs:test2poke2", function() {
cps.removeGlobal("testName", {usePrivateBrowsing: isPrivate});
});
lastResult = yield;
processResults(lastResult.results);
mm.sendAsyncMessage("testRemoteContentPrefs:test3", {});
lastResult = yield;
processResults(lastResult.results);
mm.addMessageListener("testRemoteContentPrefs:getPref", function(msg) {
let results = [];
cps.getByDomainAndName(msg.data.group, msg.data.name, null, {
handleResult: function(pref) {
results.push(pref);
},
handleCompletion: function(reason) {
mm.sendAsyncMessage("testRemoteContentPrefs:prefResults",
{ results: results });
}
});
});
mm.sendAsyncMessage("testRemoteContentPrefs:test4", {});
lastResult = yield;
processResults(lastResult.results);
document.getElementById('iframe').remove();
setTimeout(callback, 0);
}
function runTest(isPrivate, callback) {
info("testing with isPrivate=" + isPrivate);
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
if (isPrivate) {
SpecialPowers.wrap(iframe).mozprivatebrowsing = true;
}
iframe.id = "iframe";
iframe.src = childFrameURL;
iframe.addEventListener("mozbrowserloadend", function() {
info("Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")(" + isPrivate + ");",
false);
test = testStructure(mm, isPrivate, callback);
test.next();
});
document.body.appendChild(iframe);
}
function runTests() {
info("Browser prefs set.");
runTest(false, function() {
runTest(true, function() {
SimpleTest.finish();
});
});
}
addEventListener("load", function() {
info("Got load event.");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({
"set": [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["browser.pagethumbnails.capturing_disabled", true]
]
}, runTests);
});
</script>
</body>
</html>

View file

@ -0,0 +1,7 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
]
};

View file

@ -0,0 +1,162 @@
/* 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/. */
// Inspired by the Places infrastructure in head_bookmarks.js
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;
var Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ContentPrefInstance.jsm');
const CONTENT_PREFS_DB_FILENAME = "content-prefs.sqlite";
const CONTENT_PREFS_BACKUP_DB_FILENAME = "content-prefs.sqlite.corrupt";
var ContentPrefTest = {
// Convenience Getters
__dirSvc: null,
get _dirSvc() {
if (!this.__dirSvc)
this.__dirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
return this.__dirSvc;
},
__consoleSvc: null,
get _consoleSvc() {
if (!this.__consoleSvc)
this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
getService(Ci.nsIConsoleService);
return this.__consoleSvc;
},
__ioSvc: null,
get _ioSvc() {
if (!this.__ioSvc)
this.__ioSvc = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
return this.__ioSvc;
},
// nsISupports
interfaces: [Ci.nsIDirectoryServiceProvider, Ci.nsISupports],
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
},
// nsIDirectoryServiceProvider
getFile: function ContentPrefTest_getFile(property, persistent) {
persistent.value = true;
if (property == "ProfD")
return this._dirSvc.get("CurProcD", Ci.nsIFile);
// This causes extraneous errors to show up in the log when the directory
// service asks us first for CurProcD and MozBinD. I wish there was a way
// to suppress those errors.
throw Cr.NS_ERROR_FAILURE;
},
// Utilities
getURI: function ContentPrefTest_getURI(spec) {
return this._ioSvc.newURI(spec, null, null);
},
/**
* Get the profile directory.
*/
getProfileDir: function ContentPrefTest_getProfileDir() {
// do_get_profile can be only called from a parent process
if (runningInParent) {
return do_get_profile();
}
// if running in a content process, this just returns the path
// profile was initialized in the ipc head file
let env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
// the python harness sets this in the environment for us
let profd = env.get("XPCSHELL_TEST_PROFILE_DIR");
let file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(profd);
return file;
},
/**
* Delete the content pref service's persistent datastore. We do this before
* and after running tests to make sure we start from scratch each time. We
* also do it during the database creation, schema migration, and backup tests.
*/
deleteDatabase: function ContentPrefTest_deleteDatabase() {
var file = this.getProfileDir();
file.append(CONTENT_PREFS_DB_FILENAME);
if (file.exists())
try { file.remove(false); } catch (e) { /* stupid windows box */ }
return file;
},
/**
* Delete the backup of the content pref service's persistent datastore.
* We do this during the database creation, schema migration, and backup tests.
*/
deleteBackupDatabase: function ContentPrefTest_deleteBackupDatabase() {
var file = this.getProfileDir();
file.append(CONTENT_PREFS_BACKUP_DB_FILENAME);
if (file.exists())
file.remove(false);
return file;
},
/**
* Log a message to the console and the test log.
*/
log: function ContentPrefTest_log(message) {
message = "*** ContentPrefTest: " + message;
this._consoleSvc.logStringMessage(message);
print(message);
}
};
var gInPrivateBrowsing = false;
function enterPBMode() {
gInPrivateBrowsing = true;
}
function exitPBMode() {
gInPrivateBrowsing = false;
Services.obs.notifyObservers(null, "last-pb-context-exited", null);
}
ContentPrefTest.deleteDatabase();
function inChildProcess() {
var appInfo = Cc["@mozilla.org/xre/app-info;1"];
if (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType ==
Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
return false;
}
return true;
}
// Turn on logging for the content preferences service so we can troubleshoot
// problems with the tests. Note that we cannot do this in a child process
// without crashing (but we don't need it anyhow)
if (!inChildProcess()) {
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
prefBranch.setBoolPref("browser.preferences.content.log", true);
}

View file

@ -0,0 +1,6 @@
/* 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/. */
ContentPrefTest.deleteDatabase();
ContentPrefTest.__dirSvc = null;

View file

@ -0,0 +1,42 @@
/* 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 loadContext = { get usePrivateBrowsing() { return gInPrivateBrowsing; } };
ContentPrefTest.deleteDatabase();
var cp = new ContentPrefInstance(loadContext);
do_check_neq(cp, null, "Retrieving the content prefs service failed");
try {
const uri1 = ContentPrefTest.getURI("http://www.example.com/");
const uri2 = ContentPrefTest.getURI("http://www.anotherexample.com/");
const pref_name = "browser.content.full-zoom";
const zoomA = 1.5, zoomA_new = 0.8, zoomB = 1.3;
// save Zoom-A
cp.setPref(uri1, pref_name, zoomA);
// make sure Zoom-A is retrievable
do_check_eq(cp.getPref(uri1, pref_name), zoomA);
// enter private browsing mode
enterPBMode();
// make sure Zoom-A is retrievable
do_check_eq(cp.getPref(uri1, pref_name), zoomA);
// save Zoom-B
cp.setPref(uri2, pref_name, zoomB);
// make sure Zoom-B is retrievable
do_check_eq(cp.getPref(uri2, pref_name), zoomB);
// update Zoom-A
cp.setPref(uri1, pref_name, zoomA_new);
// make sure Zoom-A has changed
do_check_eq(cp.getPref(uri1, pref_name), zoomA_new);
// exit private browsing mode
exitPBMode();
// make sure Zoom-A change has not persisted
do_check_eq(cp.getPref(uri1, pref_name), zoomA);
// make sure Zoom-B change has not persisted
do_check_eq(cp.hasPref(uri2, pref_name), false);
} catch (e) {
do_throw("Unexpected exception: " + e);
}
}

View file

@ -0,0 +1,35 @@
/* 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() {
var cps = new ContentPrefInstance(null);
var uri = ContentPrefTest.getURI("http://www.example.com/");
do_check_thrown(function () { cps.setPref(uri, null, 8); });
do_check_thrown(function () { cps.hasPref(uri, null); });
do_check_thrown(function () { cps.getPref(uri, null); });
do_check_thrown(function () { cps.removePref(uri, null); });
do_check_thrown(function () { cps.getPrefsByName(null); });
do_check_thrown(function () { cps.removePrefsByName(null); });
do_check_thrown(function () { cps.setPref(uri, "", 21); });
do_check_thrown(function () { cps.hasPref(uri, ""); });
do_check_thrown(function () { cps.getPref(uri, ""); });
do_check_thrown(function () { cps.removePref(uri, ""); });
do_check_thrown(function () { cps.getPrefsByName(""); });
do_check_thrown(function () { cps.removePrefsByName(""); });
}
function do_check_thrown (aCallback) {
var exThrown = false;
try {
aCallback();
do_throw("NS_ERROR_ILLEGAL_VALUE should have been thrown here");
} catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_ILLEGAL_VALUE);
exThrown = true;
}
do_check_true(exThrown);
}

View file

@ -0,0 +1,103 @@
/* 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 prefObserver = {
setCalledNum: 0,
onContentPrefSet: function(aGroup, aName, aValue) {
this.setCalledNum++;
},
removedCalledNum: 0,
onContentPrefRemoved: function(aGroup, aName) {
this.removedCalledNum++;
}
};
function run_test() {
let loadContext = { get usePrivateBrowsing() { return gInPrivateBrowsing; } };
var cps = new ContentPrefInstance(loadContext);
cps.removeGroupedPrefs();
var uri = ContentPrefTest.getURI("http://www.example.com/");
var group = cps.grouper.group(uri);
// first, set a pref in normal mode
cps.setPref(uri, "value", "foo");
cps.setPref(null, "value-global", "foo-global");
var num;
cps.addObserver("value", prefObserver);
cps.addObserver("value-global", prefObserver);
enterPBMode();
// test setPref
num = prefObserver.setCalledNum;
cps.setPref(uri, "value", "foo-private-browsing");
do_check_eq(cps.hasPref(uri, "value"), true);
do_check_eq(cps.getPref(uri, "value"), "foo-private-browsing");
do_check_eq(prefObserver.setCalledNum, num + 1);
num = prefObserver.setCalledNum;
cps.setPref(null, "value-global", "foo-private-browsing-global");
do_check_eq(cps.hasPref(null, "value-global"), true);
do_check_eq(cps.getPref(null, "value-global"), "foo-private-browsing-global");
do_check_eq(prefObserver.setCalledNum, num + 1);
// test removePref
num = prefObserver.removedCalledNum;
cps.removePref(uri, "value");
do_check_eq(cps.hasPref(uri, "value"), true);
// fallback to non private mode value
do_check_eq(cps.getPref(uri, "value"), "foo");
do_check_eq(prefObserver.removedCalledNum, num + 1);
num = prefObserver.removedCalledNum;
cps.removePref(null, "value-global");
do_check_eq(cps.hasPref(null, "value-global"), true);
// fallback to non private mode value
do_check_eq(cps.getPref(null, "value-global"), "foo-global") ;
do_check_eq(prefObserver.removedCalledNum, num + 1);
// test removeGroupedPrefs
cps.setPref(uri, "value", "foo-private-browsing");
cps.removeGroupedPrefs();
do_check_eq(cps.hasPref(uri, "value"), false);
do_check_eq(cps.getPref(uri, "value"), undefined);
cps.setPref(null, "value-global", "foo-private-browsing-global");
cps.removeGroupedPrefs();
do_check_eq(cps.hasPref(null, "value-global"), true);
do_check_eq(cps.getPref(null, "value-global"), "foo-private-browsing-global");
// test removePrefsByName
num = prefObserver.removedCalledNum;
cps.setPref(uri, "value", "foo-private-browsing");
cps.removePrefsByName("value");
do_check_eq(cps.hasPref(uri, "value"), false);
do_check_eq(cps.getPref(uri, "value"), undefined);
do_check_true(prefObserver.removedCalledNum > num);
num = prefObserver.removedCalledNum;
cps.setPref(null, "value-global", "foo-private-browsing");
cps.removePrefsByName("value-global");
do_check_eq(cps.hasPref(null, "value-global"), false);
do_check_eq(cps.getPref(null, "value-global"), undefined);
do_check_true(prefObserver.removedCalledNum > num);
// test getPrefs
cps.setPref(uri, "value", "foo-private-browsing");
do_check_eq(cps.getPrefs(uri).getProperty("value"), "foo-private-browsing");
cps.setPref(null, "value-global", "foo-private-browsing-global");
do_check_eq(cps.getPrefs(null).getProperty("value-global"), "foo-private-browsing-global");
// test getPrefsByName
do_check_eq(cps.getPrefsByName("value").getProperty(group), "foo-private-browsing");
do_check_eq(cps.getPrefsByName("value-global").getProperty(null), "foo-private-browsing-global");
cps.removeObserver("value", prefObserver);
cps.removeObserver("value-global", prefObserver);
}

View file

@ -0,0 +1,463 @@
/* 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() {
// Database Creation, Schema Migration, and Backup
// Note: in these tests we use createInstance instead of getService
// so we can instantiate the service multiple times and make it run
// its database initialization code each time.
// Create a new database.
{
ContentPrefTest.deleteDatabase();
// Get the service and make sure it has a ready database connection.
let cps = Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
do_check_true(cps.DBConnection.connectionReady);
cps.DBConnection.close();
}
// Open an existing database.
{
let dbFile = ContentPrefTest.deleteDatabase();
let cps = Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
cps.DBConnection.close();
do_check_true(dbFile.exists());
// Get the service and make sure it has a ready database connection.
cps = Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
do_check_true(cps.DBConnection.connectionReady);
cps.DBConnection.close();
}
// Open an empty database.
{
let dbFile = ContentPrefTest.deleteDatabase();
// Create an empty database.
let dbService = Cc["@mozilla.org/storage/service;1"].
getService(Ci.mozIStorageService);
let dbConnection = dbService.openDatabase(dbFile);
do_check_eq(dbConnection.schemaVersion, 0);
dbConnection.close();
do_check_true(dbFile.exists());
// Get the service and make sure it has created the schema.
let cps = Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
do_check_neq(cps.DBConnection.schemaVersion, 0);
cps.DBConnection.close();
}
// Open a corrupted database.
{
let dbFile = ContentPrefTest.deleteDatabase();
let backupDBFile = ContentPrefTest.deleteBackupDatabase();
// Create a corrupted database.
let foStream = Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
foStream.init(dbFile, 0x02 | 0x08 | 0x20, 0o666, 0);
let garbageData = "garbage that makes SQLite think the file is corrupted";
foStream.write(garbageData, garbageData.length);
foStream.close();
// Get the service and make sure it backs up and recreates the database.
let cps = Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
do_check_true(backupDBFile.exists());
do_check_true(cps.DBConnection.connectionReady);
cps.DBConnection.close();
}
// Open a database with a corrupted schema.
{
let dbFile = ContentPrefTest.deleteDatabase();
let backupDBFile = ContentPrefTest.deleteBackupDatabase();
// Create an empty database and set the schema version to a number
// that will trigger a schema migration that will fail.
let dbService = Cc["@mozilla.org/storage/service;1"].
getService(Ci.mozIStorageService);
let dbConnection = dbService.openDatabase(dbFile);
dbConnection.schemaVersion = -1;
dbConnection.close();
do_check_true(dbFile.exists());
// Get the service and make sure it backs up and recreates the database.
let cps = Cc["@mozilla.org/content-pref/service;1"].
createInstance(Ci.nsIContentPrefService);
do_check_true(backupDBFile.exists());
do_check_true(cps.DBConnection.connectionReady);
cps.DBConnection.close();
}
// Now get the content pref service for real for use by the rest of the tests.
let cps = new ContentPrefInstance(null);
var uri = ContentPrefTest.getURI("http://www.example.com/");
// Make sure disk synchronization checking is turned off by default.
var statement = cps.DBConnection.createStatement("PRAGMA synchronous");
statement.executeStep();
do_check_eq(0, statement.getInt32(0));
// Nonexistent Pref
do_check_eq(cps.getPref(uri, "test.nonexistent.getPref"), undefined);
do_check_eq(cps.setPref(uri, "test.nonexistent.setPref", 5), undefined);
do_check_false(cps.hasPref(uri, "test.nonexistent.hasPref"));
do_check_eq(cps.removePref(uri, "test.nonexistent.removePref"), undefined);
// Existing Pref
cps.setPref(uri, "test.existing", 5);
// getPref should return the pref value
do_check_eq(cps.getPref(uri, "test.existing"), 5);
// setPref should return undefined and change the value of the pref
do_check_eq(cps.setPref(uri, "test.existing", 6), undefined);
do_check_eq(cps.getPref(uri, "test.existing"), 6);
// hasPref should return true
do_check_true(cps.hasPref(uri, "test.existing"));
// removePref should return undefined and remove the pref
do_check_eq(cps.removePref(uri, "test.existing"), undefined);
do_check_false(cps.hasPref(uri, "test.existing"));
// Round-Trip Data Integrity
// Make sure pref values remain the same from setPref to getPref.
cps.setPref(uri, "test.data-integrity.integer", 5);
do_check_eq(cps.getPref(uri, "test.data-integrity.integer"), 5);
cps.setPref(uri, "test.data-integrity.float", 5.5);
do_check_eq(cps.getPref(uri, "test.data-integrity.float"), 5.5);
cps.setPref(uri, "test.data-integrity.boolean", true);
do_check_eq(cps.getPref(uri, "test.data-integrity.boolean"), true);
cps.setPref(uri, "test.data-integrity.string", "test");
do_check_eq(cps.getPref(uri, "test.data-integrity.string"), "test");
cps.setPref(uri, "test.data-integrity.null", null);
do_check_eq(cps.getPref(uri, "test.data-integrity.null"), null);
// XXX Test arbitrary binary data.
// Make sure hasPref and removePref work on all data types.
do_check_true(cps.hasPref(uri, "test.data-integrity.integer"));
do_check_true(cps.hasPref(uri, "test.data-integrity.float"));
do_check_true(cps.hasPref(uri, "test.data-integrity.boolean"));
do_check_true(cps.hasPref(uri, "test.data-integrity.string"));
do_check_true(cps.hasPref(uri, "test.data-integrity.null"));
do_check_eq(cps.removePref(uri, "test.data-integrity.integer"), undefined);
do_check_eq(cps.removePref(uri, "test.data-integrity.float"), undefined);
do_check_eq(cps.removePref(uri, "test.data-integrity.boolean"), undefined);
do_check_eq(cps.removePref(uri, "test.data-integrity.string"), undefined);
do_check_eq(cps.removePref(uri, "test.data-integrity.null"), undefined);
do_check_false(cps.hasPref(uri, "test.data-integrity.integer"));
do_check_false(cps.hasPref(uri, "test.data-integrity.float"));
do_check_false(cps.hasPref(uri, "test.data-integrity.boolean"));
do_check_false(cps.hasPref(uri, "test.data-integrity.string"));
do_check_false(cps.hasPref(uri, "test.data-integrity.null"));
// getPrefs
cps.setPref(uri, "test.getPrefs.a", 1);
cps.setPref(uri, "test.getPrefs.b", 2);
cps.setPref(uri, "test.getPrefs.c", 3);
var prefs = cps.getPrefs(uri);
do_check_true(prefs.hasKey("test.getPrefs.a"));
do_check_eq(prefs.get("test.getPrefs.a"), 1);
do_check_true(prefs.hasKey("test.getPrefs.b"));
do_check_eq(prefs.get("test.getPrefs.b"), 2);
do_check_true(prefs.hasKey("test.getPrefs.c"));
do_check_eq(prefs.get("test.getPrefs.c"), 3);
// Site-Specificity
{
// These are all different sites, and setting a pref for one of them
// shouldn't set it for the others.
let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
let uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
let uri3 = ContentPrefTest.getURI("http://domain1.com/");
let uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
cps.setPref(uri1, "test.site-specificity.uri1", 5);
do_check_false(cps.hasPref(uri2, "test.site-specificity.uri1"));
do_check_false(cps.hasPref(uri3, "test.site-specificity.uri1"));
do_check_false(cps.hasPref(uri4, "test.site-specificity.uri1"));
cps.setPref(uri2, "test.site-specificity.uri2", 5);
do_check_false(cps.hasPref(uri1, "test.site-specificity.uri2"));
do_check_false(cps.hasPref(uri3, "test.site-specificity.uri2"));
do_check_false(cps.hasPref(uri4, "test.site-specificity.uri2"));
cps.setPref(uri3, "test.site-specificity.uri3", 5);
do_check_false(cps.hasPref(uri1, "test.site-specificity.uri3"));
do_check_false(cps.hasPref(uri2, "test.site-specificity.uri3"));
do_check_false(cps.hasPref(uri4, "test.site-specificity.uri3"));
cps.setPref(uri4, "test.site-specificity.uri4", 5);
do_check_false(cps.hasPref(uri1, "test.site-specificity.uri4"));
do_check_false(cps.hasPref(uri2, "test.site-specificity.uri4"));
do_check_false(cps.hasPref(uri3, "test.site-specificity.uri4"));
}
// Observers
var specificObserver = {
interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
},
numTimesSetCalled: 0,
onContentPrefSet: function specificObserver_onContentPrefSet(group, name, value) {
++this.numTimesSetCalled;
do_check_eq(group, "www.example.com");
do_check_eq(name, "test.observer.1");
do_check_eq(value, "test value");
},
numTimesRemovedCalled: 0,
onContentPrefRemoved: function specificObserver_onContentPrefRemoved(group, name) {
++this.numTimesRemovedCalled;
do_check_eq(group, "www.example.com");
do_check_eq(name, "test.observer.1");
}
};
var genericObserver = {
interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
},
numTimesSetCalled: 0,
onContentPrefSet: function genericObserver_onContentPrefSet(group, name, value, isPrivate) {
++this.numTimesSetCalled;
do_check_eq(group, "www.example.com");
if (name == "test.observer.private")
do_check_true(isPrivate);
else if (name == "test.observer.normal")
do_check_false(isPrivate);
else if (name != "test.observer.1" && name != "test.observer.2")
do_throw("genericObserver.onContentPrefSet: " +
"name not in (test.observer.(1|2|normal|private))");
do_check_eq(value, "test value");
},
numTimesRemovedCalled: 0,
onContentPrefRemoved: function genericObserver_onContentPrefRemoved(group, name, isPrivate) {
++this.numTimesRemovedCalled;
do_check_eq(group, "www.example.com");
if (name == "test.observer.private")
do_check_true(isPrivate);
else if (name == "test.observer.normal")
do_check_false(isPrivate);
if (name != "test.observer.1" && name != "test.observer.2" &&
name != "test.observer.normal" && name != "test.observer.private") {
do_throw("genericObserver.onContentPrefSet: " +
"name not in (test.observer.(1|2|normal|private))");
}
}
};
// Make sure we can add observers, observers get notified about changes,
// specific observers only get notified about changes to the specific setting,
// and generic observers get notified about changes to all settings.
cps.addObserver("test.observer.1", specificObserver);
cps.addObserver(null, genericObserver);
cps.setPref(uri, "test.observer.1", "test value");
cps.setPref(uri, "test.observer.2", "test value");
cps.removePref(uri, "test.observer.1");
cps.removePref(uri, "test.observer.2");
do_check_eq(specificObserver.numTimesSetCalled, 1);
do_check_eq(genericObserver.numTimesSetCalled, 2);
do_check_eq(specificObserver.numTimesRemovedCalled, 1);
do_check_eq(genericObserver.numTimesRemovedCalled, 2);
// Make sure information about private context is properly
// retrieved by the observer.
cps.setPref(uri, "test.observer.private", "test value", {usePrivateBrowsing: true});
cps.setPref(uri, "test.observer.normal", "test value", {usePrivateBrowsing: false});
cps.removePref(uri, "test.observer.private");
cps.removePref(uri, "test.observer.normal");
// Make sure we can remove observers and they don't get notified
// about changes anymore.
cps.removeObserver("test.observer.1", specificObserver);
cps.removeObserver(null, genericObserver);
cps.setPref(uri, "test.observer.1", "test value");
cps.removePref(uri, "test.observer.1", "test value");
do_check_eq(specificObserver.numTimesSetCalled, 1);
do_check_eq(genericObserver.numTimesSetCalled, 4);
do_check_eq(specificObserver.numTimesRemovedCalled, 1);
do_check_eq(genericObserver.numTimesRemovedCalled, 3);
// Get/Remove Prefs By Name
{
var anObserver = {
interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
QueryInterface: function ContentPrefTest_QueryInterface(iid) {
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
},
onContentPrefSet: function anObserver_onContentPrefSet(group, name, value) {
},
expectedDomains: [],
numTimesRemovedCalled: 0,
onContentPrefRemoved: function anObserver_onContentPrefRemoved(group, name) {
++this.numTimesRemovedCalled;
// remove the domain from the list of expected domains
var index = this.expectedDomains.indexOf(group);
do_check_true(index >= 0);
this.expectedDomains.splice(index, 1);
}
};
let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
let uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
let uri3 = ContentPrefTest.getURI("http://domain1.com/");
let uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
cps.setPref(uri1, "test.byname.1", 1);
cps.setPref(uri1, "test.byname.2", 2);
cps.setPref(uri2, "test.byname.1", 4);
cps.setPref(uri3, "test.byname.3", 8);
cps.setPref(uri4, "test.byname.1", 16);
cps.setPref(null, "test.byname.1", 32);
cps.setPref(null, "test.byname.2", false);
function enumerateAndCheck(testName, expectedSum, expectedDomains) {
var prefsByName = cps.getPrefsByName(testName);
var enumerator = prefsByName.enumerator;
var sum = 0;
while (enumerator.hasMoreElements()) {
var property = enumerator.getNext().QueryInterface(Components.interfaces.nsIProperty);
sum += parseInt(property.value);
// remove the domain from the list of expected domains
var index = expectedDomains.indexOf(property.name);
do_check_true(index >= 0);
expectedDomains.splice(index, 1);
}
do_check_eq(sum, expectedSum);
// check all domains have been removed from the array
do_check_eq(expectedDomains.length, 0);
}
enumerateAndCheck("test.byname.1", 53,
["foo.domain1.com", null, "www.domain1.com", "www.domain2.com"]);
enumerateAndCheck("test.byname.2", 2, ["www.domain1.com", null]);
enumerateAndCheck("test.byname.3", 8, ["domain1.com"]);
cps.addObserver("test.byname.1", anObserver);
anObserver.expectedDomains = ["foo.domain1.com", null, "www.domain1.com", "www.domain2.com"];
cps.removePrefsByName("test.byname.1");
do_check_false(cps.hasPref(uri1, "test.byname.1"));
do_check_false(cps.hasPref(uri2, "test.byname.1"));
do_check_false(cps.hasPref(uri3, "test.byname.1"));
do_check_false(cps.hasPref(uri4, "test.byname.1"));
do_check_false(cps.hasPref(null, "test.byname.1"));
do_check_true(cps.hasPref(uri1, "test.byname.2"));
do_check_true(cps.hasPref(uri3, "test.byname.3"));
do_check_eq(anObserver.numTimesRemovedCalled, 4);
do_check_eq(anObserver.expectedDomains.length, 0);
cps.removeObserver("test.byname.1", anObserver);
// Clean up after ourselves
cps.removePref(uri1, "test.byname.2");
cps.removePref(uri3, "test.byname.3");
cps.removePref(null, "test.byname.2");
}
// Clear Private Data Pref Removal
{
let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
let uri2 = ContentPrefTest.getURI("http://www.domain2.com/");
let uri3 = ContentPrefTest.getURI("http://www.domain3.com/");
let dbConnection = cps.DBConnection;
let prefCount = dbConnection.createStatement("SELECT COUNT(*) AS count FROM prefs");
let groupCount = dbConnection.createStatement("SELECT COUNT(*) AS count FROM groups");
// Add some prefs for multiple domains.
cps.setPref(uri1, "test.removeAllGroups", 1);
cps.setPref(uri2, "test.removeAllGroups", 2);
cps.setPref(uri3, "test.removeAllGroups", 3);
// Add a global pref.
cps.setPref(null, "test.removeAllGroups", 1);
// Make sure there are some prefs and groups in the database.
prefCount.executeStep();
do_check_true(prefCount.row.count > 0);
prefCount.reset();
groupCount.executeStep();
do_check_true(groupCount.row.count > 0);
groupCount.reset();
// Remove all prefs and groups from the database using the same routine
// the Clear Private Data dialog uses.
cps.removeGroupedPrefs();
// Make sure there are no longer any groups in the database and the only pref
// is the global one.
prefCount.executeStep();
do_check_true(prefCount.row.count == 1);
prefCount.reset();
groupCount.executeStep();
do_check_true(groupCount.row.count == 0);
groupCount.reset();
let globalPref = dbConnection.createStatement("SELECT groupID FROM prefs");
globalPref.executeStep();
do_check_true(globalPref.row.groupID == null);
globalPref.reset();
}
}

View file

@ -0,0 +1,244 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var cps = new ContentPrefInstance(null);
function run_test() {
testCacheWorks("test1.example.com", "test-pref1");
testHasCachedPrefFunction("test2.example.com", "test-pref2");
testSetCaches("test3.example.com", "test-pref3");
testGetCaches("test4.example.com", "test-pref4");
testRemovePrefs("test5.example.com", "test-pref5");
testTypeConversions("test6.example.com", "test-pref6");
testNonExistingPrefCachesAsUndefined("test7.example.com", "test-pref7");
testCacheEviction("test8.example.com", "test-pref8");
}
function testCacheWorks(uri, prefName) {
const CACHED_VALUE = 3;
const NEW_VALUE = 5;
cps.setPref(uri, prefName, CACHED_VALUE);
do_check_eq(cps.getPref(uri, prefName), CACHED_VALUE);
// Now change the value directly through the DB and check
// that the cached value is different
let groupId = selectValue("SELECT id FROM groups WHERE name = :param1", "id", uri);
let settingId = selectValue("SELECT id FROM settings WHERE name = :param1", "id", prefName);
let prefId = selectValue("SELECT id FROM prefs WHERE groupID = :param1 AND settingID = :param2",
"id", groupId, settingId);
let stmt = cps.DBConnection.createStatement("UPDATE prefs SET value = :value WHERE id = :id");
stmt.params.value = NEW_VALUE;
stmt.params.id = prefId;
stmt.execute();
let dbValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
let cacheValue = cps.getPref(uri, prefName);
do_check_eq(dbValue, NEW_VALUE);
do_check_eq(cacheValue, CACHED_VALUE);
do_check_neq(cacheValue, dbValue);
do_test_pending();
cps.getPref(uri, prefName, function (value) {
do_check_eq(dbValue, NEW_VALUE);
do_check_eq(value, CACHED_VALUE);
do_check_neq(value, dbValue);
do_test_finished();
});
}
function testHasCachedPrefFunction(uri, prefName) {
const STARTING_VALUE = 3;
const NEW_VALUE = 5;
do_check_false(isCached(uri, prefName));
cps.setPref(uri, prefName, STARTING_VALUE);
let groupId = selectValue("SELECT id FROM groups WHERE name = :param1", "id", uri);
let settingId = selectValue("SELECT id FROM settings WHERE name = :param1", "id", prefName);
let prefId = selectValue("SELECT id FROM prefs WHERE groupID = :param1 AND settingID = :param2",
"id", groupId, settingId);
do_check_neq(prefId, undefined);
let originalValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
do_check_eq(originalValue, STARTING_VALUE);
let stmt = cps.DBConnection.createStatement("UPDATE prefs SET value = :value WHERE id = :id");
stmt.params.value = NEW_VALUE;
stmt.params.id = prefId;
stmt.execute();
let newValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
do_check_eq(newValue, NEW_VALUE);
let cachedValue = cps.getPref(uri, prefName);
do_check_eq(cachedValue, STARTING_VALUE);
do_check_true(isCached(uri, prefName));
}
function testSetCaches(uri, prefName) {
cps.setPref(uri, prefName, 0);
do_check_true(isCached(uri, prefName));
}
function testRemovePrefs(uri, prefName) {
/* removePref */
cps.setPref("www1." + uri, prefName, 1);
do_check_eq(cps.getPref("www1." + uri, prefName), 1);
cps.removePref("www1." + uri, prefName);
do_check_false(isCached("www1." + uri, prefName));
do_check_false(cps.hasPref("www1." + uri, prefName));
do_check_neq(cps.getPref("www1." + uri, prefName), 1);
/* removeGroupedPrefs */
cps.setPref("www2." + uri, prefName, 2);
cps.setPref("www3." + uri, prefName, 3);
do_check_eq(cps.getPref("www2." + uri, prefName), 2);
do_check_eq(cps.getPref("www3." + uri, prefName), 3);
cps.removeGroupedPrefs();
do_check_false(isCached("www2." + uri, prefName));
do_check_false(isCached("www3." + uri, prefName));
do_check_false(cps.hasPref("www2." + uri, prefName));
do_check_false(cps.hasPref("www3." + uri, prefName));
do_check_neq(cps.getPref("www2." + uri, prefName), 2);
do_check_neq(cps.getPref("www3." + uri, prefName), 3);
/* removePrefsByName */
cps.setPref("www4." + uri, prefName, 4);
cps.setPref("www5." + uri, prefName, 5);
do_check_eq(cps.getPref("www4." + uri, prefName), 4);
do_check_eq(cps.getPref("www5." + uri, prefName), 5);
cps.removePrefsByName(prefName);
do_check_false(isCached("www4." + uri, prefName));
do_check_false(isCached("www5." + uri, prefName));
do_check_false(cps.hasPref("www4." + uri, prefName));
do_check_false(cps.hasPref("www5." + uri, prefName));
do_check_neq(cps.getPref("www4." + uri, prefName), 4);
do_check_neq(cps.getPref("www5." + uri, prefName), 5);
}
function testGetCaches(uri, prefName) {
const VALUE = 4;
let insertGroup = cps.DBConnection.createStatement("INSERT INTO groups (name) VALUES (:name)");
insertGroup.params.name = uri;
insertGroup.execute();
let groupId = cps.DBConnection.lastInsertRowID;
let insertSetting = cps.DBConnection.createStatement("INSERT INTO settings (name) VALUES (:name)");
insertSetting.params.name = prefName;
insertSetting.execute();
let settingId = cps.DBConnection.lastInsertRowID;
let insertPref = cps.DBConnection.createStatement(`
INSERT INTO prefs (groupID, settingID, value)
VALUES (:groupId, :settingId, :value)
`);
insertPref.params.groupId = groupId;
insertPref.params.settingId = settingId;
insertPref.params.value = VALUE;
insertPref.execute();
let prefId = cps.DBConnection.lastInsertRowID;
let dbValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
// First access from service should hit the DB
let svcValue = cps.getPref(uri, prefName);
// Second time should get the value from cache
let cacheValue = cps.getPref(uri, prefName);
do_check_eq(VALUE, dbValue);
do_check_eq(VALUE, svcValue);
do_check_eq(VALUE, cacheValue);
do_check_true(isCached(uri, prefName));
}
function testTypeConversions(uri, prefName) {
let value;
cps.setPref(uri, prefName, true);
value = cps.getPref(uri, prefName);
do_check_true(value === 1);
cps.setPref(uri, prefName, false);
value = cps.getPref(uri, prefName);
do_check_true(value === 0);
cps.setPref(uri, prefName, null);
value = cps.getPref(uri, prefName);
do_check_true(value === null);
cps.setPref(uri, prefName, undefined);
value = cps.getPref(uri, prefName);
do_check_true(value === null);
}
function testNonExistingPrefCachesAsUndefined(uri, prefName) {
do_check_false(isCached(uri, prefName));
// Cache the pref
let value = cps.getPref(uri, prefName);
do_check_true(value === undefined);
do_check_true(isCached(uri, prefName));
// Cached pref
value = cps.getPref(uri, prefName);
do_check_true(value === undefined);
}
function testCacheEviction(uri, prefName) {
cps.setPref(uri, prefName, 5);
do_check_eq(cps.getPref(uri, prefName), 5);
do_check_true(isCached(uri, prefName));
// try to evict value from cache by adding various other entries
const ENTRIES_TO_ADD = 200;
for (let i = 0; i < ENTRIES_TO_ADD; i++) {
let uriToAdd = "www" + i + uri;
cps.setPref(uriToAdd, prefName, 0);
}
do_check_false(isCached(uri, prefName));
}
function selectValue(stmt, columnName, param1, param2) {
stmt = cps.DBConnection.createStatement(stmt);
if (param1)
stmt.params.param1 = param1;
if (param2)
stmt.params.param2 = param2;
stmt.executeStep();
let val = stmt.row[columnName];
stmt.reset();
stmt.finalize();
return val;
}
function isCached(uri, prefName) {
return cps.hasCachedPref(uri, prefName);
}

View file

@ -0,0 +1,34 @@
/* 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 cps = new ContentPrefInstance(null);
var uri = ContentPrefTest.getURI("http://www.example.com/");
function run_test() {
do_test_pending();
cps.setPref(uri, "asynctest", "pie");
do_check_eq(cps.getPref(uri, "asynctest"), "pie");
cps.getPref(uri, "asynctest", function(aValue) {
do_check_eq(aValue, "pie");
testCallbackObj();
});
}
function testCallbackObj() {
cps.getPref(uri, "asynctest", {
onResult: function(aValue) {
do_check_eq(aValue, "pie");
cps.removePref(uri, "asynctest");
testNoResult();
}
});
}
function testNoResult() {
cps.getPref(uri, "asynctest", function(aValue) {
do_check_eq(aValue, undefined);
do_test_finished();
});
}

View file

@ -0,0 +1,128 @@
/* 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() {
var cps = new ContentPrefInstance(null);
// Make sure disk synchronization checking is turned off by default.
var statement = cps.DBConnection.createStatement("PRAGMA synchronous");
statement.executeStep();
do_check_eq(0, statement.getInt32(0));
// These are the different types of aGroup arguments we'll test.
var anObject = {"foo":"bar"}; // a simple object
var uri = ContentPrefTest.getURI("http://www.example.com/"); // nsIURI
var stringURI = "www.example.com"; // typeof = "string"
var stringObjectURI = new String("www.example.com"); // typeof = "object"
{
// First check that all the methods work or don't work.
function simple_test_methods(aGroup, shouldThrow) {
var prefName = "test.pref.0";
var prefValue = Math.floor(Math.random() * 100);
if (shouldThrow) {
do_check_thrown(function () { cps.getPref(aGroup, prefName); });
do_check_thrown(function () { cps.setPref(aGroup, prefName, prefValue); });
do_check_thrown(function () { cps.hasPref(aGroup, prefName); });
do_check_thrown(function () { cps.removePref(aGroup, prefName); });
do_check_thrown(function () { cps.getPrefs(aGroup); });
} else {
do_check_eq(cps.setPref(aGroup, prefName, prefValue), undefined);
do_check_true(cps.hasPref(aGroup, prefName));
do_check_eq(cps.getPref(aGroup, prefName), prefValue);
do_check_eq(cps.removePref(aGroup, prefName), undefined);
do_check_false(cps.hasPref(aGroup, prefName));
}
}
simple_test_methods(cps, true); // arbitrary nsISupports object, should throw too
simple_test_methods(anObject, true);
simple_test_methods(uri, false);
simple_test_methods(stringURI, false);
simple_test_methods(stringObjectURI, false);
}
{
// Now we'll check that each argument produces the same result.
function complex_test_methods(aGroup) {
var prefName = "test.pref.1";
var prefValue = Math.floor(Math.random() * 100);
do_check_eq(cps.setPref(aGroup, prefName, prefValue), undefined);
do_check_true(cps.hasPref(uri, prefName));
do_check_true(cps.hasPref(stringURI, prefName));
do_check_true(cps.hasPref(stringObjectURI, prefName));
do_check_eq(cps.getPref(uri, prefName), prefValue);
do_check_eq(cps.getPref(stringURI, prefName), prefValue);
do_check_eq(cps.getPref(stringObjectURI, prefName), prefValue);
do_check_eq(cps.removePref(aGroup, prefName), undefined);
do_check_false(cps.hasPref(uri, prefName));
do_check_false(cps.hasPref(stringURI, prefName));
do_check_false(cps.hasPref(stringObjectURI, prefName));
}
complex_test_methods(uri);
complex_test_methods(stringURI);
complex_test_methods(stringObjectURI);
}
{
// test getPrefs returns the same prefs
do_check_eq(cps.setPref(stringObjectURI, "test.5", 5), undefined);
do_check_eq(cps.setPref(stringURI, "test.2", 2), undefined);
do_check_eq(cps.setPref(uri, "test.1", 1), undefined);
enumerateAndCheck(cps.getPrefs(uri), 8, ["test.1", "test.2", "test.5"]);
enumerateAndCheck(cps.getPrefs(stringURI), 8, ["test.1", "test.2", "test.5"]);
enumerateAndCheck(cps.getPrefs(stringObjectURI), 8, ["test.1", "test.2", "test.5"]);
do_check_eq(cps.setPref(uri, "test.4", 4), undefined);
do_check_eq(cps.setPref(stringObjectURI, "test.0", 0), undefined);
enumerateAndCheck(cps.getPrefs(uri), 12, ["test.0", "test.1", "test.2", "test.4", "test.5"]);
enumerateAndCheck(cps.getPrefs(stringURI), 12, ["test.0", "test.1", "test.2", "test.4", "test.5"]);
enumerateAndCheck(cps.getPrefs(stringObjectURI), 12, ["test.0", "test.1", "test.2", "test.4", "test.5"]);
do_check_eq(cps.setPref(stringURI, "test.3", 3), undefined);
enumerateAndCheck(cps.getPrefs(uri), 15, ["test.0", "test.1", "test.2", "test.3", "test.4", "test.5"]);
enumerateAndCheck(cps.getPrefs(stringURI), 15, ["test.0", "test.1", "test.2", "test.3", "test.4", "test.5"]);
enumerateAndCheck(cps.getPrefs(stringObjectURI), 15, ["test.0", "test.1", "test.2", "test.3", "test.4", "test.5"]);
}
}
function do_check_thrown (aCallback) {
var exThrown = false;
try {
aCallback();
do_throw("NS_ERROR_ILLEGAL_VALUE should have been thrown here");
} catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_ILLEGAL_VALUE);
exThrown = true;
}
do_check_true(exThrown);
}
function enumerateAndCheck(prefs, expectedSum, expectedNames) {
var enumerator = prefs.enumerator;
var sum = 0;
while (enumerator.hasMoreElements()) {
var property = enumerator.getNext().QueryInterface(Components.interfaces.nsIProperty);
sum += parseInt(property.value);
// remove the pref name from the list of expected names
var index = expectedNames.indexOf(property.name);
do_check_true(index >= 0);
expectedNames.splice(index, 1);
}
do_check_eq(sum, expectedSum);
// check all pref names have been removed from the array
do_check_eq(expectedNames.length, 0);
}

View file

@ -0,0 +1,52 @@
/* 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 cps = new ContentPrefInstance(null);
function run_test() {
var uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
var uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
var uri3 = ContentPrefTest.getURI("http://domain1.com/");
var uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
cps.setPref(uri1, "one", 1);
cps.setPref(uri1, "two", 2);
cps.setPref(uri2, "one", 4);
cps.setPref(uri3, "three", 8);
cps.setPref(uri4, "two", 16);
cps.removePref(uri3, "three"); // uri3 should be removed now
checkForUnusedGroups();
checkForUnusedSettings();
cps.removePrefsByName("two"); // uri4 should be removed now
checkForUnusedGroups();
checkForUnusedSettings();
cps.removeGroupedPrefs();
checkForUnusedGroups();
checkForUnusedSettings();
}
function checkForUnusedGroups() {
var stmt = cps.DBConnection.createStatement(`
SELECT COUNT(*) AS count FROM groups
WHERE id NOT IN (SELECT DISTINCT groupID FROM prefs)
`);
stmt.executeStep();
do_check_eq(0, stmt.row.count);
stmt.reset();
stmt.finalize();
}
function checkForUnusedSettings() {
var stmt = cps.DBConnection.createStatement(`
SELECT COUNT(*) AS count FROM settings
WHERE id NOT IN (SELECT DISTINCT settingID FROM prefs)
`);
stmt.executeStep();
do_check_eq(0, stmt.row.count);
stmt.reset();
stmt.finalize();
}

View file

@ -0,0 +1,12 @@
[DEFAULT]
head = head_contentPrefs.js
tail = tail_contentPrefs.js
[test_bug248970.js]
[test_bug503971.js]
[test_bug679784.js]
[test_contentPrefs.js]
[test_contentPrefsCache.js]
[test_getPrefAsync.js]
[test_stringGroups.js]
[test_unusedGroupsAndSettings.js]

View file

@ -0,0 +1,7 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
]
};

View file

@ -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);
}
},
};

View file

@ -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);
}

View file

@ -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]);
}
}

View file

@ -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);
},
];

View file

@ -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;
},
];

View file

@ -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;
},
];

View file

@ -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);
}
];

View file

@ -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]]);
},
];

View file

@ -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;
},
];

View file

@ -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;
},
];

View file

@ -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;
},
];

View file

@ -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;
},
];

View file

@ -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;
},
];

View file

@ -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);
}

View file

@ -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 + ").");
},
];

View file

@ -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]