toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
     6 const Cc = Components.classes;
     7 const Ci = Components.interfaces;
     8 const Cu = Components.utils;
     9 const Cr = Components.results;
    11 const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul";
    13 Cu.import("resource://testing-common/httpd.js");
    14 var gTestserver = new HttpServer();
    15 gTestserver.start(-1);
    16 gPort = gTestserver.identity.primaryPort;
    18 // register static files with server and interpolate port numbers in them
    19 mapFile("/data/bug455906_warn.xml", gTestserver);
    20 mapFile("/data/bug455906_start.xml", gTestserver);
    21 mapFile("/data/bug455906_block.xml", gTestserver);
    22 mapFile("/data/bug455906_empty.xml", gTestserver);
    24 // Workaround for Bug 658720 - URL formatter can leak during xpcshell tests
    25 const PREF_BLOCKLIST_ITEM_URL = "extensions.blocklist.itemURL";
    26 Services.prefs.setCharPref(PREF_BLOCKLIST_ITEM_URL, "http://localhost:" + gPort + "/blocklist/%blockID%");
    28 var ADDONS = [{
    29   // Tests how the blocklist affects a disabled add-on
    30   id: "test_bug455906_1@tests.mozilla.org",
    31   name: "Bug 455906 Addon Test 1",
    32   version: "5",
    33   appVersion: "3"
    34 }, {
    35   // Tests how the blocklist affects an enabled add-on
    36   id: "test_bug455906_2@tests.mozilla.org",
    37   name: "Bug 455906 Addon Test 2",
    38   version: "5",
    39   appVersion: "3"
    40 }, {
    41   // Tests how the blocklist affects an enabled add-on, to be disabled by the notification
    42   id: "test_bug455906_3@tests.mozilla.org",
    43   name: "Bug 455906 Addon Test 3",
    44   version: "5",
    45   appVersion: "3"
    46 }, {
    47   // Tests how the blocklist affects a disabled add-on that was already warned about
    48   id: "test_bug455906_4@tests.mozilla.org",
    49   name: "Bug 455906 Addon Test 4",
    50   version: "5",
    51   appVersion: "3"
    52 }, {
    53   // Tests how the blocklist affects an enabled add-on that was already warned about
    54   id: "test_bug455906_5@tests.mozilla.org",
    55   name: "Bug 455906 Addon Test 5",
    56   version: "5",
    57   appVersion: "3"
    58 }, {
    59   // Tests how the blocklist affects an already blocked add-on
    60   id: "test_bug455906_6@tests.mozilla.org",
    61   name: "Bug 455906 Addon Test 6",
    62   version: "5",
    63   appVersion: "3"
    64 }, {
    65   // Tests how the blocklist affects an incompatible add-on
    66   id: "test_bug455906_7@tests.mozilla.org",
    67   name: "Bug 455906 Addon Test 7",
    68   version: "5",
    69   appVersion: "2"
    70 }, {
    71   // Spare add-on used to ensure we get a notification when switching lists
    72   id: "dummy_bug455906_1@tests.mozilla.org",
    73   name: "Dummy Addon 1",
    74   version: "5",
    75   appVersion: "3"
    76 }, {
    77   // Spare add-on used to ensure we get a notification when switching lists
    78   id: "dummy_bug455906_2@tests.mozilla.org",
    79   name: "Dummy Addon 2",
    80   version: "5",
    81   appVersion: "3"
    82 }];
    84 function MockPlugin(name, version, enabledState) {
    85   this.name = name;
    86   this.version = version;
    87   this.enabledState = enabledState;
    88 }
    89 Object.defineProperty(MockPlugin.prototype, "blocklisted", {
    90   get: function MockPlugin_getBlocklisted() {
    91     let bls = Cc["@mozilla.org/extensions/blocklist;1"].getService(Ci.nsIBlocklistService);
    92     return bls.getPluginBlocklistState(this) == bls.STATE_BLOCKED;
    93   }
    94 });
    95 Object.defineProperty(MockPlugin.prototype, "disabled", {
    96   get: function MockPlugin_getDisabled() {
    97     return this.enabledState == Ci.nsIPluginTag.STATE_DISABLED;
    98   }
    99 });
   101 var PLUGINS = [
   102   // Tests how the blocklist affects a disabled plugin
   103   new MockPlugin("test_bug455906_1", "5", Ci.nsIPluginTag.STATE_DISABLED),
   104   // Tests how the blocklist affects an enabled plugin
   105   new MockPlugin("test_bug455906_2", "5", Ci.nsIPluginTag.STATE_ENABLED),
   106   // Tests how the blocklist affects an enabled plugin, to be disabled by the notification
   107   new MockPlugin("test_bug455906_3", "5", Ci.nsIPluginTag.STATE_ENABLED),
   108   // Tests how the blocklist affects a disabled plugin that was already warned about
   109   new MockPlugin("test_bug455906_4", "5", Ci.nsIPluginTag.STATE_DISABLED),
   110   // Tests how the blocklist affects an enabled plugin that was already warned about
   111   new MockPlugin("test_bug455906_5", "5", Ci.nsIPluginTag.STATE_ENABLED),
   112   // Tests how the blocklist affects an already blocked plugin
   113   new MockPlugin("test_bug455906_6", "5", Ci.nsIPluginTag.STATE_ENABLED)
   114 ];
   116 var gNotificationCheck = null;
   117 var gTestCheck = null;
   119 // A fake plugin host for the blocklist service to use
   120 var PluginHost = {
   121   getPluginTags: function(countRef) {
   122     countRef.value = PLUGINS.length;
   123     return PLUGINS;
   124   },
   126   QueryInterface: function(iid) {
   127     if (iid.equals(Ci.nsIPluginHost)
   128      || iid.equals(Ci.nsISupports))
   129       return this;
   131     throw Components.results.NS_ERROR_NO_INTERFACE;
   132   }
   133 }
   135 var PluginHostFactory = {
   136   createInstance: function (outer, iid) {
   137     if (outer != null)
   138       throw Components.results.NS_ERROR_NO_AGGREGATION;
   139     return PluginHost.QueryInterface(iid);
   140   }
   141 };
   143 // Don't need the full interface, attempts to call other methods will just
   144 // throw which is just fine
   145 var WindowWatcher = {
   146   openWindow: function(parent, url, name, features, windowArguments) {
   147     // Should be called to list the newly blocklisted items
   148     do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG);
   150     if (gNotificationCheck) {
   151       var args = windowArguments.wrappedJSObject;
   152       gNotificationCheck(args);
   153     }
   155     //run the code after the blocklist is closed
   156     Services.obs.notifyObservers(null, "addon-blocklist-closed", null);
   158     // Call the next test after the blocklist has finished up
   159     do_timeout(0, gTestCheck);
   160   },
   162   QueryInterface: function(iid) {
   163     if (iid.equals(Ci.nsIWindowWatcher)
   164      || iid.equals(Ci.nsISupports))
   165       return this;
   167     throw Cr.NS_ERROR_NO_INTERFACE;
   168   }
   169 }
   171 var WindowWatcherFactory = {
   172   createInstance: function createInstance(outer, iid) {
   173     if (outer != null)
   174       throw Components.results.NS_ERROR_NO_AGGREGATION;
   175     return WindowWatcher.QueryInterface(iid);
   176   }
   177 };
   178 var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
   179 registrar.registerFactory(Components.ID("{721c3e73-969e-474b-a6dc-059fd288c428}"),
   180                           "Fake Plugin Host",
   181                           "@mozilla.org/plugin/host;1", PluginHostFactory);
   182 registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"),
   183                           "Fake Window Watcher",
   184                           "@mozilla.org/embedcomp/window-watcher;1", WindowWatcherFactory);
   186 function create_addon(addon) {
   187   var installrdf = "<?xml version=\"1.0\"?>\n" +
   188                    "\n" +
   189                    "<RDF xmlns=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +
   190                    "     xmlns:em=\"http://www.mozilla.org/2004/em-rdf#\">\n" +
   191                    "  <Description about=\"urn:mozilla:install-manifest\">\n" +
   192                    "    <em:id>" + addon.id + "</em:id>\n" +
   193                    "    <em:version>" + addon.version + "</em:version>\n" +
   194                    "    <em:targetApplication>\n" +
   195                    "      <Description>\n" +
   196                    "        <em:id>xpcshell@tests.mozilla.org</em:id>\n" +
   197                    "        <em:minVersion>" + addon.appVersion + "</em:minVersion>\n" +
   198                    "        <em:maxVersion>" + addon.appVersion + "</em:maxVersion>\n" +
   199                    "      </Description>\n" +
   200                    "    </em:targetApplication>\n" +
   201                    "    <em:name>" + addon.name + "</em:name>\n" +
   202                    "  </Description>\n" +
   203                    "</RDF>\n";
   204   var target = gProfD.clone();
   205   target.append("extensions");
   206   target.append(addon.id);
   207   target.append("install.rdf");
   208   target.create(target.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
   209   var stream = Cc["@mozilla.org/network/file-output-stream;1"].
   210                createInstance(Ci.nsIFileOutputStream);
   211   stream.init(target,
   212               FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE,
   213               FileUtils.PERMS_FILE, 0);
   214   stream.write(installrdf, installrdf.length);
   215   stream.close();
   216 }
   218 function load_blocklist(file) {
   219   Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + gPort + "/data/" + file);
   220   var blocklist = Cc["@mozilla.org/extensions/blocklist;1"].
   221                   getService(Ci.nsITimerCallback);
   222   blocklist.notify(null);
   223 }
   225 function check_addon_state(addon) {
   226   return addon.userDisabled + "," + addon.softDisabled + "," + addon.appDisabled;
   227 }
   229 function check_plugin_state(plugin) {
   230   return plugin.disabled + "," + plugin.blocklisted;
   231 }
   233 function create_blocklistURL(blockID){
   234   let url = Services.urlFormatter.formatURLPref(PREF_BLOCKLIST_ITEM_URL);
   235   url = url.replace(/%blockID%/g, blockID);
   236   return url;
   237 }
   239 // Performs the initial setup
   240 function run_test() {
   241   // Setup for test
   242   dump("Setting up tests\n");
   243   // Rather than keeping lots of identical add-ons in version control, just
   244   // write them into the profile.
   245   for (let addon of ADDONS)
   246     create_addon(addon);
   248   // Copy the initial blocklist into the profile to check add-ons start in the
   249   // right state.
   250   copyBlocklistToProfile(do_get_file("data/bug455906_start.xml"));
   252   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "3", "8");
   253   startupManager();
   255   do_test_pending();
   256   check_test_pt1();
   257 }
   259 // Before every main test this is the state the add-ons are meant to be in
   260 function check_initial_state(callback) {
   261   AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) {
   262     do_check_eq(check_addon_state(addons[0]), "true,false,false");
   263     do_check_eq(check_addon_state(addons[1]), "false,false,false");
   264     do_check_eq(check_addon_state(addons[2]), "false,false,false");
   265     do_check_eq(check_addon_state(addons[3]), "true,true,false");
   266     do_check_eq(check_addon_state(addons[4]), "false,false,false");
   267     do_check_eq(check_addon_state(addons[5]), "false,false,true");
   268     do_check_eq(check_addon_state(addons[6]), "false,false,true");
   270     do_check_eq(check_plugin_state(PLUGINS[0]), "true,false");
   271     do_check_eq(check_plugin_state(PLUGINS[1]), "false,false");
   272     do_check_eq(check_plugin_state(PLUGINS[2]), "false,false");
   273     do_check_eq(check_plugin_state(PLUGINS[3]), "true,false");
   274     do_check_eq(check_plugin_state(PLUGINS[4]), "false,false");
   275     do_check_eq(check_plugin_state(PLUGINS[5]), "false,true");
   277     callback();
   278   });
   279 }
   281 // Tests the add-ons were installed and the initial blocklist applied as expected
   282 function check_test_pt1() {
   283   dump("Checking pt 1\n");
   285   AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], callback_soon(function(addons) {
   286     for (var i = 0; i < ADDONS.length; i++) {
   287       if (!addons[i])
   288         do_throw("Addon " + (i + 1) + " did not get installed correctly");
   289     }
   291     do_check_eq(check_addon_state(addons[0]), "false,false,false");
   292     do_check_eq(check_addon_state(addons[1]), "false,false,false");
   293     do_check_eq(check_addon_state(addons[2]), "false,false,false");
   295     // Warn add-ons should be soft disabled automatically
   296     do_check_eq(check_addon_state(addons[3]), "true,true,false");
   297     do_check_eq(check_addon_state(addons[4]), "true,true,false");
   299     // Blocked and incompatible should be app disabled only
   300     do_check_eq(check_addon_state(addons[5]), "false,false,true");
   301     do_check_eq(check_addon_state(addons[6]), "false,false,true");
   303     // We've overridden the plugin host so we cannot tell what that would have
   304     // initialised the plugins as
   306     // Put the add-ons into the base state
   307     addons[0].userDisabled = true;
   308     addons[4].userDisabled = false;
   310     restartManager();
   311     check_initial_state(function() {
   312       gNotificationCheck = check_notification_pt2;
   313       gTestCheck = check_test_pt2;
   314       load_blocklist("bug455906_warn.xml");
   315     });
   316   }));
   317 }
   319 function check_notification_pt2(args) {
   320   dump("Checking notification pt 2\n");
   321   do_check_eq(args.list.length, 4);
   323   for (let addon of args.list) {
   324     if (addon.item instanceof Ci.nsIPluginTag) {
   325       switch (addon.item.name) {
   326         case "test_bug455906_2":
   327           do_check_false(addon.blocked);
   328           break;
   329         case "test_bug455906_3":
   330           do_check_false(addon.blocked);
   331           addon.disable = true;
   332           break;
   333         default:
   334           do_throw("Unknown addon: " + addon.item.name);
   335       }
   336     }
   337     else {
   338       switch (addon.item.id) {
   339         case "test_bug455906_2@tests.mozilla.org":
   340           do_check_false(addon.blocked);
   341           break;
   342         case "test_bug455906_3@tests.mozilla.org":
   343           do_check_false(addon.blocked);
   344           addon.disable = true;
   345           break;
   346         default:
   347           do_throw("Unknown addon: " + addon.item.id);
   348       }
   349     }
   350   }
   351 }
   353 function check_test_pt2() {
   354   restartManager();
   355   dump("Checking results pt 2\n");
   357   AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], callback_soon(function(addons) {
   358     // Should have disabled this add-on as requested
   359     do_check_eq(check_addon_state(addons[2]), "true,true,false");
   360     do_check_eq(check_plugin_state(PLUGINS[2]), "true,false");
   362     // The blocked add-on should have changed to soft disabled
   363     do_check_eq(check_addon_state(addons[5]), "true,true,false");
   364     do_check_eq(check_plugin_state(PLUGINS[5]), "true,false");
   366     // These should have been unchanged
   367     do_check_eq(check_addon_state(addons[0]), "true,false,false");
   368     do_check_eq(check_addon_state(addons[1]), "false,false,false");
   369     do_check_eq(check_addon_state(addons[3]), "true,true,false");
   370     do_check_eq(check_addon_state(addons[4]), "false,false,false");
   371     do_check_eq(check_addon_state(addons[6]), "false,false,true");
   372     do_check_eq(check_plugin_state(PLUGINS[0]), "true,false");
   373     do_check_eq(check_plugin_state(PLUGINS[1]), "false,false");
   374     do_check_eq(check_plugin_state(PLUGINS[3]), "true,false");
   375     do_check_eq(check_plugin_state(PLUGINS[4]), "false,false");
   377     // Back to starting state
   378     addons[2].userDisabled = false;
   379     addons[5].userDisabled = false;
   380     PLUGINS[2].enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   381     PLUGINS[5].enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   382     restartManager();
   383     gNotificationCheck = null;
   384     gTestCheck = run_test_pt3;
   385     load_blocklist("bug455906_start.xml");
   386   }));
   387 }
   389 function run_test_pt3() {
   390   restartManager();
   391   check_initial_state(function() {
   392     gNotificationCheck = check_notification_pt3;
   393     gTestCheck = check_test_pt3;
   394     load_blocklist("bug455906_block.xml");
   395   });
   396 }
   398 function check_notification_pt3(args) {
   399   dump("Checking notification pt 3\n");
   400   do_check_eq(args.list.length, 6);
   402   for (let addon of args.list) {
   403     if (addon.item instanceof Ci.nsIPluginTag) {
   404       switch (addon.item.name) {
   405         case "test_bug455906_2":
   406           do_check_true(addon.blocked);
   407           break;
   408         case "test_bug455906_3":
   409           do_check_true(addon.blocked);
   410           break;
   411         case "test_bug455906_5":
   412           do_check_true(addon.blocked);
   413           break;
   414         default:
   415           do_throw("Unknown addon: " + addon.item.name);
   416       }
   417     }
   418     else {
   419       switch (addon.item.id) {
   420         case "test_bug455906_2@tests.mozilla.org":
   421           do_check_true(addon.blocked);
   422           break;
   423         case "test_bug455906_3@tests.mozilla.org":
   424           do_check_true(addon.blocked);
   425           break;
   426         case "test_bug455906_5@tests.mozilla.org":
   427           do_check_true(addon.blocked);
   428           break;
   429         default:
   430           do_throw("Unknown addon: " + addon.item.id);
   431       }
   432     }
   433   }
   434 }
   436 function check_test_pt3() {
   437   restartManager();
   438   dump("Checking results pt 3\n");
   440   let blocklist = Cc["@mozilla.org/extensions/blocklist;1"].
   441                   getService(Ci.nsIBlocklistService);
   443   AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) {
   444     // All should have gained the blocklist state, user disabled as previously
   445     do_check_eq(check_addon_state(addons[0]), "true,false,true");
   446     do_check_eq(check_addon_state(addons[1]), "false,false,true");
   447     do_check_eq(check_addon_state(addons[2]), "false,false,true");
   448     do_check_eq(check_addon_state(addons[4]), "false,false,true");
   449     do_check_eq(check_plugin_state(PLUGINS[0]), "true,true");
   450     do_check_eq(check_plugin_state(PLUGINS[1]), "false,true");
   451     do_check_eq(check_plugin_state(PLUGINS[2]), "false,true");
   452     do_check_eq(check_plugin_state(PLUGINS[3]), "true,true");
   453     do_check_eq(check_plugin_state(PLUGINS[4]), "false,true");
   455     // Should have gained the blocklist state but no longer be soft disabled
   456     do_check_eq(check_addon_state(addons[3]), "false,false,true");
   458     // Check blockIDs are correct
   459     do_check_eq(blocklist.getAddonBlocklistURL(addons[0]),create_blocklistURL(addons[0].id));
   460     do_check_eq(blocklist.getAddonBlocklistURL(addons[1]),create_blocklistURL(addons[1].id));
   461     do_check_eq(blocklist.getAddonBlocklistURL(addons[2]),create_blocklistURL(addons[2].id));
   462     do_check_eq(blocklist.getAddonBlocklistURL(addons[3]),create_blocklistURL(addons[3].id));
   463     do_check_eq(blocklist.getAddonBlocklistURL(addons[4]),create_blocklistURL(addons[4].id));
   465     // All plugins have the same blockID on the test
   466     do_check_eq(blocklist.getPluginBlocklistURL(PLUGINS[0]), create_blocklistURL('test_bug455906_plugin'));
   467     do_check_eq(blocklist.getPluginBlocklistURL(PLUGINS[1]), create_blocklistURL('test_bug455906_plugin'));
   468     do_check_eq(blocklist.getPluginBlocklistURL(PLUGINS[2]), create_blocklistURL('test_bug455906_plugin'));
   469     do_check_eq(blocklist.getPluginBlocklistURL(PLUGINS[3]), create_blocklistURL('test_bug455906_plugin'));
   470     do_check_eq(blocklist.getPluginBlocklistURL(PLUGINS[4]), create_blocklistURL('test_bug455906_plugin'));
   472     // Shouldn't be changed
   473     do_check_eq(check_addon_state(addons[5]), "false,false,true");
   474     do_check_eq(check_addon_state(addons[6]), "false,false,true");
   475     do_check_eq(check_plugin_state(PLUGINS[5]), "false,true");
   477     // Back to starting state
   478     gNotificationCheck = null;
   479     gTestCheck = run_test_pt4;
   480     load_blocklist("bug455906_start.xml");
   481   });
   482 }
   484 function run_test_pt4() {
   485   AddonManager.getAddonByID(ADDONS[4].id, callback_soon(function(addon) {
   486     addon.userDisabled = false;
   487     PLUGINS[4].enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   488     restartManager();
   489     check_initial_state(function() {
   490       gNotificationCheck = check_notification_pt4;
   491       gTestCheck = check_test_pt4;
   492       load_blocklist("bug455906_empty.xml");
   493     });
   494   }));
   495 }
   497 function check_notification_pt4(args) {
   498   dump("Checking notification pt 4\n");
   500   // Should be just the dummy add-on to force this notification
   501   do_check_eq(args.list.length, 1);
   502   do_check_false(args.list[0].item instanceof Ci.nsIPluginTag);
   503   do_check_eq(args.list[0].item.id, "dummy_bug455906_2@tests.mozilla.org");
   504 }
   506 function check_test_pt4() {
   507   restartManager();
   508   dump("Checking results pt 4\n");
   510   AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) {
   511     // This should have become unblocked
   512     do_check_eq(check_addon_state(addons[5]), "false,false,false");
   513     do_check_eq(check_plugin_state(PLUGINS[5]), "false,false");
   515     // Should get re-enabled
   516     do_check_eq(check_addon_state(addons[3]), "false,false,false");
   518     // No change for anything else
   519     do_check_eq(check_addon_state(addons[0]), "true,false,false");
   520     do_check_eq(check_addon_state(addons[1]), "false,false,false");
   521     do_check_eq(check_addon_state(addons[2]), "false,false,false");
   522     do_check_eq(check_addon_state(addons[4]), "false,false,false");
   523     do_check_eq(check_addon_state(addons[6]), "false,false,true");
   524     do_check_eq(check_plugin_state(PLUGINS[0]), "true,false");
   525     do_check_eq(check_plugin_state(PLUGINS[1]), "false,false");
   526     do_check_eq(check_plugin_state(PLUGINS[2]), "false,false");
   527     do_check_eq(check_plugin_state(PLUGINS[3]), "true,false");
   528     do_check_eq(check_plugin_state(PLUGINS[4]), "false,false");
   530     finish();
   531   });
   532 }
   534 function finish() {
   535   gTestserver.stop(do_test_finished);
   536 }

mercurial