diff options
Diffstat (limited to 'toolkit/components/contentprefs/tests/unit')
12 files changed, 1288 insertions, 0 deletions
diff --git a/toolkit/components/contentprefs/tests/unit/.eslintrc.js b/toolkit/components/contentprefs/tests/unit/.eslintrc.js new file mode 100644 index 0000000000..d35787cd2c --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../../testing/xpcshell/xpcshell.eslintrc.js" + ] +}; diff --git a/toolkit/components/contentprefs/tests/unit/head_contentPrefs.js b/toolkit/components/contentprefs/tests/unit/head_contentPrefs.js new file mode 100644 index 0000000000..84ca1bebff --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/head_contentPrefs.js @@ -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); +} + diff --git a/toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js b/toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js new file mode 100644 index 0000000000..f3c95dac89 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/tail_contentPrefs.js @@ -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; diff --git a/toolkit/components/contentprefs/tests/unit/test_bug248970.js b/toolkit/components/contentprefs/tests/unit/test_bug248970.js new file mode 100644 index 0000000000..5f4aa25c50 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_bug248970.js @@ -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); + } +} diff --git a/toolkit/components/contentprefs/tests/unit/test_bug503971.js b/toolkit/components/contentprefs/tests/unit/test_bug503971.js new file mode 100644 index 0000000000..ccfe1d02bc --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_bug503971.js @@ -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); +} diff --git a/toolkit/components/contentprefs/tests/unit/test_bug679784.js b/toolkit/components/contentprefs/tests/unit/test_bug679784.js new file mode 100644 index 0000000000..97251d87ba --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_bug679784.js @@ -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); +} diff --git a/toolkit/components/contentprefs/tests/unit/test_contentPrefs.js b/toolkit/components/contentprefs/tests/unit/test_contentPrefs.js new file mode 100644 index 0000000000..f7e99ea9d1 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_contentPrefs.js @@ -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(); + } +} diff --git a/toolkit/components/contentprefs/tests/unit/test_contentPrefsCache.js b/toolkit/components/contentprefs/tests/unit/test_contentPrefsCache.js new file mode 100644 index 0000000000..38a2faddc4 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_contentPrefsCache.js @@ -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); +} diff --git a/toolkit/components/contentprefs/tests/unit/test_getPrefAsync.js b/toolkit/components/contentprefs/tests/unit/test_getPrefAsync.js new file mode 100644 index 0000000000..27d239f793 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_getPrefAsync.js @@ -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(); + }); +} diff --git a/toolkit/components/contentprefs/tests/unit/test_stringGroups.js b/toolkit/components/contentprefs/tests/unit/test_stringGroups.js new file mode 100644 index 0000000000..afce3b64a3 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_stringGroups.js @@ -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); +} diff --git a/toolkit/components/contentprefs/tests/unit/test_unusedGroupsAndSettings.js b/toolkit/components/contentprefs/tests/unit/test_unusedGroupsAndSettings.js new file mode 100644 index 0000000000..24a86bcc06 --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/test_unusedGroupsAndSettings.js @@ -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(); +} diff --git a/toolkit/components/contentprefs/tests/unit/xpcshell.ini b/toolkit/components/contentprefs/tests/unit/xpcshell.ini new file mode 100644 index 0000000000..cbae178b1b --- /dev/null +++ b/toolkit/components/contentprefs/tests/unit/xpcshell.ini @@ -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] |