Bug 1342896 Don't show prompts for interactive webextension updates with no new permissions r=rhelmer
authorAndrew Swan <aswan@mozilla.com>
Fri, 03 Mar 2017 11:05:35 -0800
changeset 345919 9a3a43ae9b2d219503b561318d31f25aa4df58b8
parent 345918 7d79c8090f75d66a1c39821273d5760fdb94a23e
child 345920 4fe183d67d1b2dd854e364b89d892fc3666ca624
push id38341
push useraswan@mozilla.com
push dateSat, 04 Mar 2017 04:57:09 +0000
treeherderautoland@9a3a43ae9b2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhelmer
bugs1342896
milestone54.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 1342896 Don't show prompts for interactive webextension updates with no new permissions r=rhelmer MozReview-Commit-ID: 50SP3eL79Qm
browser/base/content/test/webextensions/browser.ini
browser/base/content/test/webextensions/browser_extension_update_interactive.js
browser/base/content/test/webextensions/browser_update_interactive.js
browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
browser/modules/ExtensionsUI.jsm
--- a/browser/base/content/test/webextensions/browser.ini
+++ b/browser/base/content/test/webextensions/browser.ini
@@ -12,13 +12,14 @@ support-files =
   browser_webext_update_icon2.xpi
   browser_webext_update_perms1.xpi
   browser_webext_update_perms2.xpi
   browser_webext_update.json
   browser_webext_search.xml
 
 [browser_extension_sideloading.js]
 [browser_extension_update_background.js]
-[browser_extension_update_interactive.js]
 [browser_permissions_addons_search.js]
 [browser_permissions_installTrigger.js]
 [browser_permissions_local_file.js]
 [browser_permissions_mozAddonManager.js]
+[browser_update_interactive.js]
+[browser_update_interactive_noprompt.js]
rename from browser/base/content/test/webextensions/browser_extension_update_interactive.js
rename to browser/base/content/test/webextensions/browser_update_interactive.js
--- a/browser/base/content/test/webextensions/browser_extension_update_interactive.js
+++ b/browser/base/content/test/webextensions/browser_update_interactive.js
@@ -1,12 +1,11 @@
 const {AddonManagerPrivate} = Cu.import("resource://gre/modules/AddonManager.jsm", {});
 
 const ID = "update2@tests.mozilla.org";
-const ID_LEGACY = "legacy_update@tests.mozilla.org";
 
 // Set some prefs that apply to all the tests in this file
 add_task(function* setup() {
   yield SpecialPowers.pushPrefEnv({set: [
     // We don't have pre-pinned certificates for the local mochitest server
     ["extensions.install.requireBuiltInCerts", false],
     ["extensions.update.requireBuiltInCerts", false],
 
@@ -129,48 +128,8 @@ add_task(() => interactiveUpdateTest(fal
 // Invoke an invidual extension's "Find Updates" menu item
 function checkOne(win, addon) {
   win.gViewController.doCommand("cmd_findItemUpdates", addon);
 }
 
 // Test "Find Updates" with both auto-update settings
 add_task(() => interactiveUpdateTest(true, checkOne));
 add_task(() => interactiveUpdateTest(false, checkOne));
-
-// Check that an update from a legacy extension to a webextensino
-// does not display a prompt
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [
-    // Point updates to the local mochitest server
-    ["extensions.update.url", `${BASE}/browser_webext_update.json`],
-  ]});
-
-  // Navigate away to ensure that BrowserOpenAddonMgr() opens a new tab
-  gBrowser.selectedBrowser.loadURI("about:robots");
-  await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-
-  // Install initial version of the test extension
-  let addon = await promiseInstallAddon(`${BASE}/browser_legacy.xpi`);
-  ok(addon, "Addon was installed");
-  is(addon.version, "1.1", "Version 1 of the addon is installed");
-
-  // Go to Extensions in about:addons
-  let win = await BrowserOpenAddonsMgr("addons://list/extension");
-
-  let sawPopup = false;
-  PopupNotifications.panel.addEventListener("popupshown",
-                                            () => sawPopup = true,
-                                            {once: true});
-
-  // Trigger an update check, we should see the update get applied
-  let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
-  win.gViewController.doCommand("cmd_findAllUpdates");
-  await updatePromise;
-
-  addon = await AddonManager.getAddonByID(ID_LEGACY);
-  is(addon.version, "2.0", "Should have upgraded");
-
-  ok(!sawPopup, "Should not have seen a permission notification");
-
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-  addon.uninstall();
-  await SpecialPowers.popPrefEnv();
-});
copy from browser/base/content/test/webextensions/browser_extension_update_interactive.js
copy to browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
--- a/browser/base/content/test/webextensions/browser_extension_update_interactive.js
+++ b/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
@@ -1,176 +1,62 @@
-const {AddonManagerPrivate} = Cu.import("resource://gre/modules/AddonManager.jsm", {});
-
-const ID = "update2@tests.mozilla.org";
-const ID_LEGACY = "legacy_update@tests.mozilla.org";
 
 // Set some prefs that apply to all the tests in this file
 add_task(function* setup() {
   yield SpecialPowers.pushPrefEnv({set: [
     // We don't have pre-pinned certificates for the local mochitest server
     ["extensions.install.requireBuiltInCerts", false],
     ["extensions.update.requireBuiltInCerts", false],
 
+    // Point updates to the local mochitest server
+    ["extensions.update.url", `${BASE}/browser_webext_update.json`],
+
     // XXX remove this when prompts are enabled by default
     ["extensions.webextPermissionPrompts", true],
   ]});
 });
 
-// Helper function to test a specific scenario for interactive updates.
-// `checkFn` is a callable that triggers a check for updates.
-// `autoUpdate` specifies whether the test should be run with
-// updates applied automatically or not.
-function* interactiveUpdateTest(autoUpdate, checkFn) {
-  yield SpecialPowers.pushPrefEnv({set: [
-    ["extensions.update.autoUpdateDefault", autoUpdate],
-
-    // Point updates to the local mochitest server
-    ["extensions.update.url", `${BASE}/browser_webext_update.json`],
-  ]});
-
-  // Trigger an update check, manually applying the update if we're testing
-  // without auto-update.
-  async function triggerUpdate(win, addon) {
-    let manualUpdatePromise;
-    if (!autoUpdate) {
-      manualUpdatePromise = new Promise(resolve => {
-        let listener = {
-          onNewInstall() {
-            AddonManager.removeInstallListener(listener);
-            resolve();
-          },
-        };
-        AddonManager.addInstallListener(listener);
-      });
-    }
-
-    let promise = checkFn(win, addon);
-
-    if (manualUpdatePromise) {
-      await manualUpdatePromise;
-
-      let list = win.document.getElementById("addon-list");
-
-      // Make sure we have XBL bindings
-      list.clientHeight;
-
-      let item = list.children.find(_item => _item.value == ID);
-      EventUtils.synthesizeMouseAtCenter(item._updateBtn, {}, win);
-    }
-
-    return {promise};
-  }
-
-  // Navigate away from the starting page to force about:addons to load
-  // in a new tab during the tests below.
-  gBrowser.selectedBrowser.loadURI("about:robots");
-  yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-
-  // Install version 1.0 of the test extension
-  let addon = yield promiseInstallAddon(`${BASE}/browser_webext_update1.xpi`);
-  ok(addon, "Addon was installed");
-  is(addon.version, "1.0", "Version 1 of the addon is installed");
-
-  let win = yield BrowserOpenAddonsMgr("addons://list/extension");
-
-  // Trigger an update check
-  let popupPromise = promisePopupNotificationShown("addon-webext-permissions");
-  let {promise: checkPromise} = yield triggerUpdate(win, addon);
-  let panel = yield popupPromise;
-
-  // Click the cancel button, wait to see the cancel event
-  let cancelPromise = promiseInstallEvent(addon, "onInstallCancelled");
-  panel.secondaryButton.click();
-  yield cancelPromise;
-
-  addon = yield AddonManager.getAddonByID(ID);
-  is(addon.version, "1.0", "Should still be running the old version");
-
-  // Make sure the update check is completely finished.
-  yield checkPromise;
-
-  // Trigger a new update check
-  popupPromise = promisePopupNotificationShown("addon-webext-permissions");
-  checkPromise = (yield triggerUpdate(win, addon)).promise;
-
-  // This time, accept the upgrade
-  let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
-  panel = yield popupPromise;
-  panel.button.click();
-
-  addon = yield updatePromise;
-  is(addon.version, "2.0", "Should have upgraded");
-
-  yield checkPromise;
-
-  yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-  addon.uninstall();
-  yield SpecialPowers.popPrefEnv();
-}
-
-// Invoke the "Check for Updates" menu item
-function checkAll(win) {
-  win.gViewController.doCommand("cmd_findAllUpdates");
-  return new Promise(resolve => {
-    let observer = {
-      observe(subject, topic, data) {
-        Services.obs.removeObserver(observer, "EM-update-check-finished");
-        resolve();
-      },
-    };
-    Services.obs.addObserver(observer, "EM-update-check-finished", false);
-  });
-}
-
-// Test "Check for Updates" with both auto-update settings
-add_task(() => interactiveUpdateTest(true, checkAll));
-add_task(() => interactiveUpdateTest(false, checkAll));
-
-
-// Invoke an invidual extension's "Find Updates" menu item
-function checkOne(win, addon) {
-  win.gViewController.doCommand("cmd_findItemUpdates", addon);
-}
-
-// Test "Find Updates" with both auto-update settings
-add_task(() => interactiveUpdateTest(true, checkOne));
-add_task(() => interactiveUpdateTest(false, checkOne));
-
-// Check that an update from a legacy extension to a webextensino
-// does not display a prompt
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [
-    // Point updates to the local mochitest server
-    ["extensions.update.url", `${BASE}/browser_webext_update.json`],
-  ]});
-
+// Helper to test that an update of a given extension does not
+// generate any permission prompts.
+async function testUpdateNoPrompt(filename, id,
+                                  initialVersion = "1.0", updateVersion = "2.0") {
   // Navigate away to ensure that BrowserOpenAddonMgr() opens a new tab
   gBrowser.selectedBrowser.loadURI("about:robots");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
   // Install initial version of the test extension
-  let addon = await promiseInstallAddon(`${BASE}/browser_legacy.xpi`);
+  let addon = await promiseInstallAddon(`${BASE}/${filename}`);
   ok(addon, "Addon was installed");
-  is(addon.version, "1.1", "Version 1 of the addon is installed");
+  is(addon.version, initialVersion, "Version 1 of the addon is installed");
 
   // Go to Extensions in about:addons
   let win = await BrowserOpenAddonsMgr("addons://list/extension");
 
   let sawPopup = false;
-  PopupNotifications.panel.addEventListener("popupshown",
-                                            () => sawPopup = true,
-                                            {once: true});
+  function popupListener() {
+    sawPopup = true;
+  }
+  PopupNotifications.panel.addEventListener("popupshown", popupListener);
 
   // Trigger an update check, we should see the update get applied
   let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
   win.gViewController.doCommand("cmd_findAllUpdates");
   await updatePromise;
 
-  addon = await AddonManager.getAddonByID(ID_LEGACY);
-  is(addon.version, "2.0", "Should have upgraded");
+  addon = await AddonManager.getAddonByID(id);
+  is(addon.version, updateVersion, "Should have upgraded");
 
   ok(!sawPopup, "Should not have seen a permission notification");
+  PopupNotifications.panel.removeEventListener("popupshown", popupListener);
 
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
   addon.uninstall();
-  await SpecialPowers.popPrefEnv();
-});
+}
+
+// Test that we don't see a prompt when updating from a legacy
+// extension to a webextension.
+add_task(() => testUpdateNoPrompt("browser_legacy.xpi",
+                                  "legacy_update@tests.mozilla.org", "1.1"));
+
+// Test that we don't see a prompt when no new promptable permissions
+// are added.
+add_task(() => testUpdateNoPrompt("browser_webext_update_perms1.xpi",
+                                  "update_perms@tests.mozilla.org"));
--- a/browser/modules/ExtensionsUI.jsm
+++ b/browser/modules/ExtensionsUI.jsm
@@ -136,16 +136,22 @@ this.ExtensionsUI = {
       // there are multiple simultaneous installs happening, see
       // bug 1329884 for a longer explanation.
       let progressNotification = target.ownerGlobal.PopupNotifications.getNotification("addon-progress", target);
       if (progressNotification) {
         progressNotification.remove();
       }
 
       let strings = this._buildStrings(info);
+      // If this is an update with no promptable permissions, just apply it
+      if (info.type == "update" && strings.msgs.length == 0) {
+        info.resolve();
+        return;
+      }
+
       this.showPermissionsPrompt(target, strings, info.icon).then(answer => {
         if (answer) {
           info.resolve();
         } else {
           info.reject();
         }
       });
     } else if (topic == "webextension-update-permissions") {