Bug 1223573 - Part 6. Tidy up bootstrap.js add enough setup to get xpcshell-tests passing again. r=mikedeboer
authorMark Banner <standard8@mozilla.com>
Sun, 29 Nov 2015 17:08:35 +0000
changeset 274490 117061bb2218b158627a4182742c0cb0598edd3e
parent 274489 e19308d96a1dc85718eef8999ad86b7e35223d5c
child 274491 722d3a01dcfcb37f57e9e2a299bef5c0c1a528c9
push id16444
push usermbanner@mozilla.com
push dateSun, 29 Nov 2015 17:10:04 +0000
treeherderfx-team@29ce9059dc2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1223573
milestone45.0a1
Bug 1223573 - Part 6. Tidy up bootstrap.js add enough setup to get xpcshell-tests passing again. r=mikedeboer
browser/extensions/loop/bootstrap.js
browser/extensions/loop/test/xpcshell/head.js
--- a/browser/extensions/loop/bootstrap.js
+++ b/browser/extensions/loop/bootstrap.js
@@ -1,14 +1,23 @@
 /* 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";
+
+const { utils: Cu, classes: Cc } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
 
 var WindowListener = {
-
+  /**
+   * Sets up the chrome integration within browser windows for Loop.
+   *
+   * @param {Object} window The window to inject the integration into.
+   */
   setupBrowserUI: function(window) {
     const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     const kBrowserSharingNotificationId = "loop-sharing-notification";
     const kPrefBrowserSharingInfoBar = "browserSharing.showInfoBar";
 
     let document = window.document;
     let gBrowser = window.gBrowser;
     let xhrClass = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"];
@@ -17,25 +26,25 @@ var WindowListener = {
     // the "exported" symbols
     var LoopUI = {
       /**
        * @var {XULWidgetSingleWrapper} toolbarButton Getter for the Loop toolbarbutton
        *                                             instance for this window.
        */
       get toolbarButton() {
         delete this.toolbarButton;
-        return this.toolbarButton = CustomizableUI.getWidget("loop-button").forWindow(window);
+        return (this.toolbarButton = CustomizableUI.getWidget("loop-button").forWindow(window));
       },
 
       /**
        * @var {XULElement} panel Getter for the Loop panel element.
        */
       get panel() {
         delete this.panel;
-        return this.panel = document.getElementById("loop-notification-panel");
+        return (this.panel = document.getElementById("loop-notification-panel"));
       },
 
       /**
        * @var {XULElement|null} browser Getter for the Loop panel browser element.
        *                                Will be NULL if the panel hasn't loaded yet.
        */
       get browser() {
         let browser = document.querySelector("#loop-notification-panel > #loop-panel-iframe");
@@ -88,30 +97,30 @@ var WindowListener = {
       togglePanel: function(event, tabId = null) {
         if (!this.panel) {
           // We're on the hidden window! What fun!
           let obs = win => {
             Services.obs.removeObserver(obs, "browser-delayed-startup-finished");
             win.LoopUI.togglePanel(event, tabId);
           };
           Services.obs.addObserver(obs, "browser-delayed-startup-finished", false);
-          return OpenBrowserWindow();
+          return window.OpenBrowserWindow();
         }
         if (this.panel.state == "open") {
           return new Promise(resolve => {
             this.panel.hidePopup();
             resolve();
           });
         }
 
         return this.openCallPanel(event, tabId).then(doc => {
           let fm = Services.focus;
           fm.moveFocus(doc.defaultView, null, fm.MOVEFOCUS_FIRST, fm.FLAG_NOSCROLL);
         }).catch(err => {
-          Cu.reportError(x);
+          Cu.reportError(err);
         });
       },
 
       /**
        * Opens the panel for Loop and sizes it appropriately.
        *
        * @param {event}  event   The event opening the panel, used to anchor
        *                         the panel to the button which triggers it.
@@ -378,17 +387,19 @@ var WindowListener = {
         let notification = new window.Notification(options.title, notificationOptions);
         notification.addEventListener("click", e => {
           if (window.closed) {
             return;
           }
 
           try {
             window.focus();
-          } catch (ex) {}
+          } catch (ex) {
+            // Do nothing.
+          }
 
           // We need a setTimeout here, otherwise the panel won't show after the
           // window received focus.
           window.setTimeout(() => {
             if (typeof options.onclick == "function") {
               options.onclick();
             } else {
               // Open the Loop panel as a default action.
@@ -611,9 +622,37 @@ var WindowListener = {
 
     XPCOMUtils.defineLazyModuleGetter(LoopUI, "hookWindowCloseForPanelClose", "resource://gre/modules/MozSocialAPI.jsm");
     XPCOMUtils.defineLazyModuleGetter(LoopUI, "LoopAPI", "chrome://loop/content/modules/MozLoopAPI.jsm");
     XPCOMUtils.defineLazyModuleGetter(LoopUI, "LoopRooms", "chrome://loop/content/modules/LoopRooms.jsm");
     XPCOMUtils.defineLazyModuleGetter(LoopUI, "MozLoopService", "chrome://loop/content/modules/MozLoopService.jsm");
     XPCOMUtils.defineLazyModuleGetter(LoopUI, "PanelFrame", "resource:///modules/PanelFrame.jsm");
     XPCOMUtils.defineLazyModuleGetter(LoopUI, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
   }
+};
+
+/**
+ * Loads the default preferences from the prefs file. This loads the preferences
+ * into the default branch, so they don't appear as user preferences.
+ */
+function loadDefaultPrefs() {
+  var branch = Services.prefs.getDefaultBranch("");
+  Services.scriptloader.loadSubScript("chrome://loop/content/preferences/prefs.js", {
+    pref: (key, val) => {
+      switch (typeof val) {
+        case "boolean":
+          branch.setBoolPref(key, val);
+          break;
+        case "number":
+          branch.setIntPref(key, val);
+          break;
+        case "string":
+          branch.setCharPref(key, val);
+         break;
+      }
+    }
+  });
 }
+
+
+function startup(data, reason) {
+  loadDefaultPrefs();
+}
--- a/browser/extensions/loop/test/xpcshell/head.js
+++ b/browser/extensions/loop/test/xpcshell/head.js
@@ -5,16 +5,53 @@
 
 var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 // Initialize this before the imports, as some of them need it.
 do_get_profile();
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+
+// Setup the add-ons manager for this test.
+Cu.import("resource://gre/modules/FileUtils.jsm");
+
+function registerDirectory(key, dir) {
+  let dirProvider = {
+    getFile: function(prop, persistent) {
+      persistent.value = false;
+      if (prop == key) {
+        return dir.clone();
+      }
+      return null;
+    },
+
+    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider,
+                                           Ci.nsISupports])
+  };
+  Services.dirsvc.registerProvider(dirProvider);
+}
+
+// As we're not running in application, we need to setup the features directory
+// manually.
+const distroDir = FileUtils.getDir("GreD", ["browser", "features"], true);
+registerDirectory("XREAppFeat", distroDir);
+
+// Set up application info - xpcshell doesn't have this by default.
+Cu.import("resource://testing-common/AppInfo.jsm");
+updateAppInfo();
+
+// Now trigger the addons-startup, and hence startup the manager itself. This
+// should load the manager correctly.
+var gInternalManager = Cc["@mozilla.org/addons/integration;1"]
+  .getService(Ci.nsIObserver)
+  .QueryInterface(Ci.nsITimerCallback);
+
+gInternalManager.observe(null, "addons-startup", null);
+
 Cu.import("resource://gre/modules/Http.jsm");
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("chrome://loop/content/modules/MozLoopService.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("chrome://loop/content/modules/LoopRooms.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 const { MozLoopServiceInternal } = Cu.import("chrome://loop/content/modules/MozLoopService.jsm", {});
 const { LoopRoomsInternal, timerHandlers } = Cu.import("chrome://loop/content/modules/LoopRooms.jsm", {});