summaryrefslogtreecommitdiffstats
path: root/dom/settings/tests
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/settings/tests
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/settings/tests')
-rw-r--r--dom/settings/tests/chrome.ini24
-rw-r--r--dom/settings/tests/file_bug1110872.html47
-rw-r--r--dom/settings/tests/file_bug1110872.js47
-rw-r--r--dom/settings/tests/file_loadserver.js17
-rw-r--r--dom/settings/tests/test_settings_basics.html816
-rw-r--r--dom/settings/tests/test_settings_blobs.html148
-rw-r--r--dom/settings/tests/test_settings_bug1110872.html17
-rw-r--r--dom/settings/tests/test_settings_data_uris.html149
-rw-r--r--dom/settings/tests/test_settings_events.html47
-rw-r--r--dom/settings/tests/test_settings_navigator_object.html37
-rw-r--r--dom/settings/tests/test_settings_observer_killer.html60
-rw-r--r--dom/settings/tests/test_settings_onsettingchange.html306
-rw-r--r--dom/settings/tests/test_settings_permissions.html184
-rw-r--r--dom/settings/tests/test_settings_service.js138
-rw-r--r--dom/settings/tests/test_settings_service.xul19
-rw-r--r--dom/settings/tests/test_settings_service_callback.js47
-rw-r--r--dom/settings/tests/test_settings_service_callback.xul19
-rw-r--r--dom/settings/tests/unit/test_settingsrequestmanager_messages.js174
-rw-r--r--dom/settings/tests/unit/xpcshell.ini6
19 files changed, 2302 insertions, 0 deletions
diff --git a/dom/settings/tests/chrome.ini b/dom/settings/tests/chrome.ini
new file mode 100644
index 000000000..92b1554a0
--- /dev/null
+++ b/dom/settings/tests/chrome.ini
@@ -0,0 +1,24 @@
+[DEFAULT]
+skip-if = toolkit == 'android' # Bug 1287455: takes too long to complete on Android
+support-files =
+ file_loadserver.js
+ file_bug1110872.js
+ file_bug1110872.html
+ test_settings_service.js
+ test_settings_service_callback.js
+
+[test_settings_service.xul]
+run-if = buildapp == 'b2g' || buildapp == 'mulet'
+[test_settings_service_callback.xul]
+run-if = buildapp == 'b2g' || buildapp == 'mulet'
+[test_settings_basics.html]
+[test_settings_permissions.html]
+[test_settings_blobs.html]
+[test_settings_data_uris.html]
+[test_settings_events.html]
+[test_settings_navigator_object.html]
+[test_settings_onsettingchange.html]
+[test_settings_bug1110872.html]
+skip-if = !e10s
+[test_settings_observer_killer.html]
+skip-if = !debug
diff --git a/dom/settings/tests/file_bug1110872.html b/dom/settings/tests/file_bug1110872.html
new file mode 100644
index 000000000..3dcc45b82
--- /dev/null
+++ b/dom/settings/tests/file_bug1110872.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Test for Bug {1110872} Settings API Reloads</title>
+ </head>
+ <body>
+ <script type="application/javascript;version=1.7">
+
+ var createLock = function (msg) {
+ var lock = navigator.mozSettings.createLock();
+ var req = lock.get("wallpaper.image");
+ // We don't actually care about success or failure here, we just
+ // want to know the queue gets processed at all.
+ req.onsuccess = function () {
+ parent.postMessage({name:"done" + msg.data.step}, "*");
+ }
+ req.onerror = function () {
+ parent.postMessage({name:"done" + msg.data.step}, "*");
+ };
+ return req;
+ }
+ window.onload = function() {
+ window.addEventListener("message", function (msg) {
+ var i;
+ var reqs = [];
+ if (msg.data.step == 1) {
+ for (i = 0; i < 100; ++i) {
+ reqs.push(createLock(msg));
+ }
+ } else {
+ reqs.push(createLock(msg));
+ }
+ // If this is our first time through, reload
+ // before the SettingsManager has a chance to get a response
+ // to our query.
+ if (msg.data.step == 1) {
+ location.reload();
+ }
+ });
+ }
+ </script>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1110872}">Mozilla Bug {1110872} Inner Window for Reload Test</a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ </body>
+</html>
diff --git a/dom/settings/tests/file_bug1110872.js b/dom/settings/tests/file_bug1110872.js
new file mode 100644
index 000000000..d31b6c2f3
--- /dev/null
+++ b/dom/settings/tests/file_bug1110872.js
@@ -0,0 +1,47 @@
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+
+var iframe;
+var loadedEvents = 0;
+
+function loadServer() {
+ var url = SimpleTest.getTestFileURL("file_loadserver.js");
+ var script = SpecialPowers.loadChromeScript(url);
+}
+
+function runTest() {
+ iframe = document.createElement('iframe');
+ document.body.appendChild(iframe);
+ iframe.addEventListener('load', mozbrowserLoaded);
+ iframe.src = 'file_bug1110872.html';
+}
+
+function iframeBodyRecv(msg) {
+ switch (loadedEvents) {
+ case 1:
+ // If we get a message back before we've seen 2 loads, that means
+ // something went wrong with the test. Fail immediately.
+ ok(true, 'got response from first test!');
+ break;
+ case 2:
+ // If we get a message back after 2 loads (initial load, reload),
+ // it means the callback for the last lock fired, which means the
+ // SettingsRequestManager queue has to have been cleared
+ // correctly.
+ ok(true, 'further queries returned ok after SettingsManager death');
+ SimpleTest.finish();
+ break;
+ }
+}
+
+function mozbrowserLoaded() {
+ loadedEvents++;
+ iframe.contentWindow.postMessage({name: "start", step: loadedEvents}, '*');
+ window.addEventListener('message', iframeBodyRecv);
+}
+
+window.addEventListener("load", function() {
+ loadServer();
+ runTest();
+});
diff --git a/dom/settings/tests/file_loadserver.js b/dom/settings/tests/file_loadserver.js
new file mode 100644
index 000000000..a919d9690
--- /dev/null
+++ b/dom/settings/tests/file_loadserver.js
@@ -0,0 +1,17 @@
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+
+// Stolen from SpecialPowers, since at this point we don't know we're in a test.
+var isMainProcess = function() {
+ try {
+ return Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULRuntime).
+ processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+ } catch (e) { }
+ return true;
+};
+
+if (isMainProcess()) {
+ Components.utils.import("resource://gre/modules/SettingsRequestManager.jsm");
+}
diff --git a/dom/settings/tests/test_settings_basics.html b/dom/settings/tests/test_settings_basics.html
new file mode 100644
index 000000000..a14650390
--- /dev/null
+++ b/dom/settings/tests/test_settings_basics.html
@@ -0,0 +1,816 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
+-->
+<head>
+ <title>Test for Bug {678695} Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={678695}">Mozilla Bug {678695}</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+"use strict";
+
+var url = SimpleTest.getTestFileURL("file_loadserver.js");
+var script = SpecialPowers.loadChromeScript(url);
+
+function onUnwantedSuccess() {
+ ok(false, "onUnwantedSuccess: shouldn't get here");
+}
+
+function onFailure() {
+ ok(false, "in on Failure!");
+}
+
+const wifi = {"net3g.apn": "internet.mnc012.mcc345.gprs"};
+const wifi2 = {"net3g.apn": "internet.mnc012.mcc345.test"};
+var wifi3 = {"net3g.apn2": "internet.mnc012.mcc345.test3"};
+var wifiEnabled = {"wifi.enabled": true};
+var wifiDisabled = {"wifi.enabled": false};
+var screenBright = {"screen.brightness": 0.7};
+var screenBright2 = {"screen.brightness": 0.1};
+var wifiNetworks0 = { "wifi.networks[0]": { ssid: "myfreenetwork", mac: "01:23:45:67:89:ab", passwd: "secret"}};
+var wifiNetworks1 = { "wifi.networks[1]": { ssid: "myfreenetwork2", mac: "01:23:45:67:89:ab", passwd: "secret2"}};
+
+var combination = {
+ "wifi.enabled": false,
+ "screen.brightness": 0.7,
+ "wifi.networks[0]": { ssid: "myfreenetwork", mac: "01:23:45:67:89:ab", passwd: "secret" },
+ "test.test": true,
+ "net3g.apn2": "internet.mnc012.mcc345.gprs"
+}
+
+function equals(o1, o2) {
+ var k1 = Object.keys(o1).sort();
+ var k2 = Object.keys(o2).sort();
+ if (k1.length != k2.length) return false;
+ return k1.zip(k2, function(keyPair) {
+ if(typeof o1[keyPair[0]] == typeof o2[keyPair[1]] == "object"){
+ return equals(o1[keyPair[0]], o2[keyPair[1]])
+ } else {
+ return o1[keyPair[0]] == o2[keyPair[1]];
+ }
+ }).all();
+};
+
+function observer1(setting) {
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, 0.7, "Same settingvalue");
+};
+
+function observer2(setting) {
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, 0.7, "Same settingvalue");
+};
+
+function observerWithNext(setting) {
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, 0.7, "Same settingvalue");
+ next();
+};
+
+function onsettingschangeWithNext(event) {
+ is(event.settingName, "screen.brightness", "Same settingName");
+ is(event.settingValue, 0.7, "Same settingvalue");
+ next();
+};
+
+function check(o1, o2) {
+ is(JSON.stringify(o1), JSON.stringify(o2), "same");
+}
+
+var req, req2, req3, req4, req5, req6;
+var index = 0;
+
+var steps = [
+ function () {
+ ok(true, "Deleting database");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ },
+ function () {
+ ok(true, "Setting wifi");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifi);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ }
+ req.onerror = onFailure;
+
+ var lock2 = navigator.mozSettings.createLock();
+ req2 = lock2.get("net3g.apn");
+ req2.onsuccess = function () {
+ is(Object.keys(req2.result).length, 1, "length 1");
+ check(wifi, req2.result);
+ ok(true, "Get net3g.apn Done");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Change wifi1");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifi2);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ };
+ req.onerror = onFailure;
+ ok(true, "Get changed net3g.apn");
+ req2 = lock.get("net3g.apn");
+ req2.onsuccess = function () {
+ is(Object.keys(req2.result).length, 1, "length 1");
+ check(wifi2, req2.result);
+ ok(true, "Get net3g.apn Done");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Set Combination");
+ var lock = navigator.mozSettings.createLock();
+ req3 = lock.set(combination);
+ req3.onsuccess = function () {
+ ok(true, "set done");
+ req4 = lock.get("net3g.apn2");
+ req4.onsuccess = function() {
+ ok(true, "Done");
+ check(combination["net3g.apn2"], req4.result["net3g.apn2"]);
+ next();
+ }
+ }
+ req3.onerror = onFailure;
+ },
+ function() {
+ var lock = navigator.mozSettings.createLock();
+ req4 = lock.get("net3g.apn2");
+ req4.onsuccess = function() {
+ ok(true, "Done");
+ check(combination["net3g.apn2"], req4.result["net3g.apn2"]);
+ next();
+ }
+ req4.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Get unknown key");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("abc.def");
+ req.onsuccess = function() {
+ is(req.result["abc.def"], undefined, "no result");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "adding onsettingchange");
+ navigator.mozSettings.onsettingchange = onsettingschangeWithNext;
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.get("screen.brightness");
+ req2.onsuccess = function() {
+ ok(true, "end adding onsettingchange");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Test onsettingchange");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set done, observer has to call next");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "delete onsettingschange");
+ var lock = navigator.mozSettings.createLock();
+ navigator.mozSettings.onsettingchange = null;
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Waiting for all set callbacks");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function() {
+ ok(true, "Done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "adding Observers 1");
+ navigator.mozSettings.addObserver("screen.brightness", observer1);
+ navigator.mozSettings.addObserver("screen.brightness", observer1);
+ navigator.mozSettings.addObserver("screen.brightness", observer2);
+ navigator.mozSettings.addObserver("screen.brightness", observerWithNext);
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.get("screen.brightness");
+ req2.onsuccess = function() {
+ ok(true, "set observeSetting done!");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test observers");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ navigator.mozSettings.removeObserver("screen.brightness", observer2);
+ navigator.mozSettings.removeObserver("screen.brightness", observer1);
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ navigator.mozSettings.removeObserver("screen.brightness", observerWithNext);
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ navigator.mozSettings.removeObserver("screen.brightness", observer2);
+ navigator.mozSettings.removeObserver("screen.brightness", observer1);
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function () {
+ ok(true, "get done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Nested test");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function () {
+ req3 = lock.set({"screen.brightness": req.result["screen.brightness"] + 1})
+ req3.onsuccess = function () {
+ req4 = lock.get("screen.brightness");
+ req4.onsuccess = function() {
+ is(req4.result["screen.brightness"], 1.7, "same Value");
+ }
+ req4.onerror = onFailure;
+ }
+ req3.onerror = onFailure;
+ };
+ req.onerror = onFailure;
+
+ req2 = lock.get("screen.brightness");
+ req2.onsuccess = function () {
+ is(req2.result["screen.brightness"], 0.7, "same Value");
+ }
+ req2.onerror = onFailure;
+
+ var lock2 = navigator.mozSettings.createLock();
+ req5 = lock2.get("screen.brightness");
+ req5.onsuccess = function () {
+ is(req5.result["screen.brightness"], 1.7, "same Value");
+ next();
+ }
+ req5.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Deleting database");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ },
+ function () {
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.set(wifi);
+ req2.onsuccess = function () {
+ ok(true, "set done");
+ }
+ req2.onerror = onFailure;
+
+ ok(true, "Get all settings");
+ var lock2 = navigator.mozSettings.createLock();
+ req3 = lock2.get("*");
+ req3.onsuccess = function () {
+ is(Object.keys(req3.result).length, 1, "length 1");
+ check(req3.result, wifi);
+ ok(true, JSON.stringify(req3.result));
+ ok(true, "Get all settings Done");
+ };
+ req3.onerror = onFailure;
+
+ req4 = lock2.get("net3g.apn");
+ req4.onsuccess = function () {
+ is(Object.keys(req4.result).length, 1, "length 1");
+ check(wifi, req4.result);
+ ok(true, "Get net3g.apn Done");
+ next();
+ };
+ req4.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Change wifi1");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifi2);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ };
+ req.onerror = onFailure;
+
+ ok(true, "Get changed net3g.apn");
+ req2 = lock.get("net3g.apn");
+ req2.onsuccess = function () {
+ is(Object.keys(req2.result).length, 1, "length 1");
+ check(wifi2, req2.result);
+ ok(true, "Get net3g.apn Done");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Test locking");
+ var lock = navigator.mozSettings.createLock();
+ var lock2 = navigator.mozSettings.createLock();
+ req = lock.set(wifiEnabled);
+ req.onsuccess = function () {
+ ok(true, "Test Locking Done");
+ };
+ req.onerror = onFailure;
+
+ req2 = lock2.set(wifiDisabled);
+ req2.onsuccess = function () {
+ ok(true, "Set Done");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Test locking result");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("wifi.enabled");
+ req.onsuccess = function() {
+ check(req.result, wifiDisabled);
+ ok(true, "Test1 locking result done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Test locking heavy");
+ for (var i=0; i<30; i++) {
+ // only new locks!
+ var lock = navigator.mozSettings.createLock();
+ var obj = {};
+ obj["wifi.enabled" + i] = true;
+ req = lock.set( obj );
+ req.onsuccess = function () {
+ ok(true, "Set1 Done");
+ };
+ req.onerror = onFailure;
+ };
+ {
+ var lock2 = navigator.mozSettings.createLock();
+ req2 = lock2.get("*");
+ req2.onsuccess = function () {
+ is(Object.keys(req2.result).length, 32, "length 12");
+ ok(true, JSON.stringify(req2.result));
+ ok(true, "Get all settings Done");
+ };
+ req2.onerror = onFailure;
+ }
+ var lock2 = navigator.mozSettings.createLock();
+ var obj = {};
+ obj["wifi.enabled" + 30] = true;
+ req3 = lock2.set( obj );
+ req3.onsuccess = function () {
+ ok(true, "Set12 Done");
+ };
+ req3.onerror = onFailure;
+
+ var lock3 = navigator.mozSettings.createLock();
+ // with one lock
+ for (var i = 0; i < 30; i++) {
+ req4 = lock3.get("wifi.enabled" + i);
+ var testObj = {};
+ testObj["wifi.enabled" + i] = true;
+ req4.onsuccess = function () {
+ check(this.request.result, this.testObj);
+ ok(true, "Get1 Done");
+ }.bind({testObj: testObj, request: req4});
+ req4.onerror = onFailure;
+ }
+
+ ok(true, "start next2!");
+ var lock4 = navigator.mozSettings.createLock();
+ for (var i=0; i<30; i++) {
+ var obj = {};
+ obj["wifi.enabled" + i] = false;
+ req4 = lock4.set( obj );
+ req4.onsuccess = function () {
+ ok(true, "Set2 Done");
+ };
+ req4.onerror = onFailure;
+ }
+ var lock5 = navigator.mozSettings.createLock();
+ for (var i=0; i<30; i++) {
+ req5 = lock5.get("wifi.enabled" + i);
+ var testObj = {};
+ testObj["wifi.enabled" + i] = false;
+ req5.onsuccess = function () {
+ check(this.request.result, this.testObj);
+ ok(true, "Get2 Done");
+ }.bind({testObj: testObj, request: req5});
+ req5.onerror = onFailure;
+ }
+
+ var lock6 = navigator.mozSettings.createLock();
+ req6 = lock6.clear();
+ req6.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req6.onerror = onFailure;
+ },
+ function () {
+ ok(true, "reverse Test locking");
+ var lock2 = navigator.mozSettings.createLock();
+ var lock = navigator.mozSettings.createLock();
+
+ req = lock.set(wifiEnabled);
+ req.onsuccess = function () {
+ ok(true, "Test Locking Done");
+ next();
+ };
+ req.onerror = onFailure;
+
+ req2 = lock2.set(wifiDisabled);
+ req2.onsuccess = function () {
+ ok(true, "Set Done");
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Test locking result");
+ var lock = navigator.mozSettings.createLock();
+
+ req = lock.get("wifi.enabled");
+ req.onsuccess = function() {
+ check(req.result, wifiEnabled);
+ ok(true, "Test2 locking result done");
+ }
+ req.onerror = onFailure;
+
+ var lock2 = navigator.mozSettings.createLock();
+ req2 = lock2.clear();
+ req2.onsuccess = function () {
+ ok(true, "Deleted the database");
+ };
+ req2.onerror = onFailure;
+
+ var lock3 = navigator.mozSettings.createLock();
+ req3 = lock3.set(wifi);
+ req3.onsuccess = function () {
+ ok(true, "set done");
+ next();
+ }
+ req3.onerror = onFailure;
+
+ },
+ function () {
+ ok(true, "Get all settings");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("*");
+ req.onsuccess = function () {
+ is(Object.keys(req.result).length, 1, "length 1");
+ check(wifi, req.result);
+ ok(true, "Get all settings Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Get net3g.apn");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("net3g.apn");
+ req.onsuccess = function () {
+ is(Object.keys(req.result).length, 1, "length 1");
+ check(wifi, req.result);
+ ok(true, "Get net3g.apn Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Change wifi2");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifi2);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Get net3g.apn");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("net3g.apn");
+ req.onsuccess = function () {
+ is(Object.keys(req.result).length, 1, "length 1");
+ check(wifi2, req.result);
+ ok(true, "Get net3g.apn Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Add wifi.enabled");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifiEnabled);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Get Wifi Enabled");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("wifi.enabled");
+ req.onsuccess = function () {
+ is(Object.keys(req.result).length, 1, "length 1");
+ check(wifiEnabled, req.result);
+ ok(true, "Get wifi.enabledDone");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Get all");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("*");
+ req.onsuccess = function () {
+ is(Object.keys(req.result).length, 2, "length 2");
+ check(wifiEnabled["wifi.enabled"], req.result["wifi.enabled"]);
+ check(wifi2["net3g.apn"], req.result["net3g.apn"]);
+ ok(true, "Get all Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Add wifiNetworks");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifiNetworks0);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ };
+ req.onerror = onFailure;
+
+ req2 = lock.set(wifiNetworks1);
+ req2.onsuccess = function () {
+ ok(true, "Set Done");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Get Wifi Networks");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("wifi.networks[0]");
+ req.onsuccess = function () {
+ is(Object.keys(req.result).length, 1, "length 1");
+ check(wifiNetworks0, req.result);
+ ok(true, "Get wifi.networks[0]");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Clear DB, multiple locks");
+ var lock4 = navigator.mozSettings.createLock();
+ var lock3 = navigator.mozSettings.createLock();
+ var lock2 = navigator.mozSettings.createLock();
+ var lock = navigator.mozSettings.createLock();
+ var lock6 = navigator.mozSettings.createLock();
+ var lock7 = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Add wifiNetworks");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifiNetworks0);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Test set after lock closed");
+ var lockx = navigator.mozSettings.createLock();
+ var cb = function() {
+ var reqx = null;
+ try {
+ reqx = lockx.set(wifiNetworks0);
+ ok(false, "should have thrown");
+ } catch (ex) {
+ ok(reqx == null, "request is still null");
+ ok(true, "Caught Exception");
+ next();
+ }
+ }
+ SimpleTest.executeSoon(cb);
+ },
+ function() {
+ ok(true, "Clear DB");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Set with multiple arguments");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(combination);
+ req.onsuccess = function () {
+ ok(true, "Set Done");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "request argument from multiple set");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function () {
+ check(req.result["screen.brightness"], 0.7, "get done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Test closed attribute on a valid lock");
+ var lock = navigator.mozSettings.createLock();
+ is(lock.closed, false, "closed attribute is false on creation");
+ req = lock.get("screen.brightness");
+ req.onsuccess = function () {
+ is(lock.closed, false, "closed attribute is false on success callback");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Test closed attribute on invalid lock");
+ var lockx = navigator.mozSettings.createLock();
+ var cb = function() {
+ var reqx = null;
+ try {
+ reqx = lockx.set(wifiNetworks0);
+ ok(false, "should have thrown");
+ } catch (ex) {
+ is(lockx.closed, true, "closed attribute is true");
+ ok(true, "Caught Exception");
+ next();
+ }
+ }
+ SimpleTest.executeSoon(cb);
+ },
+ function() {
+ ok(true, "Clear DB");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Set object value");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set({"setting-obj": {foo: {bar: 23}}});
+ req.onsuccess = function() {
+ req2 = lock.get("setting-obj");
+ req2.onsuccess = function(event) {
+ var result = event.target.result["setting-obj"];
+ ok(result, "Got valid result");
+ ok(typeof result == "object", "Result is object");
+ ok("foo" in result && "bar" in result.foo, "Result has properties");
+ ok(result.foo.bar == 23, "Result properties are set");
+ next();
+ };
+ };
+ },
+ function() {
+ ok(true, "Clear DB");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Call success callback when transaction commits");
+ var lock = navigator.mozSettings.createLock();
+ lock.onsettingstransactionsuccess = function () {
+ next();
+ };
+ req = lock.set({"setting-obj": {foo: {bar: 23}}});
+ req.onsuccess = function() {
+ req2 = lock.get("setting-obj");
+ req2.onsuccess = function(event) {
+ var result = event.target.result["setting-obj"];
+ ok(result, "Got valid result");
+ ok(typeof result == "object", "Result is object");
+ ok("foo" in result && "bar" in result.foo, "Result has properties");
+ ok(result.foo.bar == 23, "Result properties are set");
+ };
+ };
+ },
+ function() {
+ ok(true, "Clear DB");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "all done!\n");
+ SimpleTest.finish();
+ }
+];
+
+function next() {
+ ok(true, "Begin!");
+ if (index >= steps.length) {
+ ok(false, "Shouldn't get here!");
+ return;
+ }
+ try {
+ steps[index]();
+ } catch(ex) {
+ ok(false, "Caught exception", ex);
+ }
+ index += 1;
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(next);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_blobs.html b/dom/settings/tests/test_settings_blobs.html
new file mode 100644
index 000000000..6d24111cf
--- /dev/null
+++ b/dom/settings/tests/test_settings_blobs.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=821630
+-->
+<head>
+ <title>Test for Bug 821630 Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821630">Mozilla Bug 821630</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript;version=1.7">
+
+"use strict";
+
+var url = SimpleTest.getTestFileURL("file_loadserver.js");
+var script = SpecialPowers.loadChromeScript(url);
+
+function onUnwantedSuccess() {
+ ok(false, "onUnwantedSuccess: shouldn't get here");
+}
+
+function onFailure() {
+ return function(s) {
+ if (s) {
+ ok(false, "in on Failure! - " + s);
+ } else {
+ ok(false, "in on Failure!");
+ }
+ }
+}
+
+let req;
+
+let storedBlob = new Blob(['12345'], {"type": "text/plain"});
+
+function checkBlob(blob) {
+ try {
+ let url = URL.createObjectURL(blob);
+ ok(true, "Valid blob");
+ } catch (e) {
+ ok(false, "Valid blob");
+ }
+}
+
+let steps = [
+ function() {
+ let lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = next;
+ req.onerror = onFailure("Deleting database");
+ },
+ function() {
+ function obs(e) {
+ checkBlob(e.settingValue);
+ navigator.mozSettings.removeObserver("test1", obs);
+ next();
+ }
+ navigator.mozSettings.addObserver("test1", obs);
+ next();
+ },
+ function() {
+ // next is called by the observer above
+ let req = navigator.mozSettings.createLock().set({"test1": storedBlob});
+ req.onerror = onFailure("Saving blob");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().get("test1");
+ req.onsuccess = function(event) {
+ checkBlob(event.target.result["test1"]);
+ next();
+ };
+ req.onerror = onFailure("Getting blob");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().set({"test2": [1, 2, storedBlob, 4]});
+ req.onsuccess = next;
+ req.onerror = onFailure("Saving array");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().get("test2");
+ req.onsuccess = function(event) {
+ let val = event.target.result["test2"];
+ ok(Array.isArray(val), "Result is an array");
+ ok(val[0] == 1 && val[1] == 2 && val[3] == 4, "Primitives are preserved");
+ checkBlob(val[2]);
+ next();
+ };
+ req.onerror = onFailure("Getting array");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().set({"test3": {foo: "bar", baz: {number: 1, arr: [storedBlob]}}});
+ req.onsuccess = next();
+ req.onerror = onFailure("Saving object");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().get("test3");
+ req.onsuccess = function(event) {
+ let val = event.target.result["test3"];
+ ok(typeof(val) == "object", "Result is an object");
+ ok("foo" in val && typeof(val.foo) == "string", "String property preserved");
+ ok("baz" in val && typeof(val.baz) == "object", "Object property preserved");
+ let baz = val.baz;
+ ok("number" in baz && baz.number == 1, "Primite inside object preserved");
+ ok("arr" in baz && Array.isArray(baz.arr), "Array inside object is preserved");
+ checkBlob(baz.arr[0]);
+ next();
+ };
+ req.onerror = onFailure("Getting object");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().clear();
+ req.onsuccess = function() {
+ next();
+ };
+ req.onerror = onFailure("Deleting database");
+ },
+ function () {
+ ok(true, "all done!\n");
+ SimpleTest.finish();
+ }
+];
+
+function next() {
+ try {
+ let step = steps.shift();
+ if (step) {
+ step();
+ }
+ } catch(ex) {
+ ok(false, "Caught exception", ex);
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(next);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_bug1110872.html b/dom/settings/tests/test_settings_bug1110872.html
new file mode 100644
index 000000000..296c71a8c
--- /dev/null
+++ b/dom/settings/tests/test_settings_bug1110872.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Test for Bug {1110872} Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ </head>
+ <body>
+ <script type="application/javascript;version=1.7" src="file_bug1110872.js">
+ </script>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1110872}">Mozilla Bug {1110872}</a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ </body>
+</html>
diff --git a/dom/settings/tests/test_settings_data_uris.html b/dom/settings/tests/test_settings_data_uris.html
new file mode 100644
index 000000000..7d9165fb3
--- /dev/null
+++ b/dom/settings/tests/test_settings_data_uris.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=806374
+-->
+<head>
+ <title>Test for Bug 806374 Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821630">Mozilla Bug 821630</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript;version=1.7">
+
+"use strict";
+
+var url = SimpleTest.getTestFileURL("file_loadserver.js");
+var script = SpecialPowers.loadChromeScript(url);
+
+function onUnwantedSuccess() {
+ ok(false, "onUnwantedSuccess: shouldn't get here");
+}
+
+function onFailure() {
+ return function(s) {
+ if (s) {
+ ok(false, "in on Failure! - " + s);
+ } else {
+ ok(false, "in on Failure!");
+ }
+ }
+}
+
+let req;
+
+// A simple data URI that will be converted to a blob.
+let dataURI = "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;";
+
+function checkBlob(blob) {
+ try {
+ let url = URL.createObjectURL(blob);
+ ok(true, "Valid blob");
+ } catch (e) {
+ ok(false, "Valid blob");
+ }
+}
+
+let steps = [
+ function() {
+ let lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = next;
+ req.onerror = onFailure("Deleting database");
+ },
+ function() {
+ function obs(e) {
+ checkBlob(e.settingValue);
+ navigator.mozSettings.removeObserver("test1", obs);
+ next();
+ }
+ navigator.mozSettings.addObserver("test1", obs);
+ next();
+ },
+ function() {
+ // next is called by the observer above
+ let req = navigator.mozSettings.createLock().set({"test1": dataURI});
+ req.onerror = onFailure("Saving blob");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().get("test1");
+ req.onsuccess = function(event) {
+ checkBlob(event.target.result["test1"]);
+ next();
+ };
+ req.onerror = onFailure("Getting blob");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().set({"test2": [1, 2, dataURI, 4]});
+ req.onsuccess = next;
+ req.onerror = onFailure("Saving array");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().get("test2");
+ req.onsuccess = function(event) {
+ let val = event.target.result["test2"];
+ ok(Array.isArray(val), "Result is an array");
+ ok(val[0] == 1 && val[1] == 2 && val[3] == 4, "Primitives are preserved");
+ checkBlob(val[2]);
+ next();
+ };
+ req.onerror = onFailure("Getting array");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().set({"test3": {foo: "bar", baz: {number: 1, arr: [dataURI]}}});
+ req.onsuccess = next();
+ req.onerror = onFailure("Saving object");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().get("test3");
+ req.onsuccess = function(event) {
+ let val = event.target.result["test3"];
+ ok(typeof(val) == "object", "Result is an object");
+ ok("foo" in val && typeof(val.foo) == "string", "String property preserved");
+ ok("baz" in val && typeof(val.baz) == "object", "Object property preserved");
+ let baz = val.baz;
+ ok("number" in baz && baz.number == 1, "Primite inside object preserved");
+ ok("arr" in baz && Array.isArray(baz.arr), "Array inside object is preserved");
+ checkBlob(baz.arr[0]);
+ next();
+ };
+ req.onerror = onFailure("Getting object");
+ },
+ function() {
+ let req = navigator.mozSettings.createLock().clear();
+ req.onsuccess = function() {
+ next();
+ };
+ req.onerror = onFailure("Deleting database");
+ },
+ function () {
+ ok(true, "all done!\n");
+ SimpleTest.finish();
+ }
+];
+
+function next() {
+ try {
+ let step = steps.shift();
+ if (step) {
+ step();
+ }
+ } catch(ex) {
+ ok(false, "Caught exception", ex);
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(next);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_events.html b/dom/settings/tests/test_settings_events.html
new file mode 100644
index 000000000..a8bf851be
--- /dev/null
+++ b/dom/settings/tests/test_settings_events.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=678695
+-->
+<head>
+ <title>Test for Bug 678695</title>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695">Mozilla Bug 678695</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 678695 **/
+
+var e = new MozSettingsEvent("settingchanged", {settingName: "a", settingValue: 1});
+ok(e, "Should have settings event!");
+is(e.settingName, "a", "Name should be a.");
+is(e.settingValue, 1, "Value should be 1.");
+
+e = new MozSettingsEvent("settingchanged", {settingName: "test", settingValue: {test: "test"}});
+is(e.settingName, "test", "Name should be 'test'.");
+is(e.settingValue.test, "test", "Name should be 'test'.");
+
+e = new MozSettingsEvent("settingchanged", {settingName: "a", settingValue: true});
+is(e.settingName, "a", "Name should be a.");
+is(e.settingValue, true, "Value should be true.");
+
+var e = new MozSettingsTransactionEvent("settingtransactionsuccess", {});
+ok(e, "Should have settings event!");
+is(e.error, "", "error should be null");
+
+var e = new MozSettingsTransactionEvent("settingtransactionfailure", {error: "Test error."});
+ok(e, "Should have settings event!");
+is(e.error, "Test error.", "error should be 'Test error.'");
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_navigator_object.html b/dom/settings/tests/test_settings_navigator_object.html
new file mode 100644
index 000000000..2f666aee0
--- /dev/null
+++ b/dom/settings/tests/test_settings_navigator_object.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=898512
+-->
+<head>
+ <title>Test for Bug 898512 Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=898512">Mozilla Bug 898512</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript;version=1.7">
+
+SimpleTest.waitForExplicitFinish();
+
+function testPref() {
+ SpecialPowers.pushPrefEnv({
+ set: [["dom.mozSettings.enabled", false]]
+ }, function() {
+ is(navigator.mozSettings, undefined, "navigator.mozSettings is undefined");
+ SimpleTest.finish();
+ });
+}
+
+testPref();
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_observer_killer.html b/dom/settings/tests/test_settings_observer_killer.html
new file mode 100644
index 000000000..8e7ed973c
--- /dev/null
+++ b/dom/settings/tests/test_settings_observer_killer.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1193469
+-->
+<head>
+ <title>Test for Bug 1193469 Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1193469">Mozilla Bug 1193469</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript;version=1.7">
+
+var url = SimpleTest.getTestFileURL("file_loadserver.js");
+var script = SpecialPowers.loadChromeScript(url);
+
+SimpleTest.waitForExplicitFinish();
+
+SpecialPowers.pushPrefEnv({
+ set: [["dom.mozSettings.enabled", true]]
+},
+ function () {
+ ok(true, "abusing observers");
+
+ var obs;
+ for (obs = 0; obs < 9; obs++) {
+ navigator.mozSettings.addObserver("fake.setting.key", function(v) {
+ // nothing to do for real ...
+ ok(false, "should not be called");
+ });
+ ok(true, "first: added observer #" + obs);
+ }
+ ok(true, "adding first observers, should not have thrown");
+
+ try {
+ ok(true, "second: adding new observer");
+ navigator.mozSettings.addObserver("fake.setting.key", function(v) {
+ // nothing to do for real ...
+ ok(false, "should not be called");
+ });
+ ok(false, "adding too many observers should have thrown");
+ } catch (ex) {
+ ok(true, "got exception when trying to add too many observers");
+ }
+
+ SimpleTest.finish();
+ });
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_onsettingchange.html b/dom/settings/tests/test_settings_onsettingchange.html
new file mode 100644
index 000000000..974da0c63
--- /dev/null
+++ b/dom/settings/tests/test_settings_onsettingchange.html
@@ -0,0 +1,306 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=678695
+-->
+<head>
+ <title>Test for Bug 678695 Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695">Mozilla Bug 678695</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+"use strict";
+
+var url = SimpleTest.getTestFileURL("file_loadserver.js");
+var script = SpecialPowers.loadChromeScript(url);
+
+var screenBright = {"screen.brightness": 0.7};
+
+function onFailure() {
+ ok(false, "in on Failure!");
+}
+
+function observer1(setting) {
+ dump("observer 1 called!\n");
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, 0.7, "Same settingvalue");
+};
+
+function observer2(setting) {
+ dump("observer 2 called!\n");
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, 0.7, "Same settingvalue");
+};
+
+var calls = 0;
+function observerOnlyCalledOnce(setting) {
+ is(++calls, 1, "Observer only called once!");
+};
+
+
+function observerWithNext(setting) {
+ dump("observer with next called!\n");
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, 0.7, "Same settingvalue");
+ next();
+};
+
+function onsettingschangeWithNext(event) {
+ dump("onsettingschangewithnext called!\n");
+ is(event.settingName, "screen.brightness", "Same settingName");
+ is(event.settingValue, 0.7, "Same settingvalue");
+ next();
+};
+
+var cset = {'a':'b','c':[{'d':'e'}]};
+
+function onComplexSettingschangeWithNext(event) {
+ is(event.settingName, "test.key", "Same settingName");
+ is(event.settingValue['a'], "b", "Same settingvalue");
+ var c = event.settingValue['c'];
+ ok(Array.isArray(c), "c is array!");
+ is(c[0]['d'], 'e', "Right settingValue!");
+ next();
+};
+
+var req, req2;
+var index = 0;
+
+var steps = [
+ function () {
+ ok(true, "Deleting database");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.set(screenBright);
+ req2.onsuccess = function () {
+ ok(true, "set done");
+ navigator.mozSettings.onsettingchange = onsettingschangeWithNext;
+ next();
+ }
+ req2.onerror = onFailure;
+ },
+ function() {
+ ok(true, "testing");
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.set(screenBright);
+ req2.onsuccess = function() {
+ ok(true, "end adding onsettingchange");
+ };
+ req2.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test observers");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function () {
+ ok(true, "get done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "adding Observers 1");
+ navigator.mozSettings.addObserver("screen.brightness", observer1);
+ navigator.mozSettings.addObserver("screen.brightness", observer1);
+ navigator.mozSettings.addObserver("screen.brightness", observer2);
+ navigator.mozSettings.addObserver("screen.brightness", observerOnlyCalledOnce);
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.get("screen.brightness");
+ req2.onsuccess = function() {
+ ok(true, "set observeSetting done!");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test observers");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set1 done");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test observers");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ navigator.mozSettings.removeObserver("screen.brightness", observerOnlyCalledOnce);
+ req.onsuccess = function () {
+ ok(true, "set1 done");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set2 done");
+ navigator.mozSettings.removeObserver("screen.brightness", observer2);
+ navigator.mozSettings.removeObserver("screen.brightness", observer1);
+ navigator.mozSettings.removeObserver("screen.brightness", observer1);
+ }
+ req.onerror = onFailure;
+ },
+
+ function() {
+ ok(true, "delete onsettingschange");
+ var lock = navigator.mozSettings.createLock();
+ navigator.mozSettings.onsettingchange = null;
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set0 done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Waiting for all set callbacks");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function() {
+ ok(true, "Done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "adding Observers 1");
+ navigator.mozSettings.addObserver("screen.brightness", observer1);
+ navigator.mozSettings.addObserver("screen.brightness", observer1);
+ navigator.mozSettings.addObserver("screen.brightness", observer2);
+ navigator.mozSettings.addObserver("screen.brightness", observerWithNext);
+ var lock = navigator.mozSettings.createLock();
+ req2 = lock.get("screen.brightness");
+ req2.onsuccess = function() {
+ ok(true, "set observeSetting done!");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test observers");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set1 done");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set2 done");
+ navigator.mozSettings.removeObserver("screen.brightness", observer2);
+ navigator.mozSettings.removeObserver("screen.brightness", observer1);
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "test Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set3 done");
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ navigator.mozSettings.removeObserver("screen.brightness", observerWithNext);
+ req = lock.set(screenBright);
+ req.onsuccess = function () {
+ ok(true, "set4 done");
+ navigator.mozSettings.removeObserver("screen.brightness", observer2);
+ navigator.mozSettings.removeObserver("screen.brightness", observer1);
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "removing Event Listener");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("screen.brightness");
+ req.onsuccess = function () {
+ ok(true, "get5 done");
+ next();
+ }
+ req.onerror = onFailure;
+ },
+ function() {
+ ok(true, "Clear DB");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Deleting database");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.clear();
+ req.onsuccess = function () {
+ ok(true, "Deleted the database");
+ next();
+ };
+ req.onerror = onFailure;
+ },
+ function () {
+ var lock = navigator.mozSettings.createLock();
+ navigator.mozSettings.onsettingchange = onComplexSettingschangeWithNext;
+ req2 = navigator.mozSettings.createLock().set({'test.key': cset});
+ req2.onsuccess = function () {
+ ok(true, "set done");
+ }
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "all done!\n");
+ SimpleTest.finish();
+ }
+];
+
+function next() {
+ ok(true, "Begin!");
+ if (index >= steps.length) {
+ ok(false, "Shouldn't get here!");
+ return;
+ }
+ try {
+ steps[index]();
+ } catch(ex) {
+ ok(false, "Caught exception", ex);
+ }
+ index += 1;
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(next);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_permissions.html b/dom/settings/tests/test_settings_permissions.html
new file mode 100644
index 000000000..4cc02385a
--- /dev/null
+++ b/dom/settings/tests/test_settings_permissions.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
+-->
+<head>
+ <title>Test for Bug {678695} Settings API</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={900551}">Mozilla Bug {900551}</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+"use strict";
+
+var url = SimpleTest.getTestFileURL("file_loadserver.js");
+var script = SpecialPowers.loadChromeScript(url);
+
+function onUnwantedSuccess() {
+ ok(false, "onUnwantedSuccess: shouldn't get here");
+}
+
+// No more permissions, so failure cannot happen
+function onFailure() {
+ ok(true, "in on Failure!");
+ next();
+}
+
+const wifi = {"wifi.enabled": false}
+const wallpaper = {"wallpaper.image": "test-image"};
+
+var combination = {
+ "wifi.enabled": false,
+ "wallpaper.image": "test-image"
+}
+
+function equals(o1, o2) {
+ var k1 = Object.keys(o1).sort();
+ var k2 = Object.keys(o2).sort();
+ if (k1.length != k2.length) return false;
+ return k1.zip(k2, function(keyPair) {
+ if(typeof o1[keyPair[0]] == typeof o2[keyPair[1]] == "object"){
+ return equals(o1[keyPair[0]], o2[keyPair[1]])
+ } else {
+ return o1[keyPair[0]] == o2[keyPair[1]];
+ }
+ }).all();
+};
+
+function observer1(setting) {
+ is(setting.settingName, "screen.brightness", "Same settingName");
+ is(setting.settingValue, "0.7", "Same settingvalue");
+};
+
+function onsettingschangeWithNext(event) {
+ is(event.settingName, "screen.brightness", "Same settingName");
+ is(event.settingValue, "0.7", "Same settingvalue");
+ next();
+};
+
+function check(o1, o2) {
+ is(JSON.stringify(o1), JSON.stringify(o2), "same");
+}
+
+var req, req2, req3, req4, req5, req6;
+var index = 0;
+
+var steps = [
+ // Can't delete database here since that requires permissions we don't want
+ // to give the page.
+ function () {
+ ok(true, "Setting wallpaper");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wallpaper);
+ req.onsuccess = function () {
+ ok(true, "set done");
+ }
+ req.onerror = onFailure;
+
+ var lock2 = navigator.mozSettings.createLock();
+ req2 = lock2.get("wallpaper.image");
+ req2.onsuccess = function () {
+ is(Object.keys(req2.result).length, 1, "length 1");
+ check(wallpaper, req2.result);
+ ok(true, "Get wallpaper Done");
+ next();
+ };
+ req2.onerror = onFailure;
+ },
+ function () {
+ ok(true, "Get Wifi");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.get("wifi.enabled");
+ req.onerror = function () {
+ ok(true, "get failed (expected)");
+ next();
+ }
+ req.onsuccess = onFailure;
+ },
+ function () {
+ ok(true, "Set Wifi");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(wifi);
+ req.onerror = function () {
+ ok(true, "set failed (expected)");
+ next();
+ }
+ req.onsuccess = onFailure;
+ },
+ function () {
+ ok(true, "Set combination (1 valid 1 not valid)");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(combination);
+ req.onerror = function () {
+ ok(true, "set failed (expected)");
+ next();
+ }
+ req.onsuccess = onFailure;
+ },
+ function () {
+ ok(true, "All requests on a failed lock should fail");
+ var lock = navigator.mozSettings.createLock();
+ lock.onsettingstransactionfailure = function (evt) {
+ ok(evt.error == "Lock failed a permissions check, all requests now failing.", "transaction failure on permissions error message correct.");
+ ok(true, "transaction failed (expected) ");
+ next();
+ };
+ lock.onsettingstransactionsuccess = onFailure;
+
+ req = lock.set(wifi);
+ req.onerror = function () {
+ ok(true, "set failed (expected)");
+ }
+ req.onsuccess = onFailure;
+ req2 = lock.get("wallpaper.image");
+ req2.onerror = function () {
+ ok(true, "get failed (expected)");
+ }
+ req2.onsuccess = onFailure;
+ },
+ function () {
+ ok(true, "Set combination (1 valid 1 not valid)");
+ var lock = navigator.mozSettings.createLock();
+ req = lock.set(combination);
+ req.onerror = function () {
+ ok(true, "set failed (expected)");
+ next();
+ }
+ req.onsuccess = onFailure;
+ },
+ function () {
+ ok(true, "all done!\n");
+ SimpleTest.finish();
+ }
+];
+
+function next() {
+ ok(true, "Begin!");
+ if (index >= steps.length) {
+ ok(false, "Shouldn't get here!");
+ return;
+ }
+ try {
+ steps[index]();
+ } catch(ex) {
+ ok(false, "Caught exception", ex);
+ }
+ index += 1;
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(next);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/settings/tests/test_settings_service.js b/dom/settings/tests/test_settings_service.js
new file mode 100644
index 000000000..132877a5d
--- /dev/null
+++ b/dom/settings/tests/test_settings_service.js
@@ -0,0 +1,138 @@
+"use strict";
+
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+if (SpecialPowers.isMainProcess()) {
+ SpecialPowers.Cu.import("resource://gre/modules/SettingsRequestManager.jsm");
+}
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+SimpleTest.waitForExplicitFinish();
+
+XPCOMUtils.defineLazyServiceGetter(this, "SettingsService",
+ "@mozilla.org/settingsService;1",
+ "nsISettingsService");
+
+var tests = [
+ /* Callback tests */
+ function() {
+ let callbackCount = 10;
+
+ let callback = {
+ handle: function(name, result) {
+ switch (callbackCount) {
+ case 10:
+ case 9:
+ is(result, true, "result is true");
+ break;
+ case 8:
+ case 7:
+ is(result, false, "result is false");
+ break;
+ case 6:
+ case 5:
+ is(result, 9, "result is 9");
+ break;
+ case 4:
+ case 3:
+ is(result, 9.4, "result is 9.4");
+ break;
+ case 2:
+ is(result, false, "result is false");
+ break;
+ case 1:
+ is(result, null, "result is null");
+ break;
+ default:
+ ok(false, "Unexpected call: " + callbackCount);
+ }
+
+ --callbackCount;
+ if (callbackCount === 0) {
+ next();
+ }
+ },
+
+ handleError: function(name) {
+ ok(false, "error: " + name);
+ }
+ };
+
+ let lock = SettingsService.createLock();
+ let lock1 = SettingsService.createLock();
+
+ lock.set("asdf", true, callback, null);
+ lock1.get("asdf", callback);
+ lock.get("asdf", callback);
+ lock.set("asdf", false, callback, null);
+ lock.get("asdf", callback);
+ lock.set("int", 9, callback, null);
+ lock.get("int", callback);
+ lock.set("doub", 9.4, callback, null);
+ lock.get("doub", callback);
+ lock1.get("asdfxxx", callback);
+ },
+
+ /* Observer tests */
+ function() {
+ const MOZSETTINGS_CHANGED = "mozsettings-changed";
+ const TEST_OBSERVER_KEY = "test.observer.key";
+ const TEST_OBSERVER_VALUE = true;
+ const TEST_OBSERVER_MESSAGE = "test.observer.message";
+
+ var obs = {
+ observe: function (subject, topic, data) {
+
+ if (topic !== MOZSETTINGS_CHANGED) {
+ ok(false, "Event is not mozsettings-changed.");
+ return;
+ }
+ // Data is now stored in subject
+ if ("wrappedJSObject" in subject) {
+ ok(true, "JS object wrapped into subject");
+ subject = subject.wrappedJSObject;
+ }
+ if (subject["key"] != TEST_OBSERVER_KEY) {
+ return;
+ }
+
+ function checkProp(name, type, value) {
+ ok(name in subject, "subject." + name + " is present");
+ is(typeof subject[name], type, "subject." + name + " is " + type);
+ is(subject[name], value, "subject." + name + " is " + value);
+ }
+
+ checkProp("key", "string", TEST_OBSERVER_KEY);
+ checkProp("value", "boolean", TEST_OBSERVER_VALUE);
+ checkProp("isInternalChange", "boolean", true);
+
+ Services.obs.removeObserver(this, MOZSETTINGS_CHANGED);
+ next();
+ }
+ };
+
+ Services.obs.addObserver(obs, MOZSETTINGS_CHANGED, false);
+
+ let lock = SettingsService.createLock();
+ lock.set(TEST_OBSERVER_KEY, TEST_OBSERVER_VALUE, null);
+ }
+];
+
+function next() {
+ let step = tests.shift();
+ if (step) {
+ try {
+ step();
+ } catch(e) {
+ ok(false, "Test threw: " + e);
+ }
+ } else {
+ SimpleTest.finish();
+ }
+}
+
+next();
diff --git a/dom/settings/tests/test_settings_service.xul b/dom/settings/tests/test_settings_service.xul
new file mode 100644
index 000000000..58a9efad9
--- /dev/null
+++ b/dom/settings/tests/test_settings_service.xul
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=678695
+-->
+<window title="Mozilla Bug 678695"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695"
+ target="_blank">Mozilla Bug 678695</a>
+ </body>
+
+ <script type="application/javascript;version=1.7" src="test_settings_service.js" />
+</window>
diff --git a/dom/settings/tests/test_settings_service_callback.js b/dom/settings/tests/test_settings_service_callback.js
new file mode 100644
index 000000000..a780bb9c3
--- /dev/null
+++ b/dom/settings/tests/test_settings_service_callback.js
@@ -0,0 +1,47 @@
+"use strict";
+
+var Cu = Components.utils;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+SimpleTest.waitForExplicitFinish();
+
+XPCOMUtils.defineLazyServiceGetter(this, "SettingsService",
+ "@mozilla.org/settingsService;1",
+ "nsISettingsService");
+
+var tests = [
+ function () {
+ let callback = {
+ handle: function() {
+ ok(true, "handle called!");
+ next();
+ },
+
+ handleAbort: function(name) {
+ ok(false, "error: " + name);
+ next();
+ }
+ }
+ let lock = SettingsService.createLock(callback);
+ lock.set("xasdf", true, null, null);
+ }
+];
+
+function next() {
+ let step = tests.shift();
+ if (step) {
+ try {
+ step();
+ } catch(e) {
+ ok(false, "Test threw: " + e);
+ }
+ } else {
+ SimpleTest.finish();
+ }
+}
+
+next();
diff --git a/dom/settings/tests/test_settings_service_callback.xul b/dom/settings/tests/test_settings_service_callback.xul
new file mode 100644
index 000000000..3e4d27751
--- /dev/null
+++ b/dom/settings/tests/test_settings_service_callback.xul
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1012214
+-->
+<window title="Mozilla Bug 1012214"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1012214"
+ target="_blank">Mozilla Bug 1012214</a>
+ </body>
+
+ <script type="application/javascript;version=1.7" src="test_settings_service_callback.js" />
+</window>
diff --git a/dom/settings/tests/unit/test_settingsrequestmanager_messages.js b/dom/settings/tests/unit/test_settingsrequestmanager_messages.js
new file mode 100644
index 000000000..e5fb08475
--- /dev/null
+++ b/dom/settings/tests/unit/test_settingsrequestmanager_messages.js
@@ -0,0 +1,174 @@
+"use strict";
+
+var Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+ "@mozilla.org/childprocessmessagemanager;1",
+ "nsIMessageSender");
+
+var principal = Services.scriptSecurityManager.getSystemPrincipal();
+var lockID = "{435d2192-4f21-48d4-90b7-285f147a56be}";
+
+// Helper to start the Settings Request Manager
+function startSettingsRequestManager() {
+ Cu.import("resource://gre/modules/SettingsRequestManager.jsm");
+}
+
+function handlerHelper(reply, callback, runNext = true) {
+ let handler = {
+ receiveMessage: function(message) {
+ if (message.name === reply) {
+ cpmm.removeMessageListener(reply, handler);
+ callback(message);
+ if (runNext) {
+ run_next_test();
+ }
+ }
+ }
+ };
+ cpmm.addMessageListener(reply, handler);
+}
+
+// Helper function to add a listener, send message and treat the reply
+function addAndSend(msg, reply, callback, payload, runNext = true) {
+ handlerHelper(reply, callback, runNext);
+ cpmm.sendAsyncMessage(msg, payload, undefined, principal);
+}
+
+function errorHandler(reply, str) {
+ let errHandler = function(message) {
+ ok(true, str);
+ };
+
+ handlerHelper(reply, errHandler);
+}
+
+// We need to trigger a Settings:Run message to make the queue progress
+function send_settingsRun() {
+ let msg = {lockID: lockID, isServiceLock: true};
+ cpmm.sendAsyncMessage("Settings:Run", msg, undefined, principal);
+}
+
+function kill_child() {
+ let msg = {lockID: lockID, isServiceLock: true};
+ cpmm.sendAsyncMessage("child-process-shutdown", msg, undefined, principal);
+}
+
+function run_test() {
+ do_get_profile();
+ startSettingsRequestManager();
+ run_next_test();
+}
+
+add_test(function test_createLock() {
+ let msg = {lockID: lockID, isServiceLock: true};
+ cpmm.sendAsyncMessage("Settings:CreateLock", msg, undefined, principal);
+ cpmm.sendAsyncMessage(
+ "Settings:RegisterForMessages", undefined, undefined, principal);
+ ok(true);
+ run_next_test();
+});
+
+add_test(function test_get_empty() {
+ let requestID = 10;
+ let msgReply = "Settings:Get:OK";
+ let msgHandler = function(message) {
+ equal(requestID, message.data.requestID);
+ equal(lockID, message.data.lockID);
+ ok(Object.keys(message.data.settings).length >= 0);
+ };
+
+ errorHandler("Settings:Get:KO", "Settings GET failed");
+
+ addAndSend("Settings:Get", msgReply, msgHandler, {
+ requestID: requestID,
+ lockID: lockID,
+ name: "language.current"
+ });
+
+ send_settingsRun();
+});
+
+add_test(function test_set_get_nonempty() {
+ let settings = { "language.current": "fr-FR:XPC" };
+ let requestIDSet = 20;
+ let msgReplySet = "Settings:Set:OK";
+ let msgHandlerSet = function(message) {
+ equal(requestIDSet, message.data.requestID);
+ equal(lockID, message.data.lockID);
+ };
+
+ errorHandler("Settings:Set:KO", "Settings SET failed");
+
+ addAndSend("Settings:Set", msgReplySet, msgHandlerSet, {
+ requestID: requestIDSet,
+ lockID: lockID,
+ settings: settings
+ }, false);
+
+ let requestIDGet = 25;
+ let msgReplyGet = "Settings:Get:OK";
+ let msgHandlerGet = function(message) {
+ equal(requestIDGet, message.data.requestID);
+ equal(lockID, message.data.lockID);
+ for(let p in settings) {
+ equal(settings[p], message.data.settings[p]);
+ }
+ };
+
+ addAndSend("Settings:Get", msgReplyGet, msgHandlerGet, {
+ requestID: requestIDGet,
+ lockID: lockID,
+ name: Object.keys(settings)[0]
+ });
+
+ // Set and Get have been push into the queue, let's run
+ send_settingsRun();
+});
+
+// This test exposes bug 1076597 behavior
+add_test(function test_wait_for_finalize() {
+ let settings = { "language.current": "en-US:XPC" };
+ let requestIDSet = 30;
+ let msgReplySet = "Settings:Set:OK";
+ let msgHandlerSet = function(message) {
+ equal(requestIDSet, message.data.requestID);
+ equal(lockID, message.data.lockID);
+ };
+
+ errorHandler("Settings:Set:KO", "Settings SET failed");
+
+ addAndSend("Settings:Set", msgReplySet, msgHandlerSet, {
+ requestID: requestIDSet,
+ lockID: lockID,
+ settings: settings
+ }, false);
+
+ let requestIDGet = 35;
+ let msgReplyGet = "Settings:Get:OK";
+ let msgHandlerGet = function(message) {
+ equal(requestIDGet, message.data.requestID);
+ equal(lockID, message.data.lockID);
+ for(let p in settings) {
+ equal(settings[p], message.data.settings[p]);
+ }
+ };
+
+ errorHandler("Settings:Get:KO", "Settings GET failed");
+
+ addAndSend("Settings:Get", msgReplyGet, msgHandlerGet, {
+ requestID: requestIDGet,
+ lockID: lockID,
+ name: Object.keys(settings)[0]
+ });
+
+ // We simulate a child death, which will force previous requests to be set
+ // into finalize state
+ kill_child();
+
+ // Then when we issue Settings:Run, those finalized should be triggered
+ send_settingsRun();
+});
diff --git a/dom/settings/tests/unit/xpcshell.ini b/dom/settings/tests/unit/xpcshell.ini
new file mode 100644
index 000000000..9669a1ed0
--- /dev/null
+++ b/dom/settings/tests/unit/xpcshell.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+head =
+tail =
+
+[test_settingsrequestmanager_messages.js]
+skip-if = (buildapp != 'b2g')