author | Andrew Swan <aswan@mozilla.com> |
Mon, 26 Nov 2018 13:44:32 -0800 | |
changeset 448841 | 0c715a8f0170fd4b19c4281c269c03f872090648 |
parent 448840 | e3b6db3b34ab06b60ab5b0f9d8d5695df754b7e1 |
child 448842 | e2a7b9a99226012bac933c5315c898ef9379211b |
push id | 110255 |
push user | aswan@mozilla.com |
push date | Thu, 29 Nov 2018 21:53:45 +0000 |
treeherder | mozilla-inbound@0c715a8f0170 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kmag |
bugs | 857456 |
milestone | 65.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
|
--- a/toolkit/mozapps/extensions/AddonManager.jsm +++ b/toolkit/mozapps/extensions/AddonManager.jsm @@ -775,20 +775,16 @@ var AddonManagerInternal = { } logger.debug("Loaded provider scope for " + url + ": " + Object.keys(scope).toSource()); } catch (e) { AddonManagerPrivate.recordException("AMI", "provider " + url + " load failed", e); logger.error("Exception loading default provider \"" + url + "\"", e); } } - // XXX temporary - ChromeUtils.import("resource://gre/modules/addons/BootstrapLoader.jsm"); - AddonManager.addExternalExtensionLoader(BootstrapLoader); - // Load any providers registered in the category manager for (let {entry, value: url} of Services.catMan.enumerateCategory(CATEGORY_PROVIDER_MODULE)) { try { ChromeUtils.import(url, {}); logger.debug(`Loaded provider scope for ${url}`); } catch (e) { AddonManagerPrivate.recordException("AMI", "provider " + url + " load failed", e); logger.error("Exception loading provider " + entry + " from category \"" +
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm +++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm @@ -844,19 +844,16 @@ var AddonTestUtils = { // the AddonManagerInternal.shutdown() promise let shutdownError = XPIscope.XPIDatabase._saveError; AddonManagerPrivate.unregisterProvider(XPIscope.XPIProvider); Cu.unload("resource://gre/modules/addons/XPIProvider.jsm"); Cu.unload("resource://gre/modules/addons/XPIDatabase.jsm"); Cu.unload("resource://gre/modules/addons/XPIInstall.jsm"); - // XXX - Cu.unload("resource://gre/modules/addons/BootstrapLoader.jsm"); - let ExtensionScope = ChromeUtils.import("resource://gre/modules/Extension.jsm", null); ChromeUtils.defineModuleGetter(ExtensionScope, "XPIProvider", "resource://gre/modules/addons/XPIProvider.jsm"); if (shutdownError) throw shutdownError; return true;
deleted file mode 100644 --- a/toolkit/mozapps/extensions/internal/BootstrapLoader.jsm +++ /dev/null @@ -1,363 +0,0 @@ - -"use strict"; - -var EXPORTED_SYMBOLS = ["BootstrapLoader"]; - -ChromeUtils.import("resource://gre/modules/AddonManager.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetters(this, { - AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm", - Blocklist: "resource://gre/modules/Blocklist.jsm", - ConsoleAPI: "resource://gre/modules/Console.jsm", - InstallRDF: "resource://gre/modules/addons/RDFManifestConverter.jsm", - Services: "resource://gre/modules/Services.jsm", -}); - -XPCOMUtils.defineLazyGetter(this, "BOOTSTRAP_REASONS", () => { - const {XPIProvider} = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); - return XPIProvider.BOOTSTRAP_REASONS; -}); - -ChromeUtils.import("resource://gre/modules/Log.jsm"); -var logger = Log.repository.getLogger("addons.bootstrap"); - -/** - * Valid IDs fit this pattern. - */ -var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i; - -// Properties that exist in the install manifest -const PROP_METADATA = ["id", "version", "type", "internalName", "updateURL", - "optionsURL", "optionsType", "aboutURL", "iconURL"]; -const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"]; -const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"]; - -// Map new string type identifiers to old style nsIUpdateItem types. -// Retired values: -// 32 = multipackage xpi file -// 8 = locale -// 256 = apiextension -// 128 = experiment -// theme = 4 -const TYPES = { - extension: 2, - dictionary: 64, -}; - -const COMPATIBLE_BY_DEFAULT_TYPES = { - extension: true, - dictionary: true, -}; - -const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); - -function isXPI(filename) { - let ext = filename.slice(-4).toLowerCase(); - return ext === ".xpi" || ext === ".zip"; -} - -/** - * Gets an nsIURI for a file within another file, either a directory or an XPI - * file. If aFile is a directory then this will return a file: URI, if it is an - * XPI file then it will return a jar: URI. - * - * @param {nsIFile} aFile - * The file containing the resources, must be either a directory or an - * XPI file - * @param {string} aPath - * The path to find the resource at, "/" separated. If aPath is empty - * then the uri to the root of the contained files will be returned - * @returns {nsIURI} - * An nsIURI pointing at the resource - */ -function getURIForResourceInFile(aFile, aPath) { - if (!isXPI(aFile.leafName)) { - let resource = aFile.clone(); - if (aPath) - aPath.split("/").forEach(part => resource.append(part)); - - return Services.io.newFileURI(resource); - } - - return buildJarURI(aFile, aPath); -} - -/** - * Creates a jar: URI for a file inside a ZIP file. - * - * @param {nsIFile} aJarfile - * The ZIP file as an nsIFile - * @param {string} aPath - * The path inside the ZIP file - * @returns {nsIURI} - * An nsIURI for the file - */ -function buildJarURI(aJarfile, aPath) { - let uri = Services.io.newFileURI(aJarfile); - uri = "jar:" + uri.spec + "!/" + aPath; - return Services.io.newURI(uri); -} - -var BootstrapLoader = { - name: "bootstrap", - manifestFile: "install.rdf", - async loadManifest(pkg) { - /** - * Reads locale properties from either the main install manifest root or - * an em:localized section in the install manifest. - * - * @param {Object} aSource - * The resource to read the properties from. - * @param {boolean} isDefault - * True if the locale is to be read from the main install manifest - * root - * @param {string[]} aSeenLocales - * An array of locale names already seen for this install manifest. - * Any locale names seen as a part of this function will be added to - * this array - * @returns {Object} - * an object containing the locale properties - */ - function readLocale(aSource, isDefault, aSeenLocales) { - let locale = {}; - if (!isDefault) { - locale.locales = []; - for (let localeName of aSource.locales || []) { - if (!localeName) { - logger.warn("Ignoring empty locale in localized properties"); - continue; - } - if (aSeenLocales.includes(localeName)) { - logger.warn("Ignoring duplicate locale in localized properties"); - continue; - } - aSeenLocales.push(localeName); - locale.locales.push(localeName); - } - - if (locale.locales.length == 0) { - logger.warn("Ignoring localized properties with no listed locales"); - return null; - } - } - - for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) { - if (hasOwnProperty(aSource, prop)) { - locale[prop] = aSource[prop]; - } - } - - return locale; - } - - let manifestData = await pkg.readString("install.rdf"); - let manifest = InstallRDF.loadFromString(manifestData).decode(); - - let addon = new AddonInternal(); - for (let prop of PROP_METADATA) { - if (hasOwnProperty(manifest, prop)) { - addon[prop] = manifest[prop]; - } - } - - if (!addon.type) { - addon.type = "extension"; - } else { - let type = addon.type; - addon.type = null; - for (let name in TYPES) { - if (TYPES[name] == type) { - addon.type = name; - break; - } - } - } - - if (!(addon.type in TYPES)) - throw new Error("Install manifest specifies unknown type: " + addon.type); - - if (!addon.id) - throw new Error("No ID in install manifest"); - if (!gIDTest.test(addon.id)) - throw new Error("Illegal add-on ID " + addon.id); - if (!addon.version) - throw new Error("No version in install manifest"); - - addon.strictCompatibility = (!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || - manifest.strictCompatibility == "true"); - - // Only read these properties for extensions. - if (addon.type == "extension") { - if (manifest.bootstrap != "true") { - throw new Error("Non-restartless extensions no longer supported"); - } - - if (addon.optionsType && - addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE_BROWSER && - addon.optionsType != AddonManager.OPTIONS_TYPE_TAB) { - throw new Error("Install manifest specifies unknown optionsType: " + addon.optionsType); - } - } else { - // Convert legacy dictionaries into a format the WebExtension - // dictionary loader can process. - if (addon.type === "dictionary") { - addon.loader = null; - let dictionaries = {}; - await pkg.iterFiles(({path}) => { - let match = /^dictionaries\/([^\/]+)\.dic$/.exec(path); - if (match) { - let lang = match[1].replace(/_/g, "-"); - dictionaries[lang] = match[0]; - } - }); - addon.startupData = {dictionaries}; - } - - // Only extensions are allowed to provide an optionsURL, optionsType, - // optionsBrowserStyle, or aboutURL. For all other types they are silently ignored - addon.aboutURL = null; - addon.optionsBrowserStyle = null; - addon.optionsType = null; - addon.optionsURL = null; - } - - addon.defaultLocale = readLocale(manifest, true); - - let seenLocales = []; - addon.locales = []; - for (let localeData of manifest.localized || []) { - let locale = readLocale(localeData, false, seenLocales); - if (locale) - addon.locales.push(locale); - } - - let dependencies = new Set(manifest.dependencies); - addon.dependencies = Object.freeze(Array.from(dependencies)); - - let seenApplications = []; - addon.targetApplications = []; - for (let targetApp of manifest.targetApplications || []) { - if (!targetApp.id || !targetApp.minVersion || - !targetApp.maxVersion) { - logger.warn("Ignoring invalid targetApplication entry in install manifest"); - continue; - } - if (seenApplications.includes(targetApp.id)) { - logger.warn("Ignoring duplicate targetApplication entry for " + targetApp.id + - " in install manifest"); - continue; - } - seenApplications.push(targetApp.id); - addon.targetApplications.push(targetApp); - } - - // Note that we don't need to check for duplicate targetPlatform entries since - // the RDF service coalesces them for us. - addon.targetPlatforms = []; - for (let targetPlatform of manifest.targetPlatforms || []) { - let platform = { - os: null, - abi: null, - }; - - let pos = targetPlatform.indexOf("_"); - if (pos != -1) { - platform.os = targetPlatform.substring(0, pos); - platform.abi = targetPlatform.substring(pos + 1); - } else { - platform.os = targetPlatform; - } - - addon.targetPlatforms.push(platform); - } - - addon.userDisabled = false; - addon.softDisabled = addon.blocklistState == Blocklist.STATE_SOFTBLOCKED; - addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT; - - addon.userPermissions = null; - - addon.icons = {}; - if (await pkg.hasResource("icon.png")) { - addon.icons[32] = "icon.png"; - addon.icons[48] = "icon.png"; - } - - if (await pkg.hasResource("icon64.png")) { - addon.icons[64] = "icon64.png"; - } - - return addon; - }, - - loadScope(addon, file) { - let uri = getURIForResourceInFile(file, "bootstrap.js").spec; - let principal = Services.scriptSecurityManager.getSystemPrincipal(); - - let sandbox = new Cu.Sandbox(principal, { - sandboxName: uri, - addonId: addon.id, - wantGlobalProperties: ["ChromeUtils"], - metadata: { addonID: addon.id, URI: uri }, - }); - - try { - Object.assign(sandbox, BOOTSTRAP_REASONS); - - XPCOMUtils.defineLazyGetter(sandbox, "console", () => - new ConsoleAPI({ consoleID: `addon/${addon.id}` })); - - Services.scriptloader.loadSubScript(uri, sandbox); - } catch (e) { - logger.warn(`Error loading bootstrap.js for ${addon.id}`, e); - } - - function findMethod(name) { - if (sandbox.name) { - return sandbox.name; - } - - try { - let method = Cu.evalInSandbox(name, sandbox); - return method; - } catch (err) { } - - return () => { - logger.warn(`Add-on ${addon.id} is missing bootstrap method ${name}`); - }; - } - - let install = findMethod("install"); - let uninstall = findMethod("uninstall"); - let startup = findMethod("startup"); - let shutdown = findMethod("shutdown"); - - return { - install: (...args) => install(...args), - uninstall: (...args) => uninstall(...args), - - startup(...args) { - if (addon.type == "extension") { - logger.debug(`Registering manifest for ${file.path}\n`); - Components.manager.addBootstrappedManifestLocation(file); - } - return startup(...args); - }, - - shutdown(data, reason) { - try { - return shutdown(data, reason); - } catch (err) { - throw err; - } finally { - if (reason != BOOTSTRAP_REASONS.APP_SHUTDOWN) { - logger.debug(`Removing manifest for ${file.path}\n`); - Components.manager.removeBootstrappedManifestLocation(file); - } - } - }, - }; - }, -}; -
--- a/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm +++ b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm @@ -1,28 +1,26 @@ /* 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"; -var EXPORTED_SYMBOLS = ["InstallRDF", "UpdateRDFConverter"]; +var EXPORTED_SYMBOLS = ["UpdateRDFConverter"]; ChromeUtils.defineModuleGetter(this, "RDFDataSource", "resource://gre/modules/addons/RDFDataSource.jsm"); ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); const PREFIX_ITEM = "urn:mozilla:item:"; const PREFIX_EXTENSION = "urn:mozilla:extension:"; const PREFIX_THEME = "urn:mozilla:theme:"; const TOOLKIT_ID = "toolkit@mozilla.org"; -const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; - function EM_R(aProperty) { return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; } function getValue(literal) { return literal && literal.getValue(); } @@ -47,85 +45,16 @@ class Manifest { return new this(RDFDataSource.loadFromBuffer(buffer)); } static async loadFromFile(uri) { return new this(await RDFDataSource.loadFromFile(uri)); } } -class InstallRDF extends Manifest { - _readProps(source, obj, props) { - for (let prop of props) { - let val = getProperty(source, prop); - if (val != null) { - obj[prop] = val; - } - } - } - - _readArrayProp(source, obj, prop, target, decode = getValue) { - let result = Array.from(source.getObjects(EM_R(prop)), - target => decode(target)); - if (result.length) { - obj[target] = result; - } - } - - _readArrayProps(source, obj, props, decode = getValue) { - for (let [prop, target] of Object.entries(props)) { - this._readArrayProp(source, obj, prop, target, decode); - } - } - - _readLocaleStrings(source, obj) { - this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]); - this._readArrayProps(source, obj, { - locale: "locales", - developer: "developers", - translator: "translators", - contributor: "contributors", - }); - } - - decode() { - let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT); - let result = {}; - - let props = ["id", "version", "type", "updateURL", "optionsURL", - "optionsType", "aboutURL", "iconURL", - "bootstrap", "unpack", "strictCompatibility"]; - this._readProps(root, result, props); - - let decodeTargetApplication = source => { - let app = {}; - this._readProps(source, app, ["id", "minVersion", "maxVersion"]); - return app; - }; - - let decodeLocale = source => { - let localized = {}; - this._readLocaleStrings(source, localized); - return localized; - }; - - this._readLocaleStrings(root, result); - - this._readArrayProps(root, result, {"targetPlatform": "targetPlatforms"}); - this._readArrayProps(root, result, {"targetApplication": "targetApplications"}, - decodeTargetApplication); - this._readArrayProps(root, result, {"localized": "localized"}, - decodeLocale); - this._readArrayProps(root, result, {"dependency": "dependencies"}, - source => getProperty(source, "id")); - - return result; - } -} - class UpdateRDF extends Manifest { decode() { let addons = {}; let result = {addons}; for (let resource of this.ds.getAllResources()) { let id; let uri = resource.getURI();
--- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -3,17 +3,16 @@ # 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/. EXTRA_JS_MODULES.addons += [ 'AddonRepository.jsm', 'AddonSettings.jsm', 'AddonUpdateChecker.jsm', - 'BootstrapLoader.jsm', 'Content.js', 'GMPProvider.jsm', 'LightweightThemeImageOptimizer.jsm', 'LightweightThemePersister.jsm', 'ProductAddonChecker.jsm', 'RDFDataSource.jsm', 'RDFManifestConverter.jsm', 'XPIDatabase.jsm',
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bootstrap.js +++ /dev/null @@ -1,1183 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -const APP_STARTUP = 1; -const APP_SHUTDOWN = 2; -const ADDON_ENABLE = 3; -const ADDON_DISABLE = 4; -const ADDON_INSTALL = 5; -const ADDON_UNINSTALL = 6; -const ADDON_UPGRADE = 7; -const ADDON_DOWNGRADE = 8; - -const ID1 = "bootstrap1@tests.mozilla.org"; -const ID2 = "bootstrap2@tests.mozilla.org"; - -// This verifies that bootstrappable add-ons can be used without restarts. -ChromeUtils.import("resource://gre/modules/Services.jsm"); - -// Enable loading extensions from the user scopes -Services.prefs.setIntPref("extensions.enabledScopes", - AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_USER); - -BootstrapMonitor.init(); - -createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - -const profileDir = gProfD.clone(); -profileDir.append("extensions"); -const userExtDir = gProfD.clone(); -userExtDir.append("extensions2"); -userExtDir.append(gAppInfo.ID); -registerDirectory("XREUSysExt", userExtDir.parent); - - -const ADDONS = { - test_bootstrap1_1: { - "install.rdf": { - id: "bootstrap1@tests.mozilla.org", - - name: "Test Bootstrap 1", - - iconURL: "chrome://foo/skin/icon.png", - aboutURL: "chrome://foo/content/about.xul", - optionsURL: "chrome://foo/content/options.xul", - }, - "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS, - }, - test_bootstrap1_2: { - "install.rdf": { - id: "bootstrap1@tests.mozilla.org", - version: "2.0", - - name: "Test Bootstrap 1", - }, - "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS, - }, - test_bootstrap1_3: { - "install.rdf": { - id: "bootstrap1@tests.mozilla.org", - version: "3.0", - - name: "Test Bootstrap 1", - - targetApplications: [{ - id: "undefined", - minVersion: "1", - maxVersion: "1"}], - }, - "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS, - }, - test_bootstrap2_1: { - "install.rdf": { - id: "bootstrap2@tests.mozilla.org", - }, - "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS, - }, -}; - -var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]}); - -const XPIS = {}; -for (let [name, addon] of Object.entries(ADDONS)) { - XPIS[name] = AddonTestUtils.createTempXPIFile(addon); - testserver.registerFile(`/addons/${name}.xpi`, XPIS[name]); -} - - -function getStartupReason() { - let info = BootstrapMonitor.started.get(ID1); - return info ? info.reason : undefined; -} - -function getShutdownReason() { - let info = BootstrapMonitor.stopped.get(ID1); - return info ? info.reason : undefined; -} - -function getInstallReason() { - let info = BootstrapMonitor.installed.get(ID1); - return info ? info.reason : undefined; -} - -function getUninstallReason() { - let info = BootstrapMonitor.uninstalled.get(ID1); - return info ? info.reason : undefined; -} - -function getStartupOldVersion() { - let info = BootstrapMonitor.started.get(ID1); - return info ? info.data.oldVersion : undefined; -} - -function getShutdownNewVersion() { - let info = BootstrapMonitor.stopped.get(ID1); - return info ? info.data.newVersion : undefined; -} - -function getInstallOldVersion() { - let info = BootstrapMonitor.installed.get(ID1); - return info ? info.data.oldVersion : undefined; -} - -function getUninstallNewVersion() { - let info = BootstrapMonitor.uninstalled.get(ID1); - return info ? info.data.newVersion : undefined; -} - -async function checkBootstrappedPref() { - let XPIScope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); - - let data = new Map(); - for (let entry of XPIScope.XPIStates.enabledAddons()) { - data.set(entry.id, entry); - } - - let addons = await AddonManager.getAddonsByTypes(["extension"]); - for (let addon of addons) { - if (!addon.id.endsWith("@tests.mozilla.org")) - continue; - if (!addon.isActive) - continue; - if (addon.operationsRequiringRestart != AddonManager.OP_NEEDS_RESTART_NONE) - continue; - - ok(data.has(addon.id)); - let addonData = data.get(addon.id); - data.delete(addon.id); - - equal(addonData.version, addon.version); - equal(addonData.type, addon.type); - let file = addon.getResourceURI().QueryInterface(Ci.nsIFileURL).file; - equal(addonData.path, file.path); - } - equal(data.size, 0); -} - - -add_task(async function run_test() { - promiseStartupManager(); - - ok(!gExtensionsJSON.exists()); - ok(!gAddonStartup.exists()); -}); - -// Tests that installing doesn't require a restart -add_task(async function test_1() { - prepare_test({}, [ - "onNewInstall", - ]); - - let install = await AddonManager.getInstallForFile(XPIS.test_bootstrap1_1); - ensure_test_completed(); - - notEqual(install, null); - equal(install.type, "extension"); - equal(install.version, "1.0"); - equal(install.name, "Test Bootstrap 1"); - equal(install.state, AddonManager.STATE_DOWNLOADED); - notEqual(install.addon.syncGUID, null); - equal(install.addon.operationsRequiringRestart & - AddonManager.OP_NEEDS_RESTART_INSTALL, 0); - do_check_not_in_crash_annotation(ID1, "1.0"); - - let addon = install.addon; - - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], function() { - // startup should not have been called yet. - BootstrapMonitor.checkAddonNotStarted(ID1); - resolve(); - }); - install.install(); - }), - ]); - - await checkBootstrappedPref(); - let installSyncGUID = addon.syncGUID; - - let installs = await AddonManager.getAllInstalls(); - // There should be no active installs now since the install completed and - // doesn't require a restart. - equal(installs.length, 0); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - notEqual(b1.syncGUID, null); - equal(b1.syncGUID, installSyncGUID); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), ADDON_INSTALL); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "1.0"); - - let dir = do_get_addon_root_uri(profileDir, ID1); - equal(b1.getResourceURI("bootstrap.js").spec, dir + "bootstrap.js"); -}); - -// Tests that disabling doesn't require a restart -add_task(async function test_2() { - let b1 = await AddonManager.getAddonByID(ID1); - prepare_test({ - [ID1]: [ - ["onDisabling", false], - "onDisabled", - ], - }); - - equal(b1.operationsRequiringRestart & - AddonManager.OP_NEEDS_RESTART_DISABLE, 0); - await b1.disable(); - ensure_test_completed(); - - await new Promise(executeSoon); - - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(b1.userDisabled); - ok(!b1.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - equal(getShutdownReason(), ADDON_DISABLE); - equal(getShutdownNewVersion(), undefined); - do_check_not_in_crash_annotation(ID1, "1.0"); - - let newb1 = await AddonManager.getAddonByID(ID1); - notEqual(newb1, null); - equal(newb1.version, "1.0"); - ok(!newb1.appDisabled); - ok(newb1.userDisabled); - ok(!newb1.isActive); - - await checkBootstrappedPref(); -}); - -// Test that restarting doesn't accidentally re-enable -add_task(async function test_3() { - await promiseShutdownManager(); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - equal(getShutdownReason(), ADDON_DISABLE); - equal(getShutdownNewVersion(), undefined); - - await promiseStartupManager(); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - equal(getShutdownReason(), ADDON_DISABLE); - equal(getShutdownNewVersion(), undefined); - do_check_not_in_crash_annotation(ID1, "1.0"); - - ok(gAddonStartup.exists()); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(b1.userDisabled); - ok(!b1.isActive); - - await checkBootstrappedPref(); -}); - -// Tests that enabling doesn't require a restart -add_task(async function test_4() { - let b1 = await AddonManager.getAddonByID(ID1); - prepare_test({ - [ID1]: [ - ["onEnabling", false], - "onEnabled", - ], - }); - - equal(b1.operationsRequiringRestart & - AddonManager.OP_NEEDS_RESTART_ENABLE, 0); - await b1.enable(); - ensure_test_completed(); - - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), ADDON_ENABLE); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "1.0"); - - let newb1 = await AddonManager.getAddonByID(ID1); - notEqual(newb1, null); - equal(newb1.version, "1.0"); - ok(!newb1.appDisabled); - ok(!newb1.userDisabled); - ok(newb1.isActive); - - await checkBootstrappedPref(); -}); - -// Tests that a restart shuts down and restarts the add-on -add_task(async function test_5() { - await promiseShutdownManager(); - // By the time we've shut down, the database must have been written - ok(gExtensionsJSON.exists()); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - equal(getShutdownReason(), APP_SHUTDOWN); - equal(getShutdownNewVersion(), undefined); - do_check_not_in_crash_annotation(ID1, "1.0"); - await promiseStartupManager(); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), APP_STARTUP); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "1.0"); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - - await checkBootstrappedPref(); -}); - -// Tests that installing an upgrade doesn't require a restart -add_task(async function test_6() { - prepare_test({}, [ - "onNewInstall", - ]); - - let install = await AddonManager.getInstallForFile(XPIS.test_bootstrap1_2); - ensure_test_completed(); - - notEqual(install, null); - equal(install.type, "extension"); - equal(install.version, "2.0"); - equal(install.name, "Test Bootstrap 1"); - equal(install.state, AddonManager.STATE_DOWNLOADED); - - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], resolve); - install.install(); - }), - ]); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "2.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonStarted(ID1, "2.0"); - equal(getStartupReason(), ADDON_UPGRADE); - equal(getInstallOldVersion(), 1); - equal(getStartupOldVersion(), 1); - equal(getShutdownReason(), ADDON_UPGRADE); - equal(getShutdownNewVersion(), 2); - equal(getUninstallNewVersion(), 2); - do_check_not_in_crash_annotation(ID1, "1.0"); - do_check_in_crash_annotation(ID1, "2.0"); - - await checkBootstrappedPref(); -}); - -// Tests that uninstalling doesn't require a restart -add_task(async function test_7() { - let b1 = await AddonManager.getAddonByID(ID1); - prepare_test({ - [ID1]: [ - ["onUninstalling", false], - "onUninstalled", - ], - }); - - equal(b1.operationsRequiringRestart & - AddonManager.OP_NEEDS_RESTART_UNINSTALL, 0); - await b1.uninstall(); - - await checkBootstrappedPref(); - - ensure_test_completed(); - BootstrapMonitor.checkAddonNotInstalled(ID1); - BootstrapMonitor.checkAddonNotStarted(ID1); - equal(getShutdownReason(), ADDON_UNINSTALL); - equal(getShutdownNewVersion(), undefined); - do_check_not_in_crash_annotation(ID1, "2.0"); - - b1 = await AddonManager.getAddonByID(ID1); - equal(b1, null); - - await promiseRestartManager(); - - let newb1 = await AddonManager.getAddonByID(ID1); - equal(newb1, null); - - await checkBootstrappedPref(); -}); - -// Test that a bootstrapped extension dropped into the profile loads properly -// on startup and doesn't cause an EM restart -add_task(async function test_8() { - await promiseShutdownManager(); - - await manuallyInstall(XPIS.test_bootstrap1_1, profileDir, ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), ADDON_INSTALL); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "1.0"); - - await checkBootstrappedPref(); -}); - -// Test that items detected as removed during startup get removed properly -add_task(async function test_9() { - await promiseShutdownManager(); - - manuallyUninstall(profileDir, ID1); - BootstrapMonitor.clear(ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - equal(b1, null); - do_check_not_in_crash_annotation(ID1, "1.0"); - - await checkBootstrappedPref(); -}); - - -// Tests that installing a downgrade sends the right reason -add_task(async function test_10() { - prepare_test({}, [ - "onNewInstall", - ]); - - let install = await AddonManager.getInstallForFile(XPIS.test_bootstrap1_2); - ensure_test_completed(); - - notEqual(install, null); - equal(install.type, "extension"); - equal(install.version, "2.0"); - equal(install.name, "Test Bootstrap 1"); - equal(install.state, AddonManager.STATE_DOWNLOADED); - do_check_not_in_crash_annotation(ID1, "2.0"); - - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], resolve); - install.install(); - }), - ]); - - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "2.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonStarted(ID1, "2.0"); - equal(getStartupReason(), ADDON_INSTALL); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "2.0"); - - prepare_test({}, [ - "onNewInstall", - ]); - - install = await AddonManager.getInstallForFile(XPIS.test_bootstrap1_1); - ensure_test_completed(); - - notEqual(install, null); - equal(install.type, "extension"); - equal(install.version, "1.0"); - equal(install.name, "Test Bootstrap 1"); - equal(install.state, AddonManager.STATE_DOWNLOADED); - - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], resolve); - install.install(); - }), - ]); - - b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), ADDON_DOWNGRADE); - equal(getInstallOldVersion(), 2); - equal(getStartupOldVersion(), 2); - equal(getShutdownReason(), ADDON_DOWNGRADE); - equal(getShutdownNewVersion(), 1); - equal(getUninstallNewVersion(), 1); - do_check_in_crash_annotation(ID1, "1.0"); - do_check_not_in_crash_annotation(ID1, "2.0"); - - await checkBootstrappedPref(); -}); - -// Tests that uninstalling a disabled add-on still calls the uninstall method -add_task(async function test_11() { - let b1 = await AddonManager.getAddonByID(ID1); - prepare_test({ - [ID1]: [ - ["onDisabling", false], - "onDisabled", - ["onUninstalling", false], - "onUninstalled", - ], - }); - - await b1.disable(); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - equal(getShutdownReason(), ADDON_DISABLE); - equal(getShutdownNewVersion(), undefined); - do_check_not_in_crash_annotation(ID1, "1.0"); - - await b1.uninstall(); - - ensure_test_completed(); - BootstrapMonitor.checkAddonNotInstalled(ID1); - BootstrapMonitor.checkAddonNotStarted(ID1); - do_check_not_in_crash_annotation(ID1, "1.0"); - - await checkBootstrappedPref(); -}); - -// Tests that bootstrapped extensions are correctly loaded even if the app is -// upgraded at the same time -add_task(async function test_12() { - await promiseShutdownManager(); - - await manuallyInstall(XPIS.test_bootstrap1_1, profileDir, ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), ADDON_INSTALL); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "1.0"); - - await b1.uninstall(); - - await promiseRestartManager(); - await checkBootstrappedPref(); -}); - - -// Tests that installing a bootstrapped extension with an invalid application -// entry doesn't call it's startup method -add_task(async function test_13() { - prepare_test({}, [ - "onNewInstall", - ]); - - let install = await AddonManager.getInstallForFile(XPIS.test_bootstrap1_3); - ensure_test_completed(); - - notEqual(install, null); - equal(install.type, "extension"); - equal(install.version, "3.0"); - equal(install.name, "Test Bootstrap 1"); - equal(install.state, AddonManager.STATE_DOWNLOADED); - do_check_not_in_crash_annotation(ID1, "3.0"); - - await new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], resolve); - install.install(); - }); - - let installs = await AddonManager.getAllInstalls(); - - // There should be no active installs now since the install completed and - // doesn't require a restart. - equal(installs.length, 0); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "3.0"); - ok(b1.appDisabled); - ok(!b1.userDisabled); - ok(!b1.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "3.0"); // We call install even for disabled add-ons - BootstrapMonitor.checkAddonNotStarted(ID1); // Should not have called startup though - do_check_not_in_crash_annotation(ID1, "3.0"); - - await promiseRestartManager(); - - b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "3.0"); - ok(b1.appDisabled); - ok(!b1.userDisabled); - ok(!b1.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "3.0"); // We call install even for disabled add-ons - BootstrapMonitor.checkAddonNotStarted(ID1); // Should not have called startup though - do_check_not_in_crash_annotation(ID1, "3.0"); - - await checkBootstrappedPref(); - await b1.uninstall(); -}); - -// Tests that a bootstrapped extension with an invalid target application entry -// does not get loaded when detected during startup -add_task(async function test_14() { - await promiseRestartManager(); - - await promiseShutdownManager(); - - await manuallyInstall(XPIS.test_bootstrap1_3, profileDir, ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "3.0"); - ok(b1.appDisabled); - ok(!b1.userDisabled); - ok(!b1.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "3.0"); // We call install even for disabled add-ons - BootstrapMonitor.checkAddonNotStarted(ID1); // Should not have called startup though - do_check_not_in_crash_annotation(ID1, "3.0"); - - await checkBootstrappedPref(); - await b1.uninstall(); -}); - -// Tests that upgrading a disabled bootstrapped extension still calls uninstall -// and install but doesn't startup the new version -add_task(async function test_15() { - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - promiseInstallFile(XPIS.test_bootstrap1_1), - ]); - - let b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - - await b1.disable(); - ok(!b1.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - - prepare_test({}, [ - "onNewInstall", - ]); - - let install = await AddonManager.getInstallForFile(XPIS.test_bootstrap1_2); - ensure_test_completed(); - - notEqual(install, null); - ok(install.addon.userDisabled); - - await new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], resolve); - install.install(); - }); - - b1 = await AddonManager.getAddonByID(ID1); - notEqual(b1, null); - equal(b1.version, "2.0"); - ok(!b1.appDisabled); - ok(b1.userDisabled); - ok(!b1.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - - await checkBootstrappedPref(); - await promiseRestartManager(); - - let b1_2 = await AddonManager.getAddonByID(ID1); - notEqual(b1_2, null); - equal(b1_2.version, "2.0"); - ok(!b1_2.appDisabled); - ok(b1_2.userDisabled); - ok(!b1_2.isActive); - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - - await b1_2.uninstall(); -}); - -// Tests that bootstrapped extensions don't get loaded when in safe mode -add_task(async function test_16() { - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - promiseInstallFile(XPIS.test_bootstrap1_1), - ]); - - let b1 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - ok(b1.isActive); - ok(!b1.isSystem); - equal(b1.iconURL, "chrome://foo/skin/icon.png"); - equal(b1.aboutURL, "chrome://foo/content/about.xul"); - equal(b1.optionsURL, "chrome://foo/content/options.xul"); - - await promiseShutdownManager(); - - // Should have stopped - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - - gAppInfo.inSafeMode = true; - await promiseStartupManager(); - - let b1_2 = await AddonManager.getAddonByID(ID1); - // Should still be stopped - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - ok(!b1_2.isActive); - equal(b1_2.iconURL, null); - equal(b1_2.aboutURL, null); - equal(b1_2.optionsURL, null); - - await promiseShutdownManager(); - gAppInfo.inSafeMode = false; - await promiseStartupManager(); - - // Should have started - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - - let b1_3 = await AddonManager.getAddonByID(ID1); - await b1_3.uninstall(); -}); - -// Check that a bootstrapped extension in a non-profile location is loaded -add_task(async function test_17() { - await promiseShutdownManager(); - - await manuallyInstall(XPIS.test_bootstrap1_1, userExtDir, ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(b1.isActive); - ok(!b1.isSystem); - - await checkBootstrappedPref(); -}); - -// Check that installing a new bootstrapped extension in the profile replaces -// the existing one -add_task(async function test_18() { - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID1), - promiseInstallFile(XPIS.test_bootstrap1_2), - ]); - - let b1 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonStarted(ID1, "2.0"); - notEqual(b1, null); - equal(b1.version, "2.0"); - ok(b1.isActive); - ok(!b1.isSystem); - - equal(getShutdownReason(), ADDON_UPGRADE); - equal(getUninstallReason(), ADDON_UPGRADE); - equal(getInstallReason(), ADDON_UPGRADE); - equal(getStartupReason(), ADDON_UPGRADE); - - equal(getShutdownNewVersion(), 2); - equal(getUninstallNewVersion(), 2); - equal(getInstallOldVersion(), 1); - equal(getStartupOldVersion(), 1); - - await checkBootstrappedPref(); -}); - -// Check that uninstalling the profile version reveals the non-profile one -add_task(async function test_19() { - let b1 = await AddonManager.getAddonByID(ID1); - // The revealed add-on gets activated asynchronously - await new Promise(resolve => { - prepare_test({ - [ID1]: [ - ["onUninstalling", false], - "onUninstalled", - ["onInstalling", false], - "onInstalled", - ], - }, [], resolve); - - b1.uninstall(); - }); - - b1 = await AddonManager.getAddonByID(ID1); - // Should have reverted to the older version - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(b1.isActive); - ok(!b1.isSystem); - - equal(getShutdownReason(), ADDON_DOWNGRADE); - equal(getUninstallReason(), ADDON_DOWNGRADE); - equal(getInstallReason(), ADDON_DOWNGRADE); - equal(getStartupReason(), ADDON_DOWNGRADE); - - equal(getShutdownNewVersion(), "1.0"); - equal(getUninstallNewVersion(), "1.0"); - equal(getInstallOldVersion(), "2.0"); - equal(getStartupOldVersion(), "2.0"); - - await checkBootstrappedPref(); -}); - -// Check that a new profile extension detected at startup replaces the non-profile -// one -add_task(async function test_20() { - await promiseShutdownManager(); - - await manuallyInstall(XPIS.test_bootstrap1_2, profileDir, ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonStarted(ID1, "2.0"); - notEqual(b1, null); - equal(b1.version, "2.0"); - ok(b1.isActive); - ok(!b1.isSystem); - - equal(getShutdownReason(), APP_SHUTDOWN); - equal(getUninstallReason(), ADDON_UPGRADE); - equal(getInstallReason(), ADDON_UPGRADE); - equal(getStartupReason(), APP_STARTUP); - - equal(getShutdownNewVersion(), undefined); - equal(getUninstallNewVersion(), 2); - equal(getInstallOldVersion(), 1); - equal(getStartupOldVersion(), undefined); -}); - -// Check that a detected removal reveals the non-profile one -add_task(async function test_21() { - await promiseShutdownManager(); - - equal(getShutdownReason(), APP_SHUTDOWN); - equal(getShutdownNewVersion(), undefined); - - manuallyUninstall(profileDir, ID1); - BootstrapMonitor.clear(ID1); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(b1.isActive); - ok(!b1.isSystem); - - // This won't be set as the bootstrap script was gone so we couldn't - // uninstall it properly - equal(getUninstallReason(), undefined); - equal(getUninstallNewVersion(), undefined); - - equal(getInstallReason(), ADDON_DOWNGRADE); - equal(getInstallOldVersion(), 2); - - equal(getStartupReason(), APP_STARTUP); - equal(getStartupOldVersion(), undefined); - - await checkBootstrappedPref(); - await promiseShutdownManager(); - - manuallyUninstall(userExtDir, ID1); - BootstrapMonitor.clear(ID1); - - await promiseStartupManager(); -}); - -// Check that an upgrade from the filesystem is detected and applied correctly -add_task(async function test_22() { - await promiseShutdownManager(); - - let file = await manuallyInstall(XPIS.test_bootstrap1_1, profileDir, ID1); - if (file.isDirectory()) - file.append("install.rdf"); - - // Make it look old so changes are detected - setExtensionModifiedTime(file, file.lastModifiedTime - 5000); - - await promiseStartupManager(); - - let b1 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(b1.isActive); - ok(!b1.isSystem); - - await promiseShutdownManager(); - - equal(getShutdownReason(), APP_SHUTDOWN); - equal(getShutdownNewVersion(), undefined); - - manuallyUninstall(profileDir, ID1); - BootstrapMonitor.clear(ID1); - await manuallyInstall(XPIS.test_bootstrap1_2, profileDir, ID1); - - await promiseStartupManager(); - - let b1_2 = await AddonManager.getAddonByID(ID1); - // Should have installed and started - BootstrapMonitor.checkAddonInstalled(ID1, "2.0"); - BootstrapMonitor.checkAddonStarted(ID1, "2.0"); - notEqual(b1_2, null); - equal(b1_2.version, "2.0"); - ok(b1_2.isActive); - ok(!b1_2.isSystem); - - // This won't be set as the bootstrap script was gone so we couldn't - // uninstall it properly - equal(getUninstallReason(), undefined); - equal(getUninstallNewVersion(), undefined); - - equal(getInstallReason(), ADDON_UPGRADE); - equal(getInstallOldVersion(), 1); - equal(getStartupReason(), APP_STARTUP); - equal(getStartupOldVersion(), undefined); - - await checkBootstrappedPref(); - await b1_2.uninstall(); -}); - - -// Tests that installing from a URL doesn't require a restart -add_task(async function test_23() { - prepare_test({}, [ - "onNewInstall", - ]); - - let url = "http://example.com/addons/test_bootstrap1_1.xpi"; - let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall"); - - ensure_test_completed(); - - notEqual(install, null); - - await new Promise(resolve => { - prepare_test({}, [ - "onDownloadStarted", - "onDownloadEnded", - ], function() { - equal(install.type, "extension"); - equal(install.version, "1.0"); - equal(install.name, "Test Bootstrap 1"); - equal(install.state, AddonManager.STATE_DOWNLOADED); - equal(install.addon.operationsRequiringRestart & - AddonManager.OP_NEEDS_RESTART_INSTALL, 0); - do_check_not_in_crash_annotation(ID1, "1.0"); - - prepare_test({ - [ID1]: [ - ["onInstalling", false], - "onInstalled", - ], - }, [ - "onInstallStarted", - "onInstallEnded", - ], resolve); - }); - install.install(); - }); - - await checkBootstrappedPref(); - - let installs = await AddonManager.getAllInstalls(); - - // There should be no active installs now since the install completed and - // doesn't require a restart. - equal(installs.length, 0); - - let b1 = await AddonManager.getAddonByID(ID1); - - notEqual(b1, null); - equal(b1.version, "1.0"); - ok(!b1.appDisabled); - ok(!b1.userDisabled); - ok(b1.isActive); - ok(!b1.isSystem); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - equal(getStartupReason(), ADDON_INSTALL); - equal(getStartupOldVersion(), undefined); - do_check_in_crash_annotation(ID1, "1.0"); - - let dir = do_get_addon_root_uri(profileDir, ID1); - equal(b1.getResourceURI("bootstrap.js").spec, dir + "bootstrap.js"); - - await promiseRestartManager(); - - let b1_2 = await AddonManager.getAddonByID(ID1); - await b1_2.uninstall(); -}); - -// Tests that we recover from a broken preference -add_task(async function test_24() { - info("starting 24"); - - await Promise.all([ - BootstrapMonitor.promiseAddonStartup(ID2), - promiseInstallAllFiles([XPIS.test_bootstrap1_1, XPIS.test_bootstrap2_1]), - ]); - - info("test 24 got prefs"); - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - BootstrapMonitor.checkAddonInstalled(ID2, "1.0"); - BootstrapMonitor.checkAddonStarted(ID2, "1.0"); - - await promiseRestartManager(); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - BootstrapMonitor.checkAddonInstalled(ID2, "1.0"); - BootstrapMonitor.checkAddonStarted(ID2, "1.0"); - - await promiseShutdownManager(); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID1); - BootstrapMonitor.checkAddonInstalled(ID2, "1.0"); - BootstrapMonitor.checkAddonNotStarted(ID2); - - // Break the JSON. - let data = aomStartup.readStartupData(); - data["app-profile"].addons[ID1].path += "foo"; - - await OS.File.writeAtomic(gAddonStartup.path, - new TextEncoder().encode(JSON.stringify(data)), - {compression: "lz4"}); - - await promiseStartupManager(); - - BootstrapMonitor.checkAddonInstalled(ID1, "1.0"); - BootstrapMonitor.checkAddonStarted(ID1, "1.0"); - BootstrapMonitor.checkAddonInstalled(ID2, "1.0"); - BootstrapMonitor.checkAddonStarted(ID2, "1.0"); -});
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bootstrap_const.js +++ /dev/null @@ -1,27 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); - -const ADDONS = { - test_bootstrap_const: { - "install.rdf": { - "id": "bootstrap@tests.mozilla.org", - }, - "bootstrap.js": "ChromeUtils.import(\"resource://gre/modules/Services.jsm\");\n\nconst install = function() {\n Services.obs.notifyObservers(null, \"addon-install\");\n};\n", - }, -}; - -add_task(async function() { - await promiseStartupManager(); - - let sawInstall = false; - Services.obs.addObserver(function() { - sawInstall = true; - }, "addon-install"); - - await AddonTestUtils.promiseInstallXPI(ADDONS.test_bootstrap_const); - - ok(sawInstall); -});
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bootstrap_globals.js +++ /dev/null @@ -1,66 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This verifies that bootstrap.js has the expected globals defined -ChromeUtils.import("resource://gre/modules/Services.jsm"); - -createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); - -const ADDONS = { - bootstrap_globals: { - "install.rdf": { - "id": "bootstrap_globals@tests.mozilla.org", - }, - "bootstrap.js": String.raw`ChromeUtils.import("resource://gre/modules/Services.jsm"); - -var seenGlobals = new Set(); -var scope = this; -function checkGlobal(name, type) { - if (scope[name] && typeof(scope[name]) == type) - seenGlobals.add(name); -} - -var wrapped = {}; -Services.obs.notifyObservers({ wrappedJSObject: wrapped }, "bootstrap-request-globals"); -for (let [name, type] of wrapped.expectedGlobals) { - checkGlobal(name, type); -} - -function startup(data, reason) { - Services.obs.notifyObservers({ wrappedJSObject: seenGlobals }, "bootstrap-seen-globals"); -} - -function install(data, reason) {} -function shutdown(data, reason) {} -function uninstall(data, reason) {} -`, - }, -}; - - -const EXPECTED_GLOBALS = [ - ["console", "object"], -]; - -async function run_test() { - do_test_pending(); - await promiseStartupManager(); - let sawGlobals = false; - - Services.obs.addObserver(function(subject) { - subject.wrappedJSObject.expectedGlobals = EXPECTED_GLOBALS; - }, "bootstrap-request-globals"); - - Services.obs.addObserver(function({ wrappedJSObject: seenGlobals }) { - for (let [name ] of EXPECTED_GLOBALS) - Assert.ok(seenGlobals.has(name)); - - sawGlobals = true; - }, "bootstrap-seen-globals"); - - await AddonTestUtils.promiseInstallXPI(ADDONS.bootstrap_globals); - Assert.ok(sawGlobals); - await promiseShutdownManager(); - do_test_finished(); -}
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bootstrapped_chrome_manifest.js +++ /dev/null @@ -1,50 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -const ADDON = { - "install.rdf": { - "id": "bug675371@tests.mozilla.org", - }, - "chrome.manifest": `content bug675371 .`, - "test.js": `var active = true;`, -}; - -add_task(async function run_test() { - createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - await promiseStartupManager(); -}); - -function checkActive(expected) { - let target = { active: false }; - let load = () => { - Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target); - }; - - if (expected) { - load(); - } else { - Assert.throws(load, /Error opening input stream/); - } - equal(target.active, expected, "Manifest is active?"); -} - -add_task(async function test() { - let {addon} = await AddonTestUtils.promiseInstallXPI(ADDON); - - Assert.ok(addon.isActive); - - // Tests that chrome.manifest is registered when the addon is installed. - checkActive(true); - - await addon.disable(); - checkActive(false); - - await addon.enable(); - checkActive(true); - - await promiseShutdownManager(); - - // Tests that chrome.manifest remains registered at app shutdown. - checkActive(true); -});
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_invalid_install_rdf.js +++ /dev/null @@ -1,113 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// Test that side-loaded extensions with invalid install.rdf files are -// not initialized at startup. - -const APP_ID = "xpcshell@tests.mozilla.org"; - -Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_USER); - -createAppInfo(APP_ID, "XPCShell", "1", "1.9.2"); - -const userAppDir = AddonTestUtils.profileDir.clone(); -userAppDir.append("app-extensions"); -userAppDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); -AddonTestUtils.registerDirectory("XREUSysExt", userAppDir); - -const userExtensions = userAppDir.clone(); -userExtensions.append(APP_ID); -userExtensions.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - -XPCOMUtils.defineLazyServiceGetters(this, { - ChromeRegistry: ["@mozilla.org/chrome/chrome-registry;1", "nsIChromeRegistry"], -}); - -function hasChromeEntry(package) { - try { - void ChromeRegistry.convertChromeURL(Services.io.newURI(`chrome://${package}/content/`)); - return true; - } catch (e) { - return false; - } -} - -add_task(async function() { - await promiseWriteInstallRDFToXPI({ - id: "langpack-foo@addons.mozilla.org", - version: "1.0", - type: 8, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Invalid install.rdf extension", - }, userExtensions, undefined, { - "chrome.manifest": ` - content foo-langpack ./ - `, - }); - - await promiseWriteInstallRDFToXPI({ - id: "foo@addons.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Invalid install.rdf extension", - }, userExtensions, undefined, { - "chrome.manifest": ` - content foo ./ - `, - }); - - await promiseWriteInstallRDFToXPI({ - id: "foo-legacy-legacy@addons.mozilla.org", - version: "1.0", - bootstrap: false, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Invalid install.rdf extension", - }, userExtensions, undefined, { - "chrome.manifest": ` - content foo-legacy-legacy ./ - `, - }); - - equal(hasChromeEntry("foo-langpack"), false, - "Should not have registered foo-langpack resource before AOM startup"); - equal(hasChromeEntry("foo-legacy-legacy"), false, - "Should not have registered foo-legacy-legacy resource before AOM startup"); - equal(hasChromeEntry("foo"), false, - "Should not have registered foo resource before AOM startup"); - - await promiseStartupManager(); - - equal(hasChromeEntry("foo-langpack"), false, - "Should not have registered chrome manifest for invalid extension"); - equal(hasChromeEntry("foo-legacy-legacy"), false, - "Should not have registered chrome manifest for non-restartless extension"); - equal(hasChromeEntry("foo"), true, - "Should have registered chrome manifest for valid extension"); - - await promiseRestartManager(); - - equal(hasChromeEntry("foo-langpack"), false, - "Should still not have registered chrome manifest for invalid extension after restart"); - equal(hasChromeEntry("foo-legacy-legacy"), false, - "Should still not have registered chrome manifest for non-restartless extension"); - equal(hasChromeEntry("foo"), true, - "Should still have registered chrome manifest for valid extension after restart"); - - await promiseShutdownManager(); - - userAppDir.remove(true); -});
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_legacy.js +++ /dev/null @@ -1,118 +0,0 @@ - -const LEGACY_PREF = "extensions.legacy.enabled"; - -createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); - -add_task(async function test_disable() { - await promiseStartupManager(); - - let legacy = [ - { - id: "bootstrap@tests.mozilla.org", - name: "Bootstrap add-on", - version: "1.0", - bootstrap: true, - }, - ]; - - let nonLegacy = [ - { - id: "webextension@tests.mozilla.org", - manifest: { - applications: {gecko: {id: "webextension@tests.mozilla.org"}}, - }, - }, - { - id: "privileged@tests.mozilla.org", - name: "Privileged Bootstrap add-on", - version: "1.0", - bootstrap: true, - }, - { - id: "dictionary@tests.mozilla.org", - name: "Test Dictionary", - version: "1.0", - type: "64", - }, - ]; - - function makeXPI(info) { - if (info.manifest) { - return createTempWebExtensionFile(info); - } - - return createTempXPIFile(Object.assign({}, info, { - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - })); - } - - AddonTestUtils.usePrivilegedSignatures = id => id.startsWith("privileged"); - - // Start out with legacy extensions disabled, installing non-legacy - // extensions should succeed. - Services.prefs.setBoolPref(LEGACY_PREF, false); - let installs = await Promise.all(nonLegacy.map(info => { - let xpi = makeXPI(info); - return AddonManager.getInstallForFile(xpi); - })); - await promiseCompleteAllInstalls(installs); - for (let install of installs) { - Assert.equal(install.state, AddonManager.STATE_INSTALLED); - Assert.equal(install.error, 0); - } - let addons = await AddonManager.getAddonsByIDs(nonLegacy.map(a => a.id)); - for (let addon of addons) { - Assert.equal(addon.appDisabled, false); - } - - // And installing legacy extensions should fail - let legacyXPIs = legacy.map(makeXPI); - installs = await Promise.all(legacyXPIs.map(xpi => AddonManager.getInstallForFile(xpi))); - - // Yuck, the AddonInstall API is atrocious. Installs of incompatible - // extensions are detected when the install reaches the DOWNLOADED state - // and the install is abandoned at that point. Since this is a local file - // install we just start out in the DOWNLOADED state. - for (let install of installs) { - Assert.equal(install.state, AddonManager.STATE_DOWNLOADED); - Assert.equal(install.addon.appDisabled, true); - } - - // Now enable legacy extensions, and we should be able to install - // the legacy extensions. - Services.prefs.setBoolPref(LEGACY_PREF, true); - installs = await Promise.all(legacyXPIs.map(xpi => AddonManager.getInstallForFile(xpi))); - for (let install of installs) { - Assert.equal(install.state, AddonManager.STATE_DOWNLOADED); - Assert.equal(install.addon.appDisabled, false); - } - await promiseCompleteAllInstalls(installs); - for (let install of installs) { - Assert.equal(install.state, AddonManager.STATE_INSTALLED); - Assert.equal(install.error, 0); - } - addons = await AddonManager.getAddonsByIDs(legacy.map(a => a.id)); - for (let addon of addons) { - Assert.equal(addon.appDisabled, false); - } - - // Flip the preference back, the legacy extensions should become disabled - // but non-legacy extensions should remain enabled. - Services.prefs.setBoolPref(LEGACY_PREF, false); - addons = await AddonManager.getAddonsByIDs(nonLegacy.map(a => a.id)); - for (let addon of addons) { - Assert.equal(addon.appDisabled, false); - await addon.uninstall(); - } - addons = await AddonManager.getAddonsByIDs(legacy.map(a => a.id)); - for (let addon of addons) { - Assert.equal(addon.appDisabled, true); - await addon.uninstall(); - } - - Services.prefs.clearUserPref(LEGACY_PREF); -});
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_manifest.js +++ /dev/null @@ -1,752 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This tests that all properties are read from the install manifests and that -// items are correctly enabled/disabled based on them (blocklist tests are -// elsewhere) - -const ADDONS = [ - { - "install.rdf": { - id: "addon1@tests.mozilla.org", - version: "1.0", - bootstrap: true, - aboutURL: "chrome://test/content/about.xul", - iconURL: "chrome://test/skin/icon.png", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 1", - description: "Test Description", - creator: "Test Creator", - homepageURL: "http://www.example.com", - developer: [ - "Test Developer 1", - "Test Developer 2", - ], - translator: [ - "Test Translator 1", - "Test Translator 2", - ], - contributor: [ - "Test Contributor 1", - "Test Contributor 2", - ], - }, - - expected: { - id: "addon1@tests.mozilla.org", - type: "extension", - version: "1.0", - optionsType: null, - aboutURL: "chrome://test/content/about.xul", - iconURL: "chrome://test/skin/icon.png", - icons: {32: "chrome://test/skin/icon.png", 48: "chrome://test/skin/icon.png"}, - name: "Test Addon 1", - description: "Test Description", - creator: "Test Creator", - homepageURL: "http://www.example.com", - developers: ["Test Developer 1", "Test Developer 2"], - translators: ["Test Translator 1", "Test Translator 2"], - contributors: ["Test Contributor 1", "Test Contributor 2"], - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - providesUpdatesSecurely: true, - blocklistState: Ci.nsIBlocklistService.STATE_NOT_BLOCKED, - }, - }, - - { - "install.rdf": { - id: "addon2@tests.mozilla.org", - version: "1.0", - bootstrap: true, - updateURL: "https://www.foo.com", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 2", - }, - - expected: { - id: "addon2@tests.mozilla.org", - isActive: true, - userDisabled: false, - appDisabled: false, - providesUpdatesSecurely: true, - }, - }, - - { - "install.rdf": { - id: "addon3@tests.mozilla.org", - version: "1.0", - bootstrap: true, - updateURL: "http://www.foo.com", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 3", - }, - - expected: { - id: "addon3@tests.mozilla.org", - isActive: false, - userDisabled: false, - appDisabled: true, - providesUpdatesSecurely: false, - }, - }, - - { - "install.rdf": { - id: "addon4@tests.mozilla.org", - version: "1.0", - bootstrap: true, - updateURL: "http://www.foo.com", - updateKey: "foo", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 4", - }, - - expected: { - id: "addon4@tests.mozilla.org", - isActive: false, - userDisabled: false, - appDisabled: true, - providesUpdatesSecurely: false, - }, - }, - - { - "install.rdf": { - id: "addon5@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "*", - }], - name: "Test Addon 5", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - }, - }, - - { - "install.rdf": { - id: "addon6@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "0", - maxVersion: "1", - }], - name: "Test Addon 6", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - }, - }, - - { - "install.rdf": { - id: "addon7@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "0", - maxVersion: "0", - }], - name: "Test Addon 7", - }, - - expected: { - isActive: false, - userDisabled: false, - appDisabled: true, - isCompatible: false, - }, - }, - - { - "install.rdf": { - id: "addon8@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1.1", - maxVersion: "*", - }], - name: "Test Addon 8", - }, - - expected: { - isActive: false, - userDisabled: false, - appDisabled: true, - isCompatible: false, - }, - }, - - { - "install.rdf": { - id: "addon9@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "toolkit@mozilla.org", - minVersion: "1.9.2", - maxVersion: "1.9.*", - }], - name: "Test Addon 9", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - }, - }, - - { - "install.rdf": { - id: "addon10@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "toolkit@mozilla.org", - minVersion: "1.9.2.1", - maxVersion: "1.9.*", - }], - name: "Test Addon 10", - }, - - expected: { - isActive: false, - userDisabled: false, - appDisabled: true, - isCompatible: false, - }, - }, - - { - "install.rdf": { - id: "addon11@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "toolkit@mozilla.org", - minVersion: "1.9", - maxVersion: "1.9.2", - }], - name: "Test Addon 11", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - }, - }, - - { - "install.rdf": { - id: "addon12@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "toolkit@mozilla.org", - minVersion: "1.9", - maxVersion: "1.9.1.*", - }], - name: "Test Addon 12", - }, - - expected: { - isActive: false, - userDisabled: false, - appDisabled: true, - isCompatible: false, - }, - }, - - { - "install.rdf": { - id: "addon13@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "toolkit@mozilla.org", - minVersion: "1.9", - maxVersion: "1.9.*", - }, { - id: "xpcshell@tests.mozilla.org", - minVersion: "0", - maxVersion: "0.5", - }], - name: "Test Addon 13", - }, - - expected: { - isActive: false, - userDisabled: false, - appDisabled: true, - isCompatible: false, - }, - }, - - { - "install.rdf": { - id: "addon14@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "toolkit@mozilla.org", - minVersion: "1.9", - maxVersion: "1.9.1", - }, { - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 14", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - }, - }, - - { - "install.rdf": { - id: "addon15@tests.mozilla.org", - version: "1.0", - bootstrap: true, - updateKey: "foo", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 15", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - providesUpdatesSecurely: true, - }, - }, - - { - "install.rdf": { - id: "addon16@tests.mozilla.org", - version: "1.0", - bootstrap: true, - updateKey: "foo", - updateURL: "https://www.foo.com", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 16", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - providesUpdatesSecurely: true, - }, - }, - - { - "install.rdf": { - id: "addon17@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsURL: "chrome://test/content/options.xul", - optionsType: "2", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 17", - }, - - // An obsolete optionsType means the add-on isn't registered. - expected: null, - }, - - { - "install.rdf": { - id: "addon18@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 18", - }, - extraFiles: {"options.xul": ""}, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - optionsURL: null, - optionsType: null, - }, - }, - - { - "install.rdf": { - id: "addon19@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsType: "99", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 19", - }, - - expected: null, - }, - - { - "install.rdf": { - id: "addon20@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsURL: "chrome://test/content/options.xul", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 20", - }, - - // Even with a defined optionsURL optionsType is null by default. - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - optionsURL: "chrome://test/content/options.xul", - optionsType: null, - }, - }, - - { - "install.rdf": { - id: "addon21@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsType: "3", - optionsURL: "chrome://test/content/options.xul", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 21", - }, - - expected: { - isActive: true, - userDisabled: false, - appDisabled: false, - isCompatible: true, - optionsURL: "chrome://test/content/options.xul", - optionsType: AddonManager.OPTIONS_TYPE_TAB, - }, - }, - - { - "install.rdf": { - id: "addon22@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsType: "2", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 22", - }, - - // An obsolete optionsType means the add-on isn't registered. - expected: null, - }, - - { - "install.rdf": { - id: "addon23@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsType: "2", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 23", - }, - extraFiles: {"options.xul": ""}, - - // An obsolete optionsType means the add-on isn't registered. - expected: null, - }, - - { - "install.rdf": { - id: "addon24@tests.mozilla.org", - version: "1.0", - bootstrap: true, - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 24", - }, - extraFiles: {"options.xul": ""}, - - expected: { - optionsType: null, - optionsURL: null, - }, - }, - - { - "install.rdf": { - id: "addon25@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsType: "3", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 25", - }, - - expected: { - optionsType: null, - optionsURL: null, - }, - }, - - { - "install.rdf": { - id: "addon26@tests.mozilla.org", - version: "1.0", - bootstrap: true, - optionsType: "4", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - name: "Test Addon 26", - }, - extraFiles: {"options.xul": ""}, - expected: null, - }, - - // Tests compatibility based on target platforms. - - // No targetPlatforms so should be compatible - { - "install.rdf": { - id: "tp-addon1@tests.mozilla.org", - version: "1.0", - bootstrap: true, - name: "Test 1", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - }, - - expected: { - appDisabled: false, - isPlatformCompatible: true, - isActive: true, - }, - }, - - // Matches the OS - { - "install.rdf": { - id: "tp-addon2@tests.mozilla.org", - version: "1.0", - bootstrap: true, - name: "Test 2", - targetPlatforms: [ - "XPCShell", - "WINNT_x86", - "XPCShell", - ], - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - }, - - expected: { - appDisabled: false, - isPlatformCompatible: true, - isActive: true, - }, - }, - - // Matches the OS and ABI - { - "install.rdf": { - id: "tp-addon3@tests.mozilla.org", - version: "1.0", - bootstrap: true, - name: "Test 3", - targetPlatforms: [ - "WINNT", - "XPCShell_noarch-spidermonkey", - ], - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - }, - - expected: { - appDisabled: false, - isPlatformCompatible: true, - isActive: true, - }, - }, - - // Doesn't match - { - "install.rdf": { - id: "tp-addon4@tests.mozilla.org", - version: "1.0", - bootstrap: true, - name: "Test 4", - targetPlatforms: [ - "WINNT_noarch-spidermonkey", - "Darwin", - "WINNT_noarch-spidermonkey", - ], - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - }, - - expected: { - appDisabled: true, - isPlatformCompatible: false, - isActive: false, - }, - }, - - // Matches the OS but since a different entry specifies ABI this doesn't match. - { - "install.rdf": { - id: "tp-addon5@tests.mozilla.org", - version: "1.0", - bootstrap: true, - name: "Test 5", - targetPlatforms: [ - "XPCShell", - "XPCShell_foo", - ], - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1", - }], - }, - - expected: { - appDisabled: true, - isPlatformCompatible: false, - isActive: false, - }, - }, -]; - -const IDS = ADDONS.map(a => a["install.rdf"].id); - -add_task(async function setup() { - createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - const profileDir = gProfD.clone(); - profileDir.append("extensions"); - - for (let addon of ADDONS) { - await promiseWriteInstallRDFForExtension(addon["install.rdf"], profileDir, undefined, addon.extraFiles); - } -}); - -add_task(async function test_values() { - await promiseStartupManager(); - - let addons = await getAddons(IDS); - - for (let addon of ADDONS) { - let {id} = addon["install.rdf"]; - checkAddon(id, addons.get(id), addon.expected); - } - - await promiseShutdownManager(); -});
deleted file mode 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_manifest_locales.js +++ /dev/null @@ -1,134 +0,0 @@ -/* 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/. - */ - -const ID = "bug397778@tests.mozilla.org"; - -const ADDON = { - id: "bug397778@tests.mozilla.org", - version: "1.0", - name: "Fallback Name", - description: "Fallback Description", - bootstrap: true, - - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1"}], - - localized: [ - { - locale: ["fr"], - name: "fr Name", - description: "fr Description", - }, - { - locale: ["de-DE"], - name: "Deutsches W\u00f6rterbuch", - }, - { - locale: ["es-ES"], - name: "es-ES Name", - description: "es-ES Description", - }, - { - locale: ["zh-TW"], - name: "zh-TW Name", - description: "zh-TW Description", - }, - { - locale: ["zh-CN"], - name: "zh-CN Name", - description: "zh-CN Description", - }, - { - locale: ["en-GB"], - name: "en-GB Name", - description: "en-GB Description", - }, - { - locale: ["en"], - name: "en Name", - description: "en Description", - }, - { - locale: ["en-CA"], - name: "en-CA Name", - description: "en-CA Description", - }, - ], -}; - -add_task(async function setup() { - createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1"); - Services.locale.requestedLocales = ["fr-FR"]; - - await promiseStartupManager(); - await promiseInstallXPI(ADDON); -}); - -add_task(async function test_1() { - let addon = await AddonManager.getAddonByID(ID); - Assert.notEqual(addon, null); - Assert.equal(addon.name, "fr Name"); - Assert.equal(addon.description, "fr Description"); - - await addon.disable(); - await promiseRestartManager(); - - let newAddon = await AddonManager.getAddonByID(ID); - Assert.notEqual(newAddon, null); - Assert.equal(newAddon.name, "fr Name"); -}); - -add_task(async function test_2() { - // Change locale. The more specific de-DE is the best match - await restartWithLocales(["de"]); - - let addon = await AddonManager.getAddonByID(ID); - Assert.notEqual(addon, null); - Assert.equal(addon.name, "Deutsches W\u00f6rterbuch"); - Assert.equal(addon.description, null); -}); - -add_task(async function test_3() { - // Change locale. Locale case should have no effect - await restartWithLocales(["DE-de"]); - - let addon = await AddonManager.getAddonByID(ID); - Assert.notEqual(addon, null); - Assert.equal(addon.name, "Deutsches W\u00f6rterbuch"); - Assert.equal(addon.description, null); -}); - -add_task(async function test_4() { - // Change locale. es-ES should closely match - await restartWithLocales(["es-AR"]); - - let addon = await AddonManager.getAddonByID(ID); - Assert.notEqual(addon, null); - Assert.equal(addon.name, "es-ES Name"); - Assert.equal(addon.description, "es-ES Description"); -}); - -add_task(async function test_5() { - // Change locale. Either zh-CN or zh-TW could match - await restartWithLocales(["zh"]); - - let addon = await AddonManager.getAddonByID(ID); - Assert.notEqual(addon, null); - ok(addon.name == "zh-TW Name" || addon.name == "zh-CN Name", - `Add-on name mismatch: ${addon.name}`); -}); - -add_task(async function test_6() { - // Unknown locale should try to match against en-US as well. Of en,en-GB - // en should match as being less specific - await restartWithLocales(["nl-NL"]); - - let addon = await AddonManager.getAddonByID(ID); - Assert.notEqual(addon, null); - Assert.equal(addon.name, "en Name"); - Assert.equal(addon.description, "en Description"); -});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini @@ -58,20 +58,16 @@ tags = blocklist skip-if = os == "android" tags = blocklist [test_blocklist_url_ping_count.js] tags = blocklist [test_blocklistchange.js] # Times out during parallel runs on desktop requesttimeoutfactor = 2 tags = blocklist -[test_bootstrap.js] -[test_bootstrap_const.js] -[test_bootstrap_globals.js] -[test_bootstrapped_chrome_manifest.js] [test_cache_certdb.js] [test_cacheflush.js] [test_childprocess.js] [test_compatoverrides.js] head = head_addons.js head_compat.js [test_corrupt.js] [test_crash_annotation_quoting.js] [test_db_path.js] @@ -129,27 +125,20 @@ tags = blocklist [test_gmpProvider.js] skip-if = appname != "firefox" [test_harness.js] [test_hidden.js] [test_install.js] [test_install_icons.js] # Bug 676992: test consistently hangs on Android skip-if = os == "android" -[test_invalid_install_rdf.js] [test_isDebuggable.js] [test_isReady.js] [test_json_updatecheck.js] -[test_legacy.js] -skip-if = !allow_legacy_extensions || appname == "thunderbird" [test_locale.js] -[test_manifest.js] -[test_manifest_locales.js] -# Bug 676992: test consistently hangs on Android -skip-if = os == "android" [test_moved_extension_metadata.js] skip-if = true [test_no_addons.js] [test_nodisable_hidden.js] [test_onPropertyChanged_appDisabled.js] head = head_addons.js head_compat.js [test_overrideblocklist.js] run-sequentially = Uses global XCurProcD dir.