michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: */ michael@0: const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; michael@0: michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://testing-common/httpd.js"); michael@0: michael@0: var ADDONS = [{ michael@0: id: "test_bug449027_1@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 1", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: false, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_2@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 2", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_3@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 3", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_4@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 4", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: false, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_5@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 5", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: false, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_6@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 6", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_7@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 7", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_8@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 8", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_9@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 9", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_10@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 10", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_11@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 11", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_12@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 12", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_13@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 13", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_14@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 14", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: false, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_15@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 15", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_16@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 16", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_17@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 17", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: false, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_18@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 18", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: false, michael@0: toolkitBlocks: false michael@0: }, { michael@0: id: "test_bug449027_19@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 19", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_20@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 20", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_21@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 21", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_22@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 22", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_23@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 23", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_24@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 24", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }, { michael@0: id: "test_bug449027_25@tests.mozilla.org", michael@0: name: "Bug 449027 Addon Test 25", michael@0: version: "5", michael@0: start: false, michael@0: appBlocks: true, michael@0: toolkitBlocks: true michael@0: }]; michael@0: michael@0: function MockPluginTag(name, version, start, appBlocks, toolkitBlocks) michael@0: { michael@0: this.name = name; michael@0: this.version = version; michael@0: this.start = start; michael@0: this.appBlocks = appBlocks; michael@0: this.toolkitBlocks = toolkitBlocks; michael@0: } michael@0: Object.defineProperty(MockPluginTag.prototype, "blocklisted", { michael@0: get: function MockPluginTag_getBlocklisted() { michael@0: let bls = AM_Cc["@mozilla.org/extensions/blocklist;1"].getService(Ci.nsIBlocklistService); michael@0: return bls.getPluginBlocklistState(this) == bls.STATE_BLOCKED; michael@0: } michael@0: }); michael@0: michael@0: var PLUGINS = [ michael@0: new MockPluginTag("test_bug449027_1", "5", false, false, false), michael@0: new MockPluginTag("test_bug449027_2", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_3", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_4", "5", false, false, false), michael@0: new MockPluginTag("test_bug449027_5", "5", false, false, false), michael@0: new MockPluginTag("test_bug449027_6", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_7", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_8", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_9", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_10", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_11", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_12", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_13", "5", false, true, false), michael@0: new MockPluginTag("test_bug449027_14", "5", false, false, false), michael@0: new MockPluginTag("test_bug449027_15", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_16", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_17", "5", false, false, false), michael@0: new MockPluginTag("test_bug449027_18", "5", false, false, false), michael@0: new MockPluginTag("test_bug449027_19", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_20", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_21", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_22", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_23", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_24", "5", false, true, true), michael@0: new MockPluginTag("test_bug449027_25", "5", false, true, true) michael@0: ]; michael@0: michael@0: var gCallback = null; michael@0: var gTestserver = null; michael@0: var gNewBlocks = []; michael@0: michael@0: // A fake plugin host for the blocklist service to use michael@0: var PluginHost = { michael@0: getPluginTags: function(countRef) { michael@0: countRef.value = PLUGINS.length; michael@0: return PLUGINS; michael@0: }, michael@0: michael@0: QueryInterface: function(iid) { michael@0: if (iid.equals(Ci.nsIPluginHost) michael@0: || iid.equals(Ci.nsISupports)) michael@0: return this; michael@0: michael@0: throw Components.results.NS_ERROR_NO_INTERFACE; michael@0: } michael@0: } michael@0: michael@0: var PluginHostFactory = { michael@0: createInstance: function (outer, iid) { michael@0: if (outer != null) michael@0: throw Components.results.NS_ERROR_NO_AGGREGATION; michael@0: return PluginHost.QueryInterface(iid); michael@0: } michael@0: }; michael@0: michael@0: // Don't need the full interface, attempts to call other methods will just michael@0: // throw which is just fine michael@0: var WindowWatcher = { michael@0: openWindow: function(parent, url, name, features, arguments) { michael@0: // Should be called to list the newly blocklisted items michael@0: do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG); michael@0: do_check_neq(gCallback, null); michael@0: michael@0: var args = arguments.wrappedJSObject; michael@0: michael@0: gNewBlocks = []; michael@0: var list = args.list; michael@0: for (let listItem of list) michael@0: gNewBlocks.push(listItem.name + " " + listItem.version); michael@0: michael@0: // Call the callback after the blocklist has finished up michael@0: do_timeout(0, gCallback); michael@0: }, michael@0: michael@0: QueryInterface: function(iid) { michael@0: if (iid.equals(Ci.nsIWindowWatcher) michael@0: || iid.equals(Ci.nsISupports)) michael@0: return this; michael@0: michael@0: throw Components.results.NS_ERROR_NO_INTERFACE; michael@0: } michael@0: } michael@0: michael@0: var WindowWatcherFactory = { michael@0: createInstance: function createInstance(outer, iid) { michael@0: if (outer != null) michael@0: throw Components.results.NS_ERROR_NO_AGGREGATION; michael@0: return WindowWatcher.QueryInterface(iid); michael@0: } michael@0: }; michael@0: var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); michael@0: registrar.registerFactory(Components.ID("{721c3e73-969e-474b-a6dc-059fd288c428}"), michael@0: "Fake Plugin Host", michael@0: "@mozilla.org/plugin/host;1", PluginHostFactory); michael@0: registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"), michael@0: "Fake Window Watcher", michael@0: "@mozilla.org/embedcomp/window-watcher;1", WindowWatcherFactory); michael@0: michael@0: function create_addon(addon) { michael@0: var installrdf = "\n" + michael@0: "\n" + michael@0: "\n" + michael@0: " \n" + michael@0: " " + addon.id + "\n" + michael@0: " " + addon.version + "\n" + michael@0: " \n" + michael@0: " \n" + michael@0: " xpcshell@tests.mozilla.org\n" + michael@0: " 3\n" + michael@0: " 3\n" + michael@0: " \n" + michael@0: " \n" + michael@0: " " + addon.name + "\n" + michael@0: " \n" + michael@0: "\n"; michael@0: var target = gProfD.clone(); michael@0: target.append("extensions"); michael@0: target.append(addon.id); michael@0: target.append("install.rdf"); michael@0: target.create(target.NORMAL_FILE_TYPE, 0644); michael@0: var stream = Components.classes["@mozilla.org/network/file-output-stream;1"] michael@0: .createInstance(Ci.nsIFileOutputStream); michael@0: stream.init(target, 0x04 | 0x08 | 0x20, 0664, 0); // write, create, truncate michael@0: stream.write(installrdf, installrdf.length); michael@0: stream.close(); michael@0: } michael@0: michael@0: /** michael@0: * Checks that items are blocklisted correctly according to the current test. michael@0: * If a lastTest is provided checks that the notification dialog got passed michael@0: * the newly blocked items compared to the previous test. michael@0: */ michael@0: function check_state(test, lastTest, callback) { michael@0: AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) { michael@0: for (var i = 0; i < ADDONS.length; i++) { michael@0: var blocked = addons[i].blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED; michael@0: if (blocked != ADDONS[i][test]) michael@0: do_throw("Blocklist state did not match expected for extension " + (i + 1) + ", test " + test); michael@0: } michael@0: michael@0: for (i = 0; i < PLUGINS.length; i++) { michael@0: if (PLUGINS[i].blocklisted != PLUGINS[i][test]) michael@0: do_throw("Blocklist state did not match expected for plugin " + (i + 1) + ", test " + test); michael@0: } michael@0: michael@0: if (lastTest) { michael@0: var expected = 0; michael@0: for (i = 0; i < ADDONS.length; i++) { michael@0: if (ADDONS[i][test] && !ADDONS[i][lastTest]) { michael@0: if (gNewBlocks.indexOf(ADDONS[i].name + " " + ADDONS[i].version) < 0) michael@0: do_throw("Addon " + (i + 1) + " should have been listed in the blocklist notification for test " + test); michael@0: expected++; michael@0: } michael@0: } michael@0: michael@0: for (i = 0; i < PLUGINS.length; i++) { michael@0: if (PLUGINS[i][test] && !PLUGINS[i][lastTest]) { michael@0: if (gNewBlocks.indexOf(PLUGINS[i].name + " " + PLUGINS[i].version) < 0) michael@0: do_throw("Plugin " + (i + 1) + " should have been listed in the blocklist notification for test " + test); michael@0: expected++; michael@0: } michael@0: } michael@0: michael@0: do_check_eq(expected, gNewBlocks.length); michael@0: } michael@0: do_execute_soon(callback); michael@0: }); michael@0: } michael@0: michael@0: function load_blocklist(file) { michael@0: Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + gPort + "/data/" + file); michael@0: var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"] michael@0: .getService(Ci.nsITimerCallback); michael@0: blocklist.notify(null); michael@0: } michael@0: michael@0: function run_test() { michael@0: // Setup for test michael@0: dump("Setting up tests\n"); michael@0: // Rather than keeping lots of identical add-ons in version control, just michael@0: // write them into the profile. michael@0: for (let addon of ADDONS) michael@0: create_addon(addon); michael@0: michael@0: createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "3", "8"); michael@0: startupManager(); michael@0: michael@0: gTestserver = new HttpServer(); michael@0: gTestserver.registerDirectory("/data/", do_get_file("data")); michael@0: gTestserver.start(-1); michael@0: gPort = gTestserver.identity.primaryPort; michael@0: michael@0: do_test_pending(); michael@0: check_test_pt1(); michael@0: } michael@0: michael@0: /** michael@0: * Checks the initial state is correct michael@0: */ michael@0: function check_test_pt1() { michael@0: dump("Checking pt 1\n"); michael@0: michael@0: AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) { michael@0: for (var i = 0; i < ADDONS.length; i++) { michael@0: if (!addons[i]) michael@0: do_throw("Addon " + (i + 1) + " did not get installed correctly"); michael@0: } michael@0: michael@0: do_execute_soon(function checkstate1() {check_state("start", null, run_test_pt2);}); michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Load the toolkit based blocks michael@0: */ michael@0: function run_test_pt2() { michael@0: dump("Running test pt 2\n"); michael@0: gCallback = check_test_pt2; michael@0: load_blocklist("test_bug449027_toolkit.xml"); michael@0: } michael@0: michael@0: function check_test_pt2() { michael@0: dump("Checking pt 2\n"); michael@0: check_state("toolkitBlocks", "start", run_test_pt3); michael@0: } michael@0: michael@0: /** michael@0: * Load the application based blocks michael@0: */ michael@0: function run_test_pt3() { michael@0: dump("Running test pt 3\n"); michael@0: gCallback = check_test_pt3; michael@0: load_blocklist("test_bug449027_app.xml"); michael@0: } michael@0: michael@0: function check_test_pt3() { michael@0: dump("Checking pt 3\n"); michael@0: check_state("appBlocks", "toolkitBlocks", end_test); michael@0: } michael@0: michael@0: function end_test() { michael@0: gTestserver.stop(do_test_finished); michael@0: }