Attachment #8845411: Bug 1286717 - Part 2: Add mochitests for persist/persisted functions for bug #1286717

View | Details | Raw Unified | Return to bug 1286717
Collapse All | Expand All

(-)a/dom/quota/moz.build (+4 lines)
Line     Link Here 
 Lines 2-17    Link Here 
2
# vim: set filetype=python:
2
# vim: set filetype=python:
3
# This Source Code Form is subject to the terms of the Mozilla Public
3
# This Source Code Form is subject to the terms of the Mozilla Public
4
# License, v. 2.0. If a copy of the MPL was not distributed with this
4
# License, v. 2.0. If a copy of the MPL was not distributed with this
5
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
6
7
with Files("**"):
7
with Files("**"):
8
    BUG_COMPONENT = ("Core", "DOM: Quota Manager")
8
    BUG_COMPONENT = ("Core", "DOM: Quota Manager")
9
9
10
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
11
12
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
13
10
XPCSHELL_TESTS_MANIFESTS += [
14
XPCSHELL_TESTS_MANIFESTS += [
11
    'test/unit/xpcshell.ini'
15
    'test/unit/xpcshell.ini'
12
]
16
]
13
17
14
XPIDL_SOURCES += [
18
XPIDL_SOURCES += [
15
    'nsIQuotaCallbacks.idl',
19
    'nsIQuotaCallbacks.idl',
16
    'nsIQuotaManagerService.idl',
20
    'nsIQuotaManagerService.idl',
17
    'nsIQuotaRequests.idl',
21
    'nsIQuotaRequests.idl',
(-)a/dom/quota/test/browser.ini (+9 lines)
Line     Link Here 
Line 0    Link Here 
1
[DEFAULT]
2
skip-if = (buildapp != "browser")
3
support-files =
4
  head.js
5
  browserHelpers.js
6
  browser_permissionsPrompt.html
7
8
[browser_permissionsPromptAllow.js]
9
[browser_permissionsPromptDeny.js]
(-)a/dom/quota/test/browserHelpers.js (+46 lines)
Line     Link Here 
Line 0    Link Here 
1
/**
2
 * Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/publicdomain/zero/1.0/
4
 */
5
6
var testGenerator = testSteps();
7
8
var testResult;
9
var testException;
10
11
function clearAllDatabases(callback)
12
{
13
  let qms = SpecialPowers.Services.qms;
14
  let principal = SpecialPowers.wrap(document).nodePrincipal;
15
  let request = qms.clearStoragesForPrincipal(principal);
16
  let cb = SpecialPowers.wrapCallback(callback);
17
  request.callback = cb;
18
}
19
20
function runTest()
21
{
22
  testGenerator.next();
23
}
24
25
function continueToNextStep()
26
{
27
  SimpleTest.executeSoon(function() {
28
    testGenerator.next();
29
  });
30
}
31
32
function finishTestNow()
33
{
34
  if (testGenerator) {
35
    testGenerator.return();
36
    testGenerator = undefined;
37
  }
38
}
39
40
function finishTest()
41
{
42
  setTimeout(finishTestNow, 0);
43
  setTimeout(() => {
44
    window.parent.postMessage(testResult, "*");
45
  }, 0);
46
}
(-)a/dom/quota/test/browser_permissionsPrompt.html (+48 lines)
Line     Link Here 
Line 0    Link Here 
1
<!--
2
  Any copyright is dedicated to the Public Domain.
3
  http://creativecommons.org/publicdomain/zero/1.0/
4
-->
5
<html>
6
  <head>
7
    <meta charset=UTF-8>
8
    <title>Persistent-Storage Permission Prompt Test</title>
9
    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10
11
    <script type="text/javascript;version=1.7">
12
      function* testSteps()
13
      {
14
        SpecialPowers.pushPrefEnv({
15
          "set": [["dom.storageManager.enabled", true],
16
                  ["dom.storageManager.prompt.testing", false],
17
                  ["dom.storageManager.prompt.testing.allow", false]]
18
        }, continueToNextStep);
19
        yield undefined;
20
21
        clearAllDatabases(continueToNextStep);
22
        yield undefined;
23
24
        navigator.storage.persist().then(result => {
25
          testGenerator.next(result);
26
        });
27
        testResult = yield undefined;
28
29
        info("Persist() result: " + testResult);
30
31
        navigator.storage.persisted().then(result => {
32
          testGenerator.next(result);
33
        });
34
        let persistedResult = yield undefined;
35
36
        info("Persisted() result: " + persistedResult);
37
38
        is(testResult, persistedResult, "Persist/persisted results are consistent");
39
40
        finishTest();
41
      }
42
    </script>
43
44
    <script type="text/javascript;version=1.7" src="browserHelpers.js"></script>
45
  </head>
46
47
  <body onload="runTest();" onunload="finishTestNow();"></body>
48
</html>
(-)a/dom/quota/test/browser_permissionsPromptAllow.js (+102 lines)
Line     Link Here 
Line 0    Link Here 
1
/**
2
 * Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/publicdomain/zero/1.0/
4
 */
5
6
const testPageURL =
7
  "https://example.com/browser/dom/quota/test/browser_permissionsPrompt.html";
8
9
add_task(function* testPermissionAllow() {
10
  info("Creating tab");
11
  gBrowser.selectedTab = gBrowser.addTab();
12
13
  info("Loading test page: " + testPageURL);
14
  gBrowser.selectedBrowser.loadURI(testPageURL);
15
  yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
16
17
  registerPopupEventHandler("popupshowing", function () {
18
    ok(true, "prompt showing");
19
  });
20
  registerPopupEventHandler("popupshown", function () {
21
    ok(true, "prompt shown");
22
    triggerMainCommand(this);
23
  });
24
  registerPopupEventHandler("popuphidden", function () {
25
    ok(true, "prompt hidden");
26
  });
27
28
  yield promiseMessage(true, gBrowser);
29
30
  is(getPermission(testPageURL, "persistent-storage"),
31
     Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
32
     "Correct permission set");
33
  gBrowser.removeCurrentTab();
34
35
  // Keep persistent-storage permission for the next test.
36
  unregisterAllPopupEventHandlers();
37
});
38
39
add_task(function* testPermissionAllowInPrivateWindow() {
40
  info("Creating private window");
41
  let win = yield BrowserTestUtils.openNewBrowserWindow({ private : true });
42
43
  info("Creating private tab");
44
  win.gBrowser.selectedTab = win.gBrowser.addTab();
45
46
  info("Loading test page: " + testPageURL);
47
  win.gBrowser.selectedBrowser.loadURI(testPageURL);
48
  yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
49
50
  // PermissionManager is not supposed to have any knowledge of private browsing,
51
  // Prompt shall not be displayed.
52
  registerPopupEventHandler("popupshowing", function () {
53
    ok(false, "Shouldn't show a popup this time");
54
  });
55
  registerPopupEventHandler("popupshown", function () {
56
    ok(false, "Shouldn't show a popup this time");
57
  });
58
  registerPopupEventHandler("popuphidden", function () {
59
    ok(false, "Shouldn't show a popup this time");
60
  });
61
62
  yield promiseMessage(true, win.gBrowser);
63
64
  is(getPermission(testPageURL, "persistent-storage"),
65
     Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
66
     "Correct permission set");
67
68
  unregisterAllPopupEventHandlers();
69
  removePermission(testPageURL, "persistent-storage");
70
  win.gBrowser.removeCurrentTab();
71
  win.close();
72
});
73
74
add_task(function* testPermissionAllow() {
75
  info("Creating tab");
76
  gBrowser.selectedTab = gBrowser.addTab();
77
78
  info("Loading test page: " + testPageURL);
79
  gBrowser.selectedBrowser.loadURI(testPageURL);
80
  yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
81
82
  registerPopupEventHandler("popupshowing", function () {
83
    ok(true, "prompt showing");
84
  });
85
  registerPopupEventHandler("popupshown", function () {
86
    ok(true, "prompt shown");
87
    triggerMainCommand(this);
88
  });
89
  registerPopupEventHandler("popuphidden", function () {
90
    ok(true, "prompt hidden");
91
  });
92
93
  yield promiseMessage(true, gBrowser);
94
95
  is(getPermission(testPageURL, "persistent-storage"),
96
     Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
97
     "Correct permission set");
98
99
  gBrowser.removeCurrentTab();
100
  unregisterAllPopupEventHandlers();
101
  removePermission(testPageURL, "persistent-storage");
102
});
(-)a/dom/quota/test/browser_permissionsPromptDeny.js (+97 lines)
Line     Link Here 
Line 0    Link Here 
1
/**
2
 * Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/publicdomain/zero/1.0/
4
 */
5
6
const testPageURL =
7
  "https://example.com/browser/dom/quota/test/browser_permissionsPrompt.html";
8
9
add_task(function* testPermissionDenied() {
10
  info("Creating tab");
11
  gBrowser.selectedTab = gBrowser.addTab();
12
13
  info("Loading test page: " + testPageURL);
14
  gBrowser.selectedBrowser.loadURI(testPageURL);
15
  yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
16
17
  registerPopupEventHandler("popupshowing", function () {
18
    ok(true, "prompt showing");
19
  });
20
  registerPopupEventHandler("popupshown", function () {
21
    ok(true, "prompt shown");
22
    triggerSecondaryCommand(this);
23
  });
24
  registerPopupEventHandler("popuphidden", function () {
25
    ok(true, "prompt hidden");
26
  });
27
28
  yield promiseMessage(false, gBrowser);
29
30
  is(getPermission(testPageURL, "persistent-storage"),
31
     Components.interfaces.nsIPermissionManager.DENY_ACTION,
32
     "Correct permission set");
33
  gBrowser.removeCurrentTab();
34
  unregisterAllPopupEventHandlers();
35
});
36
37
add_task(function* testPermissionDeniedInPrivateWindow() {
38
  info("Creating private window");
39
  let win = yield BrowserTestUtils.openNewBrowserWindow({ private : true });
40
41
  info("Creating private tab");
42
  win.gBrowser.selectedTab = win.gBrowser.addTab();
43
44
  info("Loading test page: " + testPageURL);
45
  win.gBrowser.selectedBrowser.loadURI(testPageURL);
46
  yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
47
48
  // PermissionManager is not supposed to have any knowledge of private browsing,
49
  // Prompt shall not be displayed.
50
  registerPopupEventHandler("popupshowing", function () {
51
    ok(false, "Shouldn't show a popup this time");
52
  });
53
  registerPopupEventHandler("popupshown", function () {
54
    ok(false, "Shouldn't show a popup this time");
55
  });
56
  registerPopupEventHandler("popuphidden", function () {
57
    ok(false, "Shouldn't show a popup this time");
58
  });
59
  yield promiseMessage(false, win.gBrowser);
60
61
  is(getPermission(testPageURL, "persistent-storage"),
62
     Components.interfaces.nsIPermissionManager.DENY_ACTION,
63
     "Correct permission set");
64
  unregisterAllPopupEventHandlers();
65
  win.gBrowser.removeCurrentTab();
66
  win.close();
67
});
68
69
add_task(function* testPermissionDeniedDismiss() {
70
  info("Creating tab");
71
  gBrowser.selectedTab = gBrowser.addTab();
72
73
  info("Loading test page: " + testPageURL);
74
  gBrowser.selectedBrowser.loadURI(testPageURL);
75
  yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
76
77
  registerPopupEventHandler("popupshowing", function () {
78
    ok(true, "prompt showing");
79
  });
80
  registerPopupEventHandler("popupshown", function () {
81
    ok(true, "prompt shown");
82
    // Dismiss permission prompt.
83
    dismissNotification(this);
84
  });
85
  registerPopupEventHandler("popuphidden", function () {
86
    ok(true, "prompt hidden");
87
  });
88
89
  yield promiseMessage(false, gBrowser);
90
91
  is(getPermission(testPageURL, "persistent-storage"),
92
     Components.interfaces.nsIPermissionManager.DENY_ACTION,
93
     "Correct permission set");
94
  gBrowser.removeCurrentTab();
95
  unregisterAllPopupEventHandlers();
96
  removePermission(testPageURL, "persistent-storage");
97
});
(-)a/dom/quota/test/head.js (+126 lines)
Line     Link Here 
Line 0    Link Here 
1
/**
2
 * Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/publicdomain/zero/1.0/
4
 */
5
6
var gActiveListeners = {};
7
8
function registerPopupEventHandler(eventName, callback)
9
{
10
  gActiveListeners[eventName] = function (event) {
11
    if (event.target != PopupNotifications.panel)
12
      return;
13
    PopupNotifications.panel.removeEventListener(eventName,
14
                                                 gActiveListeners[eventName]);
15
    delete gActiveListeners[eventName];
16
17
    callback.call(PopupNotifications.panel);
18
  }
19
  PopupNotifications.panel.addEventListener(eventName,
20
                                            gActiveListeners[eventName]);
21
}
22
23
function unregisterPopupEventHandler(eventName)
24
{
25
  PopupNotifications.panel.removeEventListener(eventName,
26
                                               gActiveListeners[eventName]);
27
  delete gActiveListeners[eventName];
28
}
29
30
function unregisterAllPopupEventHandlers()
31
{
32
  for (let eventName in gActiveListeners) {
33
    PopupNotifications.panel.removeEventListener(eventName,
34
                                                 gActiveListeners[eventName]);
35
  }
36
  gActiveListeners = {};
37
}
38
39
function triggerMainCommand(popup)
40
{
41
  info("triggering main command");
42
  let notifications = popup.childNodes;
43
  ok(notifications.length > 0, "at least one notification displayed");
44
  let notification = notifications[0];
45
  info("triggering command: " + notification.getAttribute("buttonlabel"));
46
47
  EventUtils.synthesizeMouseAtCenter(notification.button, {});
48
}
49
50
function triggerSecondaryCommand(popup)
51
{
52
  info("triggering secondary command");
53
  let notifications = popup.childNodes;
54
  ok(notifications.length > 0, "at least one notification displayed");
55
  let notification = notifications[0];
56
  EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
57
}
58
59
function dismissNotification(popup)
60
{
61
  info("dismissing notification");
62
  executeSoon(function () {
63
    EventUtils.synthesizeKey("VK_ESCAPE", {});
64
  });
65
}
66
67
function setPermission(url, permission)
68
{
69
  const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
70
71
  let uri = Components.classes["@mozilla.org/network/io-service;1"]
72
                      .getService(Components.interfaces.nsIIOService)
73
                      .newURI(url);
74
  let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
75
                      .getService(Ci.nsIScriptSecurityManager);
76
  let principal = ssm.createCodebasePrincipal(uri, {});
77
78
  Components.classes["@mozilla.org/permissionmanager;1"]
79
            .getService(nsIPermissionManager)
80
            .addFromPrincipal(principal, permission,
81
                              nsIPermissionManager.ALLOW_ACTION);
82
}
83
84
function removePermission(url, permission)
85
{
86
  let uri = Components.classes["@mozilla.org/network/io-service;1"]
87
                      .getService(Components.interfaces.nsIIOService)
88
                      .newURI(url);
89
  let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
90
                      .getService(Ci.nsIScriptSecurityManager);
91
  let principal = ssm.createCodebasePrincipal(uri, {});
92
93
  Components.classes["@mozilla.org/permissionmanager;1"]
94
            .getService(Components.interfaces.nsIPermissionManager)
95
            .removeFromPrincipal(principal, permission);
96
}
97
98
function getPermission(url, permission)
99
{
100
  let uri = Components.classes["@mozilla.org/network/io-service;1"]
101
                      .getService(Components.interfaces.nsIIOService)
102
                      .newURI(url);
103
  let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
104
                      .getService(Ci.nsIScriptSecurityManager);
105
  let principal = ssm.createCodebasePrincipal(uri, {});
106
107
  return Components.classes["@mozilla.org/permissionmanager;1"]
108
                   .getService(Components.interfaces.nsIPermissionManager)
109
                   .testPermissionFromPrincipal(principal, permission);
110
}
111
112
function promiseMessage(aMessage, browser)
113
{
114
  return ContentTask.spawn(browser.selectedBrowser, aMessage, function* (aMessage) {
115
    yield new Promise((resolve, reject) => {
116
      content.addEventListener("message", function messageListener(event) {
117
        content.removeEventListener("message", messageListener);
118
        is(event.data, aMessage, "received " + aMessage);
119
        if (event.data == aMessage)
120
          resolve();
121
        else
122
          reject();
123
      });
124
    });
125
  });
126
}
(-)a/dom/quota/test/helpers.js (+424 lines)
Line     Link Here 
Line 0    Link Here 
1
/**
2
 * Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/publicdomain/zero/1.0/
4
 */
5
6
var testGenerator = testSteps();
7
8
function executeSoon(aFun)
9
{
10
  let comp = SpecialPowers.wrap(Components);
11
12
  let thread = comp.classes["@mozilla.org/thread-manager;1"]
13
                   .getService(comp.interfaces.nsIThreadManager)
14
                   .mainThread;
15
16
  thread.dispatch({
17
    run: function() {
18
      aFun();
19
    }
20
  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
21
}
22
23
function clearAllDatabases(callback)
24
{
25
  let qms = SpecialPowers.Services.qms;
26
  let principal = SpecialPowers.wrap(document).nodePrincipal;
27
  let request = qms.clearStoragesForPrincipal(principal);
28
  let cb = SpecialPowers.wrapCallback(callback);
29
  request.callback = cb;
30
}
31
32
var testHarnessGenerator = testHarnessSteps();
33
testHarnessGenerator.next();
34
35
function testHarnessSteps()
36
{
37
  function nextTestHarnessStep(val)
38
  {
39
    testHarnessGenerator.next(val);
40
  }
41
42
  let testScriptPath;
43
  let testScriptFilename;
44
45
  let scripts = document.getElementsByTagName("script");
46
  for (let i = 0; i < scripts.length; i++) {
47
    let src = scripts[i].src;
48
    let match = src.match(/quota\/test\/(test_[^\/]+\.js)$/);
49
    if (match && match.length == 2) {
50
      testScriptPath = src;
51
      testScriptFilename = match[1];
52
      break;
53
    }
54
  }
55
56
  yield undefined;
57
58
  info("Clearing old databases");
59
60
  clearAllDatabases(nextTestHarnessStep);
61
  yield undefined;
62
63
  info("Running" +
64
       (testScriptFilename ? " '" + testScriptFilename + "'" : ""));
65
66
  if (testScriptFilename && !window.disableWorkerTest) {
67
    info("Running test in a worker");
68
69
    let workerScriptBlob =
70
      new Blob([ "(" + workerScript.toString() + ")();" ],
71
               { type: "text/javascript;version=1.7" });
72
    let workerScriptURL = URL.createObjectURL(workerScriptBlob);
73
74
    let worker = new Worker(workerScriptURL);
75
76
    worker._expectingUncaughtException = false;
77
    worker.onerror = function(event) {
78
      if (worker._expectingUncaughtException) {
79
        ok(true, "Worker had an expected error: " + event.message);
80
        worker._expectingUncaughtException = false;
81
        event.preventDefault();
82
        return;
83
      }
84
      ok(false, "Worker had an error: " + event.message);
85
      worker.terminate();
86
      nextTestHarnessStep();
87
    };
88
89
    worker.onmessage = function(event) {
90
      let message = event.data;
91
      switch (message.op) {
92
        case "ok":
93
          ok(message.condition, message.name, message.diag);
94
          break;
95
96
        case "todo":
97
          todo(message.condition, message.name, message.diag);
98
          break;
99
100
        case "info":
101
          info(message.msg);
102
          break;
103
104
        case "ready":
105
          worker.postMessage({ op: "load", files: [ testScriptPath ] });
106
          break;
107
108
        case "loaded":
109
          worker.postMessage({ op: "start" });
110
          break;
111
112
        case "done":
113
          ok(true, "Worker finished");
114
          nextTestHarnessStep();
115
          break;
116
117
        case "expectUncaughtException":
118
          worker._expectingUncaughtException = message.expecting;
119
          break;
120
121
	case "clearAllDatabases":
122
          clearAllDatabases(function(){
123
            worker.postMessage({ op: "clearAllDatabasesDone" });
124
          });
125
          break;
126
127
        default:
128
          ok(false,
129
             "Received a bad message from worker: " + JSON.stringify(message));
130
          nextTestHarnessStep();
131
      }
132
    };
133
134
    URL.revokeObjectURL(workerScriptURL);
135
136
    yield undefined;
137
138
    if (worker._expectingUncaughtException) {
139
      ok(false, "expectUncaughtException was called but no uncaught " +
140
                "exception was detected!");
141
    }
142
143
    worker.terminate();
144
    worker = null;
145
146
    clearAllDatabases(nextTestHarnessStep);
147
    yield undefined;
148
  } else if (testScriptFilename) {
149
    todo(false,
150
         "Skipping test in a worker because it is explicitly disabled: " +
151
         disableWorkerTest);
152
  } else {
153
    todo(false,
154
         "Skipping test in a worker because it's not structured properly");
155
  }
156
157
  info("Running test in main thread");
158
159
  // Now run the test script in the main thread.
160
  testGenerator.next();
161
162
  yield undefined;
163
}
164
165
if (!window.runTest) {
166
  window.runTest = function()
167
  {
168
    SimpleTest.waitForExplicitFinish();
169
    testHarnessGenerator.next();
170
  }
171
}
172
173
function finishTest()
174
{
175
  SpecialPowers.notifyObserversInParentProcess(null,
176
                                               "disk-space-watcher",
177
                                               "free");
178
179
  SimpleTest.executeSoon(function() {
180
    clearAllDatabases(function() { SimpleTest.finish(); });
181
  });
182
}
183
184
function continueToNextStep()
185
{
186
  SimpleTest.executeSoon(function() {
187
    testGenerator.next();
188
  });
189
}
190
191
function continueToNextStepSync()
192
{
193
  testGenerator.next();
194
}
195
196
function errorHandler(event)
197
{
198
  ok(false, "error, '" + event.target.error.name + "'");
199
  finishTest();
200
}
201
202
function expectUncaughtException(expecting)
203
{
204
  SimpleTest.expectUncaughtException(expecting);
205
}
206
207
function unexpectedSuccessHandler()
208
{
209
  ok(false, "Got success, but did not expect it!");
210
  finishTest();
211
}
212
213
function expectedErrorHandler(name)
214
{
215
  return function(event) {
216
    is(event.type, "error", "Got an error event");
217
    is(event.target.error.name, name, "Expected error was thrown.");
218
    event.preventDefault();
219
    grabEventAndContinueHandler(event);
220
  };
221
}
222
223
function ExpectError(name, preventDefault)
224
{
225
  this._name = name;
226
  this._preventDefault = preventDefault;
227
}
228
229
ExpectError.prototype = {
230
  handleEvent: function(event)
231
  {
232
    is(event.type, "error", "Got an error event");
233
    is(event.target.error.name, this._name, "Expected error was thrown.");
234
    if (this._preventDefault) {
235
      event.preventDefault();
236
      event.stopPropagation();
237
    }
238
    grabEventAndContinueHandler(event);
239
  }
240
};
241
242
function workerScript()
243
{
244
  "use strict";
245
246
  self.repr = function(_thing_) {
247
    if (typeof(_thing_) == "undefined") {
248
      return "undefined";
249
    }
250
251
    let str;
252
253
    try {
254
      str = _thing_ + "";
255
    } catch (e) {
256
      return "[" + typeof(_thing_) + "]";
257
    }
258
259
    if (typeof(_thing_) == "function") {
260
      str = str.replace(/^\s+/, "");
261
      let idx = str.indexOf("{");
262
      if (idx != -1) {
263
        str = str.substr(0, idx) + "{...}";
264
      }
265
    }
266
267
    return str;
268
  };
269
270
  self.ok = function(_condition_, _name_, _diag_) {
271
    self.postMessage({ op: "ok",
272
                       condition: !!_condition_,
273
                       name: _name_,
274
                       diag: _diag_ });
275
  };
276
277
  self.is = function(_a_, _b_, _name_) {
278
    let pass = (_a_ == _b_);
279
    let diag = pass ? "" : "got " + repr(_a_) + ", expected " + repr(_b_);
280
    ok(pass, _name_, diag);
281
  };
282
283
  self.isnot = function(_a_, _b_, _name_) {
284
    let pass = (_a_ != _b_);
285
    let diag = pass ? "" : "didn't expect " + repr(_a_) + ", but got it";
286
    ok(pass, _name_, diag);
287
  };
288
289
  self.todo = function(_condition_, _name_, _diag_) {
290
    self.postMessage({ op: "todo",
291
                       condition: !!_condition_,
292
                       name: _name_,
293
                       diag: _diag_ });
294
  };
295
296
  self.info = function(_msg_) {
297
    self.postMessage({ op: "info", msg: _msg_ });
298
  };
299
300
  self.executeSoon = function(_fun_) {
301
    var channel = new MessageChannel();
302
    channel.port1.postMessage("");
303
    channel.port2.onmessage = function(event) { _fun_(); };
304
  };
305
306
  self.finishTest = function() {
307
    if (self._expectingUncaughtException) {
308
      self.ok(false, "expectUncaughtException was called but no uncaught "
309
                     + "exception was detected!");
310
    }
311
    self.postMessage({ op: "done" });
312
  };
313
314
  self.grabEventAndContinueHandler = function(_event_) {
315
    testGenerator.next(_event_);
316
  };
317
318
  self.continueToNextStep = function() {
319
    executeSoon(function() {
320
      testGenerator.next();
321
    });
322
  };
323
324
  self.continueToNextStepSync = function() {
325
    testGenerator.next();
326
  };
327
328
  self.errorHandler = function(_event_) {
329
    ok(false, "error, '" + _event_.target.error.name + "'");
330
    finishTest();
331
  };
332
333
  self.unexpectedSuccessHandler = function()
334
  {
335
    ok(false, "Got success, but did not expect it!");
336
    finishTest();
337
  };
338
339
  self.expectedErrorHandler = function(_name_)
340
  {
341
    return function(_event_) {
342
      is(_event_.type, "error", "Got an error event");
343
      is(_event_.target.error.name, _name_, "Expected error was thrown.");
344
      _event_.preventDefault();
345
      grabEventAndContinueHandler(_event_);
346
    };
347
  };
348
349
  self.ExpectError = function(_name_, _preventDefault_)
350
  {
351
    this._name = _name_;
352
    this._preventDefault = _preventDefault_;
353
  }
354
  self.ExpectError.prototype = {
355
    handleEvent: function(_event_)
356
    {
357
      is(_event_.type, "error", "Got an error event");
358
      is(_event_.target.error.name, this._name, "Expected error was thrown.");
359
      if (this._preventDefault) {
360
        _event_.preventDefault();
361
        _event_.stopPropagation();
362
      }
363
      grabEventAndContinueHandler(_event_);
364
    }
365
  };
366
367
  self._expectingUncaughtException = false;
368
  self.expectUncaughtException = function(_expecting_) {
369
    self._expectingUncaughtException = !!_expecting_;
370
    self.postMessage({ op: "expectUncaughtException", expecting: !!_expecting_ });
371
  };
372
373
  self._clearAllDatabasesCallback = undefined;
374
  self.clearAllDatabases = function(_callback_) {
375
    self._clearAllDatabasesCallback = _callback_;
376
    self.postMessage({ op: "clearAllDatabases" });
377
  }
378
379
  self.onerror = function(_message_, _file_, _line_) {
380
    if (self._expectingUncaughtException) {
381
      self._expectingUncaughtException = false;
382
      ok(true, "Worker: expected exception [" + _file_ + ":" + _line_ + "]: '" +
383
         _message_ + "'");
384
      return;
385
    }
386
    ok(false,
387
       "Worker: uncaught exception [" + _file_ + ":" + _line_ + "]: '" +
388
         _message_ + "'");
389
    self.finishTest();
390
    self.close();
391
    return true;
392
  };
393
394
  self.onmessage = function(_event_) {
395
    let message = _event_.data;
396
    switch (message.op) {
397
      case "load":
398
        info("Worker: loading " + JSON.stringify(message.files));
399
        self.importScripts(message.files);
400
        self.postMessage({ op: "loaded" });
401
        break;
402
403
      case "start":
404
        executeSoon(function() {
405
          info("Worker: starting tests");
406
          testGenerator.next();
407
        });
408
        break;
409
410
      case "clearAllDatabasesDone":
411
        info("Worker: all databases are cleared");
412
        if (self._clearAllDatabasesCallback) {
413
          self._clearAllDatabasesCallback();
414
        }
415
        break;
416
417
      default:
418
        throw new Error("Received a bad message from parent: " +
419
                        JSON.stringify(message));
420
    }
421
  };
422
423
  self.postMessage({ op: "ready" });
424
}
(-)a/dom/quota/test/mochitest.ini (+14 lines)
Line     Link Here 
Line 0    Link Here 
1
# This Source Code Form is subject to the terms of the Mozilla Public
2
# License, v. 2.0. If a copy of the MPL was not distributed with this
3
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5
[DEFAULT]
6
support-files =
7
  helpers.js
8
  test_storage_manager_persist_allow.js
9
  test_storage_manager_persist_deny.js
10
11
[test_storage_manager_persist_allow.html]
12
scheme=https
13
[test_storage_manager_persist_deny.html]
14
scheme=https
(-)a/dom/quota/test/test_storage_manager_persist_allow.html (+19 lines)
Line     Link Here 
Line 0    Link Here 
1
<!--
2
  Any copyright is dedicated to the Public Domain.
3
  http://creativecommons.org/publicdomain/zero/1.0/
4
-->
5
<html>
6
<head>
7
  <title>Allow Persist Prompt for StorageManager</title>
8
9
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
11
12
  <script type="text/javascript;version=1.7" src="test_storage_manager_persist_allow.js"></script>
13
  <script type="text/javascript;version=1.7" src="helpers.js"></script>
14
15
</head>
16
17
<body onload="runTest();"></body>
18
19
</html>
(-)a/dom/quota/test/test_storage_manager_persist_allow.js (+28 lines)
Line     Link Here 
Line 0    Link Here 
1
var disableWorkerTest = "Persist doesn't work in workers";
2
var testGenerator = testSteps();
3
4
function* testSteps()
5
{
6
  SpecialPowers.pushPrefEnv({
7
    "set": [["dom.storageManager.enabled", true],
8
            ["dom.storageManager.prompt.testing", true],
9
            ["dom.storageManager.prompt.testing.allow", true]]
10
  }, continueToNextStep);
11
  yield undefined;
12
13
  navigator.storage.persist().then(result => {
14
    testGenerator.next(result);
15
  });
16
  let persistResult  = yield undefined;
17
18
  is(persistResult, true, "Persist successfully");
19
20
  navigator.storage.persisted().then(result => {
21
    testGenerator.next(result);
22
  });
23
  let persistedResult  = yield undefined;
24
25
  is(persistResult, persistedResult, "Persist/persisted results are consistent");
26
27
  finishTest();
28
}
(-)a/dom/quota/test/test_storage_manager_persist_deny.html (+19 lines)
Line     Link Here 
Line 0    Link Here 
1
<!--
2
  Any copyright is dedicated to the Public Domain.
3
  http://creativecommons.org/publicdomain/zero/1.0/
4
-->
5
<html>
6
<head>
7
  <title>Deny Persist Prompt for StorageManager</title>
8
9
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
11
12
  <script type="text/javascript;version=1.7" src="test_storage_manager_persist_deny.js"></script>
13
  <script type="text/javascript;version=1.7" src="helpers.js"></script>
14
15
</head>
16
17
<body onload="runTest();"></body>
18
19
</html>
(-)a/dom/quota/test/test_storage_manager_persist_deny.js (+28 lines)
Line     Link Here 
Line 0    Link Here 
1
var disableWorkerTest = "Persist doesn't work in workers";
2
var testGenerator = testSteps();
3
4
function* testSteps()
5
{
6
  SpecialPowers.pushPrefEnv({
7
    "set": [["dom.storageManager.enabled", true],
8
            ["dom.storageManager.prompt.testing", true],
9
            ["dom.storageManager.prompt.testing.allow", false]]
10
  }, continueToNextStep);
11
  yield undefined;
12
13
  navigator.storage.persist().then(result => {
14
    testGenerator.next(result);
15
  });
16
  let persistResult  = yield undefined;
17
18
  is(persistResult, false, "Cancel the persist prompt and resolve a promise with false");
19
20
  navigator.storage.persisted().then(result => {
21
    testGenerator.next(result);
22
  });
23
  let persistedResult  = yield undefined;
24
25
  is(persistResult, persistedResult, "Persist/persisted results are consistent");
26
27
  finishTest();
28
}
(-)a/modules/libpref/init/all.js (+3 lines)
Line     Link Here 
 Lines 5612-5627   pref ("security.data_uri.inherit_securit Link Here 
5612
5612
5613
// Disable Storage api in release builds.
5613
// Disable Storage api in release builds.
5614
#if defined(NIGHTLY_BUILD) && !defined(MOZ_WIDGET_ANDROID)
5614
#if defined(NIGHTLY_BUILD) && !defined(MOZ_WIDGET_ANDROID)
5615
pref("dom.storageManager.enabled", true);
5615
pref("dom.storageManager.enabled", true);
5616
#else
5616
#else
5617
pref("dom.storageManager.enabled", false);
5617
pref("dom.storageManager.enabled", false);
5618
#endif
5618
#endif
5619
5619
5620
pref("dom.storageManager.prompt.testing", false);
5621
pref("dom.storageManager.prompt.testing.allow", false);
5622
5620
// When a user cancels this number of authentication dialogs coming from
5623
// When a user cancels this number of authentication dialogs coming from
5621
// a single web page in a row, all following authentication dialogs will
5624
// a single web page in a row, all following authentication dialogs will
5622
// be blocked (automatically canceled) for that page. The counter resets
5625
// be blocked (automatically canceled) for that page. The counter resets
5623
// when the page is reloaded. To turn this feature off, just set the limit to 0.
5626
// when the page is reloaded. To turn this feature off, just set the limit to 0.
5624
pref("prompts.authentication_dialog_abuse_limit", 3);
5627
pref("prompts.authentication_dialog_abuse_limit", 3);
5625
5628
5626
// Enable the Storage management in about:preferences and persistent-storage permission request
5629
// Enable the Storage management in about:preferences and persistent-storage permission request
5627
// To enable the DOM implementation, turn on "dom.storageManager.enabled"
5630
// To enable the DOM implementation, turn on "dom.storageManager.enabled"

Return to bug 1286717