Bug 1162920 - JavaScript error at aboutServiceWorkers.js when updating the service worker. r=fabrice
authorFernando Jimenez <ferjmoreno@gmail.com>
Wed, 13 May 2015 07:46:01 +0200
changeset 243651 8e7689f926e955b81fac5d59d3b648229295dafc
parent 243650 d6d25651b082b10c8bffea72e4fe5136e04c7da1
child 243652 7da7fb5c7d383f9577d534e10d202a13a44fac0e
push id28744
push userkwierso@gmail.com
push dateWed, 13 May 2015 18:12:16 +0000
treeherdermozilla-central@324c3423deaf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs1162920
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1162920 - JavaScript error at aboutServiceWorkers.js when updating the service worker. r=fabrice
b2g/components/AboutServiceWorkers.jsm
b2g/components/test/unit/test_aboutserviceworkers.js
b2g/components/test/unit/xpcshell.ini
--- a/b2g/components/AboutServiceWorkers.jsm
+++ b/b2g/components/AboutServiceWorkers.jsm
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict"
 
-this.EXPORTED_SYMBOLS = [];
+this.EXPORTED_SYMBOLS = ["AboutServiceWorkers"];
 
 const { interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
@@ -42,126 +42,129 @@ function serializeServiceWorkerInfo(aSer
       return;
     }
     result[property] = aServiceWorkerInfo[property];
   });
 
   return result;
 }
 
-function sendResult(aId, aResult) {
-  SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
-    id: aId,
-    result: aResult
-  });
-}
-
-function sendError(aId, aError) {
-  SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
-    id: aId,
-    error: aError
-  });
-}
 
 this.AboutServiceWorkers = {
   get enabled() {
     if (this._enabled) {
       return this._enabled;
     }
     this._enabled = false;
     try {
       this._enabled = Services.prefs.getBoolPref("dom.serviceWorkers.enabled");
     } catch(e) {}
     return this._enabled;
   },
 
   init: function() {
     SystemAppProxy.addEventListener("mozAboutServiceWorkersContentEvent",
-                                   AboutServiceWorkers);
+                                    AboutServiceWorkers);
+  },
+
+  sendResult: function(aId, aResult) {
+    SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
+      id: aId,
+      result: aResult
+    });
+  },
+
+  sendError: function(aId, aError) {
+    SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
+      id: aId,
+      error: aError
+    });
   },
 
   handleEvent: function(aEvent) {
     let message = aEvent.detail;
 
     debug("Got content event " + JSON.stringify(message));
 
     if (!message.id || !message.name) {
       dump("Invalid event " + JSON.stringify(message) + "\n");
       return;
     }
 
+    let self = AboutServiceWorkers;
+
     switch(message.name) {
       case "init":
-        if (!this.enabled) {
-          sendResult({
+        if (!self.enabled) {
+          self.sendResult(message.id, {
             enabled: false,
             registrations: []
           });
           return;
         };
 
         let data = gServiceWorkerManager.getAllRegistrations();
         if (!data) {
-          sendError(message.id, "NoServiceWorkersRegistrations");
+          self.sendError(message.id, "NoServiceWorkersRegistrations");
           return;
         }
 
         let registrations = [];
 
         for (let i = 0; i < data.length; i++) {
           let info = data.queryElementAt(i, Ci.nsIServiceWorkerInfo);
           if (!info) {
             dump("AboutServiceWorkers: Invalid nsIServiceWorkerInfo " +
                  "interface.\n");
             continue;
           }
           registrations.push(serializeServiceWorkerInfo(info));
         }
 
-        sendResult(message.id, {
-          enabled: this.enabled,
+        self.sendResult(message.id, {
+          enabled: self.enabled,
           registrations: registrations
         });
         break;
 
       case "update":
         if (!message.scope) {
-          sendError(message.id, "MissingScope");
+          self.sendError(message.id, "MissingScope");
           return;
         }
-        gServiceWorkerManager.update(message.scope);
-        sendResult(message.id, true);
+        gServiceWorkerManager.softUpdate(message.scope);
+        self.sendResult(message.id, true);
         break;
 
       case "unregister":
         if (!message.principal ||
             !message.principal.origin ||
             !message.principal.appId) {
-          sendError("MissingPrincipal");
+          self.sendError("MissingPrincipal");
           return;
         }
 
         let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
           Services.io.newURI(message.principal.origin, null, null),
           message.principal.appId,
           message.principal.isInBrowser
         );
 
         if (!message.scope) {
-          sendError("MissingScope");
+          self.sendError("MissingScope");
           return;
         }
 
         let serviceWorkerUnregisterCallback = {
           unregisterSucceeded: function() {
-            sendResult(message.id, true);
+            self.sendResult(message.id, true);
           },
 
           unregisterFailed: function() {
-            sendError(message.id, "UnregisterError");
+            self.sendError(message.id, "UnregisterError");
           },
 
           QueryInterface: XPCOMUtils.generateQI([
             Ci.nsIServiceWorkerUnregisterCallback
           ])
         };
         gServiceWorkerManager.unregister(principal,
                                          serviceWorkerUnregisterCallback,
new file mode 100644
--- /dev/null
+++ b/b2g/components/test/unit/test_aboutserviceworkers.js
@@ -0,0 +1,139 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const {utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "AboutServiceWorkers",
+  "resource://gre/modules/AboutServiceWorkers.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
+                                   "@mozilla.org/serviceworkers/manager;1",
+                                   "nsIServiceWorkerManager");
+
+const CHROME_MSG = "mozAboutServiceWorkersChromeEvent";
+
+const ORIGINAL_SENDRESULT = AboutServiceWorkers.sendResult;
+const ORIGINAL_SENDERROR = AboutServiceWorkers.sendError;
+
+do_get_profile();
+
+let mockSendResult = (aId, aResult) => {
+  let msg = {
+    id: aId,
+    result: aResult
+  };
+  Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null);
+};
+
+let mockSendError = (aId, aError) => {
+  let msg = {
+    id: aId,
+    result: aError
+  };
+  Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null);
+};
+
+function attachMocks() {
+  AboutServiceWorkers.sendResult = mockSendResult;
+  AboutServiceWorkers.sendError = mockSendError;
+}
+
+function restoreMocks() {
+  AboutServiceWorkers.sendResult = ORIGINAL_SENDRESULT;
+  AboutServiceWorkers.sendError = ORIGINAL_SENDERROR;
+}
+
+do_register_cleanup(restoreMocks);
+
+function run_test() {
+  run_next_test();
+}
+
+/**
+ * "init" tests
+ */
+[
+// Pref disabled, no registrations
+{
+  prefEnabled: false,
+  expectedMessage: {
+    id: Date.now(),
+    result: {
+      enabled: false,
+      registrations: []
+    }
+  }
+},
+// Pref enabled, no registrations
+{
+  prefEnabled: true,
+  expectedMessage: {
+    id: Date.now(),
+    result: {
+      enabled: true,
+      registrations: []
+    }
+  }
+}].forEach(test => {
+  add_test(function() {
+    Services.prefs.setBoolPref("dom.serviceWorkers.enabled", test.prefEnabled);
+
+    let id = test.expectedMessage.id;
+
+    function onMessage(subject, topic, data) {
+      let message = subject.wrappedJSObject;
+      let expected = test.expectedMessage;
+
+      do_check_true(message.id, "Message should have id");
+      do_check_eq(message.id, test.expectedMessage.id,
+                  "Id should be the expected one");
+      do_check_eq(message.result.enabled, expected.result.enabled,
+                  "Pref should be disabled");
+      do_check_true(message.result.registrations, "Registrations should exist");
+      do_check_eq(message.result.registrations.length,
+                  expected.result.registrations.length,
+                  "Registrations length should be the expected one");
+
+      Services.obs.removeObserver(onMessage, CHROME_MSG);
+
+      run_next_test();
+    }
+
+    Services.obs.addObserver(onMessage, CHROME_MSG, false);
+
+    attachMocks();
+
+    AboutServiceWorkers.handleEvent({ detail: {
+      id: id,
+      name: "init"
+    }});
+  });
+});
+
+/**
+ * ServiceWorkerManager tests.
+ */
+
+// We cannot register a sw via ServiceWorkerManager cause chrome
+// registrations are not allowed.
+// All we can do for now is to test the interface of the swm.
+add_test(function test_swm() {
+  do_check_true(gServiceWorkerManager, "SWM exists");
+  do_check_true(gServiceWorkerManager.getAllRegistrations,
+                "SWM.getAllRegistrations exists");
+  do_check_true(typeof gServiceWorkerManager.getAllRegistrations == "function",
+                "SWM.getAllRegistrations is a function");
+  do_check_true(gServiceWorkerManager.softUpdate, "SWM.softUpdate exists");
+  do_check_true(typeof gServiceWorkerManager.softUpdate == "function",
+                "SWM.softUpdate is a function");
+  do_check_true(gServiceWorkerManager.unregister, "SWM.unregister exists");
+  do_check_true(typeof gServiceWorkerManager.unregister == "function",
+                "SWM.unregister exists");
+
+  run_next_test();
+});
--- a/b2g/components/test/unit/xpcshell.ini
+++ b/b2g/components/test/unit/xpcshell.ini
@@ -23,8 +23,10 @@ skip-if = toolkit != "gonk"
 
 [test_logparser.js]
 
 [test_logshake.js]
 
 [test_logshake_gonk.js]
 # only run on b2g builds due to requiring b2g-specific log files to exist
 skip-if = (toolkit != "gonk")
+
+[test_aboutserviceworkers.js]