Bug 1456324: Part 1 - Update tests to use nsIFakePluginTag rather than JS mocks. r?Gijs draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 24 Apr 2018 16:32:17 -0700
changeset 787565 89f14b18c14b4a9487cf3e557602a40453083efb
parent 787564 d3c93907c3edfd9aedcf0187cae127fcc1498803
child 787566 ff57573991b43ae96b5b197e99bb5cd4ccd025e4
push id107747
push usermaglione.k@gmail.com
push dateTue, 24 Apr 2018 23:36:09 +0000
reviewersGijs
bugs1456324
milestone61.0a1
Bug 1456324: Part 1 - Update tests to use nsIFakePluginTag rather than JS mocks. r?Gijs This will allow us to make nsIPluginTag a builtin class. This patch also factors out some common logic from AOM plugin tests. MozReview-Commit-ID: FbXlSE8sjyK
dom/plugins/base/nsIPluginHost.idl
dom/plugins/base/nsPluginHost.cpp
toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/test_blocklist_appversion.js
toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js
toolkit/mozapps/extensions/test/xpcshell/test_blocklist_severities.js
toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js
toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
--- a/dom/plugins/base/nsIPluginHost.idl
+++ b/dom/plugins/base/nsIPluginHost.idl
@@ -153,16 +153,24 @@ interface nsIPluginHost : nsISupports
    * FakePluginTagInit.webidl for what it should look like.  Will throw
    * NS_ERROR_UNEXPECTED if there is already a fake plugin registered with the
    * given handler URI.
    */
   [implicit_jscontext]
   nsIFakePluginTag registerFakePlugin(in jsval initDictionary);
 
   /**
+   * Create a fake plugin tag without registering it.
+   *
+   * Only for use in tests.
+   */
+  [implicit_jscontext]
+  nsIFakePluginTag createFakePlugin(in jsval initDictionary);
+
+  /**
    * Get a reference to an existing fake plugin tag for the given MIME type, if
    * any.  Can return null.
    */
   nsIFakePluginTag getFakePlugin(in AUTF8String mimeType);
 
   /**
    * Unregister a fake plugin.  The argument can be the .handlerURI.spec of an
    * existing nsIFakePluginTag, or just a known handler URI string that was
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1609,16 +1609,34 @@ nsPluginHost::RegisterFakePlugin(JS::Han
     }
   }
 
   newTag.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsPluginHost::CreateFakePlugin(JS::Handle<JS::Value> aInitDictionary,
+                               JSContext* aCx,
+                               nsIFakePluginTag **aResult)
+{
+  FakePluginTagInit initDictionary;
+  if (!initDictionary.Init(aCx, aInitDictionary)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  RefPtr<nsFakePluginTag> newTag;
+  nsresult rv = nsFakePluginTag::Create(initDictionary, getter_AddRefs(newTag));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  newTag.forget(aResult);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsPluginHost::UnregisterFakePlugin(const nsACString& aHandlerURI)
 {
   nsCOMPtr<nsIURI> handlerURI;
   nsresult rv = NS_NewURI(getter_AddRefs(handlerURI), aHandlerURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (uint32_t i = 0; i < mFakePlugins.Length(); ++i) {
     if (mFakePlugins[i]->HandlerURIMatches(handlerURI)) {
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -78,36 +78,51 @@ const PERSONA_DESCRIPTION = "A nice them
 const PLUGIN_UPDATED_TOPIC     = "plugins-list-updated";
 
 // system add-ons are enabled at startup, so record date when the test starts
 const SYSTEM_ADDON_INSTALL_DATE = Date.now();
 
 // Valid attribution code to write so that settings.attribution can be tested.
 const ATTRIBUTION_CODE = "source%3Dgoogle.com";
 
+const pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+
 /**
  * Used to mock plugin tags in our fake plugin host.
  */
 function PluginTag(aName, aDescription, aVersion, aEnabled) {
+  this.pluginTag = pluginHost.createFakePlugin({
+    handlerURI: "resource://fake-plugin/${Math.random()}.xhtml",
+    mimeEntries: this.mimeTypes.map(type => ({type})),
+    name: aName,
+    description: aDescription,
+    version: aVersion,
+  });
   this.name = aName;
   this.description = aDescription;
   this.version = aVersion;
   this.disabled = !aEnabled;
 }
 
 PluginTag.prototype = {
   name: null,
   description: null,
   version: null,
   filename: null,
   fullpath: null,
-  disabled: false,
   blocklisted: false,
   clicktoplay: true,
 
+  get disabled() {
+    return this.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
+  },
+  set disabled(val) {
+    this.pluginTag.enabledState = Ci.nsIPluginTag[val ? "STATE_DISABLED" : "STATE_CLICKTOPLAY"];
+  },
+
   mimeTypes: [ PLUGIN_MIME_TYPE1, PLUGIN_MIME_TYPE2 ],
 
   getMimeTypes(count) {
     count.value = this.mimeTypes.length;
     return this.mimeTypes;
   }
 };
 
@@ -116,17 +131,17 @@ var gInstalledPlugins = [
   new PluginTag("Java", "A mock Java plugin", "1.0", false /* Disabled */),
   new PluginTag(FLASH_PLUGIN_NAME, FLASH_PLUGIN_DESC, FLASH_PLUGIN_VERSION, true),
 ];
 
 // A fake plugin host for testing plugin telemetry environment.
 var PluginHost = {
   getPluginTags(countRef) {
     countRef.value = gInstalledPlugins.length;
-    return gInstalledPlugins;
+    return gInstalledPlugins.map(plugin => plugin.pluginTag);
   },
 
   QueryInterface(iid) {
     if (iid.equals(Ci.nsIPluginHost)
      || iid.equals(Ci.nsISupports))
       return this;
 
     throw Cr.NS_ERROR_NO_INTERFACE;
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -1623,8 +1623,54 @@ async function execSystemAddonTest(setup
   if (test.finalState && setupName in test.finalState) {
     await verifySystemAddonState(setup.initialState, test.finalState[setupName], false, distroDir);
   } else {
     await verifySystemAddonState(setup.initialState, undefined, false, distroDir);
   }
 
   await promiseShutdownManager();
 }
+
+XPCOMUtils.defineLazyServiceGetter(this, "pluginHost",
+                                  "@mozilla.org/plugin/host;1", "nsIPluginHost");
+
+class MockPluginTag {
+  constructor(opts, enabledState = Ci.nsIPluginTag.STATE_ENABLED) {
+    this.pluginTag = pluginHost.createFakePlugin({
+      handlerURI: "resource://fake-plugin/${Math.random()}.xhtml",
+      mimeEntries: [{type: "application/x-fake-plugin"}],
+      ...opts,
+    });
+    this.pluginTag.enabledState = enabledState;
+
+    this.name = opts.name;
+    this.version = opts.version;
+  }
+  async isBlocklisted() {
+    let state = await Services.blocklist.getPluginBlocklistState(this.pluginTag);
+    return state == Services.blocklist.STATE_BLOCKED;
+  }
+  get disabled() {
+    return this.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
+  }
+  set disabled(val) {
+    this.enabledState = Ci.nsIPluginTag[val ? "STATE_DISABLED" : "STATE_ENABLED"];
+  }
+  get enabledState() {
+    return this.pluginTag.enabledState;
+  }
+  set enabledState(val) {
+    this.pluginTag.enabledState = val;
+  }
+}
+
+function mockPluginHost(plugins) {
+  let PluginHost = {
+    getPluginTags(count) {
+      count.value = plugins.length;
+      return plugins.map(p => p.pluginTag);
+    },
+
+    QueryInterface: XPCOMUtils.generateQI(["nsIPluginHost"]),
+  };
+
+  MockRegistrar.register("@mozilla.org/plugin/host;1", PluginHost);
+}
--- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_appversion.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_appversion.js
@@ -180,69 +180,56 @@ var ADDONS = [{
   id: "test_bug449027_25@tests.mozilla.org",
   name: "Bug 449027 Addon Test 25",
   version: "5",
   start: false,
   appBlocks: true,
   toolkitBlocks: true
 }];
 
-function MockPluginTag(name, version, start, appBlocks, toolkitBlocks) {
-  this.name = name;
-  this.version = version;
-  this.start = start;
-  this.appBlocks = appBlocks;
-  this.toolkitBlocks = toolkitBlocks;
+class MockPlugin extends MockPluginTag {
+  constructor(name, version, start, appBlocks, toolkitBlocks) {
+    super({name, version});
+    this.start = start;
+    this.appBlocks = appBlocks;
+    this.toolkitBlocks = toolkitBlocks;
+  }
 }
-MockPluginTag.prototype = {
-  async isBlocklisted() {
-    let state = await Services.blocklist.getPluginBlocklistState(this);
-    return state == Services.blocklist.STATE_BLOCKED;
-  }
-};
 
 var PLUGINS = [
-  new MockPluginTag("test_bug449027_1", "5", false, false, false),
-  new MockPluginTag("test_bug449027_2", "5", false, true, false),
-  new MockPluginTag("test_bug449027_3", "5", false, true, false),
-  new MockPluginTag("test_bug449027_4", "5", false, false, false),
-  new MockPluginTag("test_bug449027_5", "5", false, false, false),
-  new MockPluginTag("test_bug449027_6", "5", false, true, false),
-  new MockPluginTag("test_bug449027_7", "5", false, true, false),
-  new MockPluginTag("test_bug449027_8", "5", false, true, false),
-  new MockPluginTag("test_bug449027_9", "5", false, true, false),
-  new MockPluginTag("test_bug449027_10", "5", false, true, false),
-  new MockPluginTag("test_bug449027_11", "5", false, true, false),
-  new MockPluginTag("test_bug449027_12", "5", false, true, false),
-  new MockPluginTag("test_bug449027_13", "5", false, true, false),
-  new MockPluginTag("test_bug449027_14", "5", false, false, false),
-  new MockPluginTag("test_bug449027_15", "5", false, true, true),
-  new MockPluginTag("test_bug449027_16", "5", false, true, true),
-  new MockPluginTag("test_bug449027_17", "5", false, false, false),
-  new MockPluginTag("test_bug449027_18", "5", false, false, false),
-  new MockPluginTag("test_bug449027_19", "5", false, true, true),
-  new MockPluginTag("test_bug449027_20", "5", false, true, true),
-  new MockPluginTag("test_bug449027_21", "5", false, true, true),
-  new MockPluginTag("test_bug449027_22", "5", false, true, true),
-  new MockPluginTag("test_bug449027_23", "5", false, true, true),
-  new MockPluginTag("test_bug449027_24", "5", false, true, true),
-  new MockPluginTag("test_bug449027_25", "5", false, true, true)
+  new MockPlugin("test_bug449027_1", "5", false, false, false),
+  new MockPlugin("test_bug449027_2", "5", false, true, false),
+  new MockPlugin("test_bug449027_3", "5", false, true, false),
+  new MockPlugin("test_bug449027_4", "5", false, false, false),
+  new MockPlugin("test_bug449027_5", "5", false, false, false),
+  new MockPlugin("test_bug449027_6", "5", false, true, false),
+  new MockPlugin("test_bug449027_7", "5", false, true, false),
+  new MockPlugin("test_bug449027_8", "5", false, true, false),
+  new MockPlugin("test_bug449027_9", "5", false, true, false),
+  new MockPlugin("test_bug449027_10", "5", false, true, false),
+  new MockPlugin("test_bug449027_11", "5", false, true, false),
+  new MockPlugin("test_bug449027_12", "5", false, true, false),
+  new MockPlugin("test_bug449027_13", "5", false, true, false),
+  new MockPlugin("test_bug449027_14", "5", false, false, false),
+  new MockPlugin("test_bug449027_15", "5", false, true, true),
+  new MockPlugin("test_bug449027_16", "5", false, true, true),
+  new MockPlugin("test_bug449027_17", "5", false, false, false),
+  new MockPlugin("test_bug449027_18", "5", false, false, false),
+  new MockPlugin("test_bug449027_19", "5", false, true, true),
+  new MockPlugin("test_bug449027_20", "5", false, true, true),
+  new MockPlugin("test_bug449027_21", "5", false, true, true),
+  new MockPlugin("test_bug449027_22", "5", false, true, true),
+  new MockPlugin("test_bug449027_23", "5", false, true, true),
+  new MockPlugin("test_bug449027_24", "5", false, true, true),
+  new MockPlugin("test_bug449027_25", "5", false, true, true)
 ];
 
 var gNewBlocks = [];
 
-// A fake plugin host for the blocklist service to use
-var PluginHost = {
-  getPluginTags(countRef) {
-    countRef.value = PLUGINS.length;
-    return PLUGINS;
-  },
-
-  QueryInterface: XPCOMUtils.generateQI(["nsIPluginHost"]),
-};
+mockPluginHost(PLUGINS);
 
 var BlocklistPrompt = {
   get wrappedJSObject() { return this; },
 
   prompt(list) {
     gNewBlocks = list.map(item => `${item.name} ${item.version}`);
   },
 
@@ -255,18 +242,16 @@ async function loadBlocklist(file) {
 
   Services.prefs.setCharPref("extensions.blocklist.url",
                              "http://example.com/data/" + file);
   Services.blocklist.QueryInterface(Ci.nsITimerCallback).notify(null);
 
   await blocklistUpdated;
 }
 
-MockRegistrar.register("@mozilla.org/plugin/host;1", PluginHost);
-
 let factory = XPCOMUtils.generateSingletonFactory(function() { return BlocklistPrompt; });
 Cm.registerFactory(Components.ID("{26d32654-30c7-485d-b983-b4d2568aebba}"),
                    "Blocklist Prompt",
                    "@mozilla.org/addons/blocklist-prompt;1", factory);
 
 function createAddon(addon) {
   return promiseInstallXPI({
     name: addon.name,
@@ -283,36 +268,39 @@ function createAddon(addon) {
 /**
  * Checks that items are blocklisted correctly according to the current test.
  * If a lastTest is provided checks that the notification dialog got passed
  * the newly blocked items compared to the previous test.
  */
 async function checkState(test, lastTest, callback) {
   let addons = await AddonManager.getAddonsByIDs(ADDONS.map(a => a.id));
 
-  for (var i = 0; i < ADDONS.length; i++) {
-    await TestUtils.waitForCondition(() => {
-      return (addons[i].blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) == ADDONS[i][test];
-    }).catch(() => { /* ignore exceptions; the following test will fail anyway. */ });
+  const bls = Ci.nsIBlocklistService;
+
+  await TestUtils.waitForCondition(
+    () => ADDONS.every((addon, i) => addon[test] == (addons[i].blocklistState == bls.STATE_BLOCKED))
+  ).catch(() => { /* ignore exceptions; the following test will fail anyway. */ });
+
+  for (let [i, addon] of ADDONS.entries()) {
     var blocked = addons[i].blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED;
-    equal(blocked, ADDONS[i][test],
+    equal(blocked, addon[test],
           `Blocklist state should match expected for extension ${addons[i].id}, test ${test}`);
   }
 
-  for (i = 0; i < PLUGINS.length; i++) {
-    equal(await PLUGINS[i].isBlocklisted(), PLUGINS[i][test],
-          `Blocklist state should match expected for plugin ${PLUGINS[i].name}, test ${test}`);
+  for (let plugin of PLUGINS) {
+    equal(await plugin.isBlocklisted(), plugin[test],
+          `Blocklist state should match expected for plugin ${plugin.name}, test ${test}`);
   }
 
   if (lastTest) {
     var expected = 0;
-    for (i = 0; i < PLUGINS.length; i++) {
-      if (PLUGINS[i][test] && !PLUGINS[i][lastTest]) {
-        ok(gNewBlocks.includes(`${PLUGINS[i].name} ${PLUGINS[i].version}`),
-           `Plugin ${PLUGINS[i].name} should have been listed in the blocklist notification for test ${test}`);
+    for (let plugin of PLUGINS) {
+      if (plugin[test] && !plugin[lastTest]) {
+        ok(gNewBlocks.includes(`${plugin.name} ${plugin.version}`),
+           `Plugin ${plugin.name} should have been listed in the blocklist notification for test ${test}`);
         expected++;
       }
     }
 
     Assert.equal(expected, gNewBlocks.length);
   }
 }
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_plugin_outdated.js
@@ -8,16 +8,22 @@ ChromeUtils.import("resource://testing-c
 ChromeUtils.import("resource://testing-common/MockRegistrar.jsm");
 
 const nsIBLS = Ci.nsIBlocklistService;
 
 var gBlocklist = null;
 var gTestserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]});
 gTestserver.registerDirectory("/data/", do_get_file("data"));
 
+class MockPlugin extends MockPluginTag {
+  constructor(opts) {
+    super(opts, opts.enabledState);
+    this.blocklisted = opts.blocklisted;
+  }
+}
 
 var PLUGINS = [{
   // Tests a plugin whose state goes from not-blocked, to outdated
   name: "test_bug514327_outdated",
   version: "5",
   disabled: false,
   blocklisted: false
 }, {
@@ -27,28 +33,19 @@ var PLUGINS = [{
   disabled: false,
   blocklisted: false
 }, {
   // Used to trigger the blocklist dialog, which indicates the blocklist has updated
   name: "test_bug514327_2",
   version: "5",
   disabled: false,
   blocklisted: false
-} ];
-
+}].map(opts => new MockPlugin(opts));
 
-// A fake plugin host for the blocklist service to use
-var PluginHost = {
-  getPluginTags(countRef) {
-    countRef.value = PLUGINS.length;
-    return PLUGINS;
-  },
-
-  QueryInterface: XPCOMUtils.generateQI(["nsIPluginHost"]),
-};
+mockPluginHost(PLUGINS);
 
 var BlocklistPrompt = {
   get wrappedJSObject() { return this; },
 
   prompt(list) {
     // Should only include one item
     Assert.equal(list.length, 1);
     // And that item should be the blocked plugin, not the outdated one
@@ -66,18 +63,16 @@ async function loadBlocklist(file) {
 
   Services.prefs.setCharPref("extensions.blocklist.url",
                              "http://example.com/data/" + file);
   Services.blocklist.QueryInterface(Ci.nsITimerCallback).notify(null);
 
   await blocklistUpdated;
 }
 
-MockRegistrar.register("@mozilla.org/plugin/host;1", PluginHost);
-
 let factory = XPCOMUtils.generateSingletonFactory(function() { return BlocklistPrompt; });
 Cm.registerFactory(Components.ID("{26d32654-30c7-485d-b983-b4d2568aebba}"),
                    "Blocklist Prompt",
                    "@mozilla.org/addons/blocklist-prompt;1", factory);
 
 add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_severities.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_severities.js
@@ -70,53 +70,40 @@ var ADDONS = [{
 }, {
   // Spare add-on used to ensure we get a notification when switching lists
   id: "dummy_bug455906_2@tests.mozilla.org",
   name: "Dummy Addon 2",
   version: "5",
   appVersion: "3"
 }];
 
-class MockPlugin {
-  constructor(name, version, enabledState) {
-    this.name = name;
-    this.version = version;
-    this.enabledState = enabledState;
-  }
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  }
-}
+// Copy the initial blocklist into the profile to check add-ons start in the
+// right state.
+// Make sure to do this before we touch the plugin service, since that
+// will force a blocklist load.
+copyBlocklistToProfile(do_get_file("data/bug455906_start.xml"));
 
 var PLUGINS = [
   // Tests how the blocklist affects a disabled plugin
-  new MockPlugin("test_bug455906_1", "5", Ci.nsIPluginTag.STATE_DISABLED),
+  new MockPluginTag({name: "test_bug455906_1", version: "5"}, Ci.nsIPluginTag.STATE_DISABLED),
   // Tests how the blocklist affects an enabled plugin
-  new MockPlugin("test_bug455906_2", "5", Ci.nsIPluginTag.STATE_ENABLED),
+  new MockPluginTag({name: "test_bug455906_2", version: "5"}, Ci.nsIPluginTag.STATE_ENABLED),
   // Tests how the blocklist affects an enabled plugin, to be disabled by the notification
-  new MockPlugin("test_bug455906_3", "5", Ci.nsIPluginTag.STATE_ENABLED),
+  new MockPluginTag({name: "test_bug455906_3", version: "5"}, Ci.nsIPluginTag.STATE_ENABLED),
   // Tests how the blocklist affects a disabled plugin that was already warned about
-  new MockPlugin("test_bug455906_4", "5", Ci.nsIPluginTag.STATE_DISABLED),
+  new MockPluginTag({name: "test_bug455906_4", version: "5"}, Ci.nsIPluginTag.STATE_DISABLED),
   // Tests how the blocklist affects an enabled plugin that was already warned about
-  new MockPlugin("test_bug455906_5", "5", Ci.nsIPluginTag.STATE_ENABLED),
+  new MockPluginTag({name: "test_bug455906_5", version: "5"}, Ci.nsIPluginTag.STATE_ENABLED),
   // Tests how the blocklist affects an already blocked plugin
-  new MockPlugin("test_bug455906_6", "5", Ci.nsIPluginTag.STATE_ENABLED)
+  new MockPluginTag({name: "test_bug455906_6", version: "5"}, Ci.nsIPluginTag.STATE_ENABLED)
 ];
 
 var gNotificationCheck = null;
 
-// A fake plugin host for the blocklist service to use
-var PluginHost = {
-  getPluginTags(countRef) {
-    countRef.value = PLUGINS.length;
-    return PLUGINS;
-  },
-
-  QueryInterface: XPCOMUtils.generateQI(["nsIPluginHost"]),
-};
+mockPluginHost(PLUGINS);
 
 // Don't need the full interface, attempts to call other methods will just
 // throw which is just fine
 var WindowWatcher = {
   openWindow(parent, url, name, features, windowArguments) {
     // Should be called to list the newly blocklisted items
     equal(url, URI_EXTENSION_BLOCKLIST_DIALOG);
 
@@ -126,17 +113,16 @@ var WindowWatcher = {
 
     // run the code after the blocklist is closed
     Services.obs.notifyObservers(null, "addon-blocklist-closed");
   },
 
   QueryInterface: XPCOMUtils.generateQI(["nsIWindowWatcher"]),
 };
 
-MockRegistrar.register("@mozilla.org/plugin/host;1", PluginHost);
 MockRegistrar.register("@mozilla.org/embedcomp/window-watcher;1", WindowWatcher);
 
 function createAddon(addon) {
   return promiseInstallXPI({
     name: addon.name,
     id: addon.id,
     version: addon.version,
     bootstrap: true,
@@ -190,20 +176,16 @@ async function checkInitialState() {
   equal(await check_plugin_state(PLUGINS[5]), "false,true");
 }
 
 function checkAddonState(addon, state) {
   return checkAddon(addon.id, addon, state);
 }
 
 add_task(async function setup() {
-  // Copy the initial blocklist into the profile to check add-ons start in the
-  // right state.
-  copyBlocklistToProfile(do_get_file("data/bug455906_start.xml"));
-
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "3", "8");
   await promiseStartupManager();
 
   for (let addon of ADDONS)
     await createAddon(addon);
 });
 
 add_task(async function test_1() {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_duplicateplugins.js
@@ -2,105 +2,75 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 ChromeUtils.import("resource://testing-common/MockRegistrar.jsm");
 
 // This verifies that duplicate plugins are coalesced and maintain their ID
 // across restarts.
 
+class MockPlugin extends MockPluginTag {
+  constructor(opts) {
+    super(opts, opts.enabledState);
+    this.blocklisted = opts.blocklisted;
+  }
+}
+
 var PLUGINS = [{
   name: "Duplicate Plugin 1",
   description: "A duplicate plugin",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/home/mozilla/.plugins/dupplugin1.so"
 }, {
   name: "Duplicate Plugin 1",
   description: "A duplicate plugin",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/usr/lib/plugins/dupplugin1.so"
 }, {
   name: "Duplicate Plugin 2",
   description: "Another duplicate plugin",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/home/mozilla/.plugins/dupplugin2.so"
 }, {
   name: "Duplicate Plugin 2",
   description: "Another duplicate plugin",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/usr/lib/plugins/dupplugin2.so"
 }, {
   name: "Non-duplicate Plugin", // 3
   description: "Not a duplicate plugin",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/home/mozilla/.plugins/dupplugin3.so"
 }, {
   name: "Non-duplicate Plugin", // 4
   description: "Not a duplicate because the descriptions are different",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/usr/lib/plugins/dupplugin4.so"
 }, {
   name: "Another Non-duplicate Plugin", // 5
   description: "Not a duplicate plugin",
   version: "1",
   blocklisted: false,
   enabledState: Ci.nsIPluginTag.STATE_ENABLED,
-  get disabled() {
-    return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
-  },
   filename: "/home/mozilla/.plugins/dupplugin5.so"
-}];
+}].map(opts => new MockPlugin(opts));
 
-// A fake plugin host to return the plugins defined above
-var PluginHost = {
-  getPluginTags(countRef) {
-    countRef.value = PLUGINS.length;
-    return PLUGINS;
-  },
-
-  QueryInterface(iid) {
-    if (iid.equals(Ci.nsIPluginHost)
-     || iid.equals(Ci.nsISupports))
-      return this;
-
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  }
-};
-
-MockRegistrar.register("@mozilla.org/plugin/host;1", PluginHost);
+mockPluginHost(PLUGINS);
 
 var gPluginIDs = [null, null, null, null, null];
 
 function run_test() {
   do_test_pending();
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
   Services.prefs.setBoolPref("media.gmp-provider.enabled", false);
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_pluginchange.js
@@ -1,59 +1,31 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const LIST_UPDATED_TOPIC     = "plugins-list-updated";
 
-var { MockRegistrar } = ChromeUtils.import("resource://testing-common/MockRegistrar.jsm", {});
-
-function PluginTag(name, description) {
-  this.name = name;
-  this.description = description;
+class PluginTag extends MockPluginTag {
+  constructor(name, description) {
+    super({name, description, version: "1.0"});
+    this.description = description;
+  }
 }
 
-PluginTag.prototype = {
-  name: null,
-  description: null,
-  version: "1.0",
-  filename: null,
-  fullpath: null,
-  disabled: false,
-  blocklisted: false,
-  clicktoplay: false,
-
-  mimeTypes: [],
-
-  getMimeTypes(count) {
-    count.value = this.mimeTypes.length;
-    return this.mimeTypes;
-  }
-};
-
 const PLUGINS = [
   // A standalone plugin
   new PluginTag("Java", "A mock Java plugin"),
 
   // A plugin made up of two plugin files
   new PluginTag("Flash", "A mock Flash plugin"),
   new PluginTag("Flash", "A mock Flash plugin")
 ];
 
-const gPluginHost = {
-  // nsIPluginHost
-  getPluginTags(count) {
-    count.value = PLUGINS.length;
-    return PLUGINS;
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPluginHost])
-};
-
-MockRegistrar.register("@mozilla.org/plugin/host;1", gPluginHost);
+mockPluginHost(PLUGINS);
 
 // This verifies that when the list of plugins changes the add-ons manager
 // correctly updates
 function run_test() {
   do_test_pending();
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
   Services.prefs.setBoolPref("media.gmp-provider.enabled", false);