765 lines
20 KiB
JavaScript
765 lines
20 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
*/
|
|
|
|
const ID = "addon@tests.mozilla.org";
|
|
|
|
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
|
|
|
|
function waitForBootstrapEvent(expectedEvent, addonId) {
|
|
return new Promise(resolve => {
|
|
function listener(msg, { method, params, reason }) {
|
|
if (params.id === addonId && method === expectedEvent) {
|
|
resolve({ params, method, reason });
|
|
AddonTestUtils.off("bootstrap-method", listener);
|
|
} else {
|
|
info(`Ignoring bootstrap event: ${method} for ${params.id}`);
|
|
}
|
|
}
|
|
AddonTestUtils.on("bootstrap-method", listener);
|
|
});
|
|
}
|
|
|
|
async function checkEvent(promise, { reason, params }) {
|
|
let event = await promise;
|
|
info(`Checking bootstrap event ${event.method} for ${event.params.id}`);
|
|
|
|
equal(
|
|
event.reason,
|
|
reason,
|
|
`Expected bootstrap reason ${getReasonName(reason)} got ${getReasonName(
|
|
event.reason
|
|
)}`
|
|
);
|
|
|
|
for (let [param, value] of Object.entries(params)) {
|
|
equal(event.params[param], value, `Expected value for params.${param}`);
|
|
}
|
|
}
|
|
|
|
BootstrapMonitor.init();
|
|
|
|
const XPIS = {};
|
|
|
|
add_task(async function setup() {
|
|
for (let n of [1, 2]) {
|
|
XPIS[n] = await createTempWebExtensionFile({
|
|
manifest: {
|
|
name: "Test",
|
|
version: `${n}.0`,
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
},
|
|
});
|
|
}
|
|
});
|
|
|
|
// Install a temporary add-on with no existing add-on present.
|
|
// Restart and make sure it has gone away.
|
|
add_task(async function test_new_temporary() {
|
|
await promiseStartupManager();
|
|
|
|
let extInstallCalled = false;
|
|
AddonManager.addInstallListener({
|
|
onExternalInstall: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
Assert.equal(aInstall.version, "1.0");
|
|
extInstallCalled = true;
|
|
},
|
|
});
|
|
|
|
let installingCalled = false;
|
|
let installedCalled = false;
|
|
AddonManager.addAddonListener({
|
|
onInstalling: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
Assert.equal(aInstall.version, "1.0");
|
|
installingCalled = true;
|
|
},
|
|
onInstalled: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
Assert.equal(aInstall.version, "1.0");
|
|
installedCalled = true;
|
|
},
|
|
onInstallStarted: () => {
|
|
do_throw("onInstallStarted called unexpectedly");
|
|
},
|
|
});
|
|
|
|
await AddonManager.installTemporaryAddon(XPIS[1]);
|
|
|
|
Assert.ok(extInstallCalled);
|
|
Assert.ok(installingCalled);
|
|
Assert.ok(installedCalled);
|
|
|
|
const install = BootstrapMonitor.checkInstalled(ID, "1.0");
|
|
equal(install.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
|
|
|
|
BootstrapMonitor.checkStarted(ID, "1.0");
|
|
|
|
let info = BootstrapMonitor.started.get(ID);
|
|
Assert.equal(info.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
|
|
|
|
let addon = await promiseAddonByID(ID);
|
|
|
|
checkAddon(ID, addon, {
|
|
version: "1.0",
|
|
name: "Test",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: true,
|
|
});
|
|
|
|
let onShutdown = waitForBootstrapEvent("shutdown", ID);
|
|
let onUninstall = waitForBootstrapEvent("uninstall", ID);
|
|
|
|
await promiseRestartManager();
|
|
|
|
let shutdown = await onShutdown;
|
|
equal(shutdown.reason, BOOTSTRAP_REASONS.ADDON_UNINSTALL);
|
|
|
|
let uninstall = await onUninstall;
|
|
equal(uninstall.reason, BOOTSTRAP_REASONS.ADDON_UNINSTALL);
|
|
|
|
BootstrapMonitor.checkNotInstalled(ID);
|
|
BootstrapMonitor.checkNotStarted(ID);
|
|
|
|
addon = await promiseAddonByID(ID);
|
|
Assert.equal(addon, null);
|
|
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Install a temporary add-on over the top of an existing add-on.
|
|
// Restart and make sure the existing add-on comes back.
|
|
add_task(async function test_replace_temporary() {
|
|
await promiseInstallFile(XPIS[2]);
|
|
let addon = await promiseAddonByID(ID);
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "2.0");
|
|
BootstrapMonitor.checkStarted(ID, "2.0");
|
|
|
|
checkAddon(ID, addon, {
|
|
version: "2.0",
|
|
name: "Test",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: false,
|
|
});
|
|
|
|
let tempdir = gTmpD.clone();
|
|
|
|
for (let newversion of ["1.0", "3.0"]) {
|
|
for (let packed of [false, true]) {
|
|
// ugh, file locking issues with xpis on windows
|
|
if (packed && AppConstants.platform == "win") {
|
|
continue;
|
|
}
|
|
|
|
let files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
name: "Test",
|
|
version: newversion,
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
},
|
|
});
|
|
|
|
let target = await AddonTestUtils.promiseWriteFilesToExtension(
|
|
tempdir.path,
|
|
ID,
|
|
files,
|
|
!packed
|
|
);
|
|
|
|
let onShutdown = waitForBootstrapEvent("shutdown", ID);
|
|
let onUpdate = waitForBootstrapEvent("update", ID);
|
|
let onStartup = waitForBootstrapEvent("startup", ID);
|
|
|
|
await AddonManager.installTemporaryAddon(target);
|
|
|
|
let reason =
|
|
Services.vc.compare(newversion, "2.0") < 0
|
|
? BOOTSTRAP_REASONS.ADDON_DOWNGRADE
|
|
: BOOTSTRAP_REASONS.ADDON_UPGRADE;
|
|
|
|
await checkEvent(onShutdown, {
|
|
reason,
|
|
params: {
|
|
version: "2.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onUpdate, {
|
|
reason,
|
|
params: {
|
|
version: newversion,
|
|
oldVersion: "2.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onStartup, {
|
|
reason,
|
|
params: {
|
|
version: newversion,
|
|
oldVersion: "2.0",
|
|
},
|
|
});
|
|
|
|
addon = await promiseAddonByID(ID);
|
|
|
|
let signedState = packed
|
|
? AddonManager.SIGNEDSTATE_PRIVILEGED
|
|
: AddonManager.SIGNEDSTATE_UNKNOWN;
|
|
|
|
// temporary add-on is installed and started
|
|
checkAddon(ID, addon, {
|
|
version: newversion,
|
|
name: "Test",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState,
|
|
temporarilyInstalled: true,
|
|
});
|
|
|
|
// Now restart, the temporary addon will go away which should
|
|
// be the opposite action (ie, if the temporary addon was an
|
|
// upgrade, then removing it is a downgrade and vice versa)
|
|
reason =
|
|
reason == BOOTSTRAP_REASONS.ADDON_UPGRADE
|
|
? BOOTSTRAP_REASONS.ADDON_DOWNGRADE
|
|
: BOOTSTRAP_REASONS.ADDON_UPGRADE;
|
|
|
|
onShutdown = waitForBootstrapEvent("shutdown", ID);
|
|
onUpdate = waitForBootstrapEvent("update", ID);
|
|
onStartup = waitForBootstrapEvent("startup", ID);
|
|
|
|
await promiseRestartManager();
|
|
|
|
await checkEvent(onShutdown, {
|
|
reason,
|
|
params: {
|
|
version: newversion,
|
|
},
|
|
});
|
|
|
|
await checkEvent(onUpdate, {
|
|
reason,
|
|
params: {
|
|
version: "2.0",
|
|
oldVersion: newversion,
|
|
},
|
|
});
|
|
|
|
await checkEvent(onStartup, {
|
|
// We don't actually propagate the upgrade/downgrade reason across
|
|
// the browser restart when a temporary addon is removed. See
|
|
// bug 1359558 for detailed reasoning.
|
|
reason: BOOTSTRAP_REASONS.APP_STARTUP,
|
|
params: {
|
|
version: "2.0",
|
|
},
|
|
});
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "2.0");
|
|
BootstrapMonitor.checkStarted(ID, "2.0");
|
|
|
|
addon = await promiseAddonByID(ID);
|
|
|
|
// existing add-on is back
|
|
checkAddon(ID, addon, {
|
|
version: "2.0",
|
|
name: "Test",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: false,
|
|
});
|
|
|
|
Services.obs.notifyObservers(target, "flush-cache-entry");
|
|
target.remove(true);
|
|
}
|
|
}
|
|
|
|
// remove original add-on
|
|
await addon.uninstall();
|
|
|
|
BootstrapMonitor.checkNotInstalled(ID);
|
|
BootstrapMonitor.checkNotStarted(ID);
|
|
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Test that loading from the same path multiple times work
|
|
add_task(async function test_samefile() {
|
|
// File locking issues on Windows, ugh
|
|
if (AppConstants.platform == "win") {
|
|
return;
|
|
}
|
|
|
|
// test that a webextension works
|
|
let webext = createTempWebExtensionFile({
|
|
manifest: {
|
|
version: "1.0",
|
|
name: "Test WebExtension 1 (temporary)",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: ID,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
let addon = await AddonManager.installTemporaryAddon(webext);
|
|
|
|
// temporary add-on is installed and started
|
|
checkAddon(ID, addon, {
|
|
version: "1.0",
|
|
name: "Test WebExtension 1 (temporary)",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: true,
|
|
});
|
|
|
|
Services.obs.notifyObservers(webext, "flush-cache-entry");
|
|
webext.remove(false);
|
|
webext = createTempWebExtensionFile({
|
|
manifest: {
|
|
version: "2.0",
|
|
name: "Test WebExtension 1 (temporary)",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: ID,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
addon = await AddonManager.installTemporaryAddon(webext);
|
|
|
|
// temporary add-on is installed and started
|
|
checkAddon(ID, addon, {
|
|
version: "2.0",
|
|
name: "Test WebExtension 1 (temporary)",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
isWebExtension: true,
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: true,
|
|
});
|
|
|
|
await addon.uninstall();
|
|
});
|
|
|
|
// Install a temporary add-on over the top of an existing add-on.
|
|
// Uninstall it and make sure the existing add-on comes back.
|
|
add_task(async function test_replace_permanent() {
|
|
await promiseInstallWebExtension({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "1.0",
|
|
name: "Test Bootstrap 1",
|
|
},
|
|
});
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "1.0");
|
|
BootstrapMonitor.checkStarted(ID, "1.0");
|
|
|
|
let unpacked_addon = gTmpD.clone();
|
|
unpacked_addon.append(ID);
|
|
|
|
let files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "2.0",
|
|
name: "Test Bootstrap 1 (temporary)",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpacked_addon.path, files);
|
|
|
|
let extInstallCalled = false;
|
|
AddonManager.addInstallListener({
|
|
onExternalInstall: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
Assert.equal(aInstall.version, "2.0");
|
|
extInstallCalled = true;
|
|
},
|
|
});
|
|
|
|
let installingCalled = false;
|
|
let installedCalled = false;
|
|
AddonManager.addAddonListener({
|
|
onInstalling: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
if (!installingCalled) {
|
|
Assert.equal(aInstall.version, "2.0");
|
|
}
|
|
installingCalled = true;
|
|
},
|
|
onInstalled: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
if (!installedCalled) {
|
|
Assert.equal(aInstall.version, "2.0");
|
|
}
|
|
installedCalled = true;
|
|
},
|
|
onInstallStarted: () => {
|
|
do_throw("onInstallStarted called unexpectedly");
|
|
},
|
|
});
|
|
|
|
let addon = await AddonManager.installTemporaryAddon(unpacked_addon);
|
|
|
|
Assert.ok(extInstallCalled);
|
|
Assert.ok(installingCalled);
|
|
Assert.ok(installedCalled);
|
|
|
|
BootstrapMonitor.checkInstalled(ID);
|
|
BootstrapMonitor.checkStarted(ID);
|
|
|
|
// temporary add-on is installed and started
|
|
checkAddon(ID, addon, {
|
|
version: "2.0",
|
|
name: "Test Bootstrap 1 (temporary)",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_UNKNOWN,
|
|
temporarilyInstalled: true,
|
|
});
|
|
|
|
await addon.uninstall();
|
|
|
|
BootstrapMonitor.checkInstalled(ID);
|
|
BootstrapMonitor.checkStarted(ID);
|
|
|
|
addon = await promiseAddonByID(ID);
|
|
|
|
// existing add-on is back
|
|
checkAddon(ID, addon, {
|
|
version: "1.0",
|
|
name: "Test Bootstrap 1",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: false,
|
|
});
|
|
|
|
unpacked_addon.remove(true);
|
|
await addon.uninstall();
|
|
|
|
BootstrapMonitor.checkNotInstalled(ID);
|
|
BootstrapMonitor.checkNotStarted(ID);
|
|
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Install a temporary add-on as a version upgrade over the top of an
|
|
// existing temporary add-on.
|
|
add_task(async function test_replace_temporary() {
|
|
const unpackedAddon = gTmpD.clone();
|
|
unpackedAddon.append(ID);
|
|
|
|
let files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "1.0",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpackedAddon.path, files);
|
|
|
|
await AddonManager.installTemporaryAddon(unpackedAddon);
|
|
|
|
// Increment the version number, re-install it, and make sure it
|
|
// gets marked as an upgrade.
|
|
files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "2.0",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpackedAddon.path, files);
|
|
|
|
const onShutdown = waitForBootstrapEvent("shutdown", ID);
|
|
const onUpdate = waitForBootstrapEvent("update", ID);
|
|
const onStartup = waitForBootstrapEvent("startup", ID);
|
|
await AddonManager.installTemporaryAddon(unpackedAddon);
|
|
|
|
await checkEvent(onShutdown, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
|
|
params: {
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onUpdate, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
|
|
params: {
|
|
version: "2.0",
|
|
oldVersion: "1.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onStartup, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
|
|
params: {
|
|
version: "2.0",
|
|
oldVersion: "1.0",
|
|
},
|
|
});
|
|
|
|
const addon = await promiseAddonByID(ID);
|
|
await addon.uninstall();
|
|
|
|
unpackedAddon.remove(true);
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Install a temporary add-on as a version downgrade over the top of an
|
|
// existing temporary add-on.
|
|
add_task(async function test_replace_temporary_downgrade() {
|
|
const unpackedAddon = gTmpD.clone();
|
|
unpackedAddon.append(ID);
|
|
|
|
let files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "1.0",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpackedAddon.path, files);
|
|
|
|
await AddonManager.installTemporaryAddon(unpackedAddon);
|
|
|
|
// Decrement the version number, re-install, and make sure
|
|
// it gets marked as a downgrade.
|
|
files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "0.8",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpackedAddon.path, files);
|
|
|
|
const onShutdown = waitForBootstrapEvent("shutdown", ID);
|
|
const onUpdate = waitForBootstrapEvent("update", ID);
|
|
const onStartup = waitForBootstrapEvent("startup", ID);
|
|
await AddonManager.installTemporaryAddon(unpackedAddon);
|
|
|
|
await checkEvent(onShutdown, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
|
|
params: {
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onUpdate, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
|
|
params: {
|
|
oldVersion: "1.0",
|
|
version: "0.8",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onStartup, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
|
|
params: {
|
|
version: "0.8",
|
|
},
|
|
});
|
|
|
|
const addon = await promiseAddonByID(ID);
|
|
await addon.uninstall();
|
|
|
|
unpackedAddon.remove(true);
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Installing a temporary add-on over an existing add-on with the same
|
|
// version number should be installed as an upgrade.
|
|
add_task(async function test_replace_same_version() {
|
|
const unpackedAddon = gTmpD.clone();
|
|
unpackedAddon.append(ID);
|
|
|
|
let files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
version: "1.0",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpackedAddon.path, files);
|
|
|
|
const onInitialInstall = waitForBootstrapEvent("install", ID);
|
|
const onInitialStartup = waitForBootstrapEvent("startup", ID);
|
|
await AddonManager.installTemporaryAddon(unpackedAddon);
|
|
|
|
await checkEvent(onInitialInstall, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_INSTALL,
|
|
params: {
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onInitialStartup, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_INSTALL,
|
|
params: {
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
let info = BootstrapMonitor.started.get(ID);
|
|
Assert.equal(info.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
|
|
|
|
// Install it again.
|
|
const onShutdown = waitForBootstrapEvent("shutdown", ID);
|
|
const onUpdate = waitForBootstrapEvent("update", ID);
|
|
const onStartup = waitForBootstrapEvent("startup", ID);
|
|
await AddonManager.installTemporaryAddon(unpackedAddon);
|
|
|
|
await checkEvent(onShutdown, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
|
|
params: {
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onUpdate, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
|
|
params: {
|
|
oldVersion: "1.0",
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
await checkEvent(onStartup, {
|
|
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
|
|
params: {
|
|
version: "1.0",
|
|
},
|
|
});
|
|
|
|
const addon = await promiseAddonByID(ID);
|
|
await addon.uninstall();
|
|
|
|
unpackedAddon.remove(true);
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Install a temporary add-on over the top of an existing disabled add-on.
|
|
// After restart, the existing add-on should continue to be installed and disabled.
|
|
add_task(async function test_replace_permanent_disabled() {
|
|
await promiseInstallFile(XPIS[1]);
|
|
let addon = await promiseAddonByID(ID);
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "1.0");
|
|
BootstrapMonitor.checkStarted(ID, "1.0");
|
|
|
|
await addon.disable();
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "1.0");
|
|
BootstrapMonitor.checkNotStarted(ID);
|
|
|
|
let unpacked_addon = gTmpD.clone();
|
|
unpacked_addon.append(ID);
|
|
|
|
let files = ExtensionTestCommon.generateFiles({
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id: ID } },
|
|
name: "Test",
|
|
version: "2.0",
|
|
},
|
|
});
|
|
await AddonTestUtils.promiseWriteFilesToDir(unpacked_addon.path, files);
|
|
|
|
let extInstallCalled = false;
|
|
AddonManager.addInstallListener({
|
|
onExternalInstall: aInstall => {
|
|
Assert.equal(aInstall.id, ID);
|
|
Assert.equal(aInstall.version, "2.0");
|
|
extInstallCalled = true;
|
|
},
|
|
});
|
|
|
|
let tempAddon = await AddonManager.installTemporaryAddon(unpacked_addon);
|
|
|
|
Assert.ok(extInstallCalled);
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "2.0");
|
|
BootstrapMonitor.checkStarted(ID);
|
|
|
|
// temporary add-on is installed and started
|
|
checkAddon(ID, tempAddon, {
|
|
version: "2.0",
|
|
name: "Test",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_UNKNOWN,
|
|
temporarilyInstalled: true,
|
|
});
|
|
|
|
await tempAddon.uninstall();
|
|
unpacked_addon.remove(true);
|
|
|
|
await addon.enable();
|
|
await new Promise(executeSoon);
|
|
addon = await promiseAddonByID(ID);
|
|
|
|
BootstrapMonitor.checkInstalled(ID, "1.0");
|
|
BootstrapMonitor.checkStarted(ID);
|
|
|
|
// existing add-on is back
|
|
checkAddon(ID, addon, {
|
|
version: "1.0",
|
|
name: "Test",
|
|
isCompatible: true,
|
|
appDisabled: false,
|
|
isActive: true,
|
|
type: "extension",
|
|
signedState: AddonManager.SIGNEDSTATE_PRIVILEGED,
|
|
temporarilyInstalled: false,
|
|
});
|
|
|
|
await addon.uninstall();
|
|
|
|
BootstrapMonitor.checkNotInstalled(ID);
|
|
BootstrapMonitor.checkNotStarted(ID);
|
|
|
|
await promiseRestartManager();
|
|
});
|
|
|
|
// Tests that XPIs with a .zip extension work when loaded temporarily.
|
|
add_task(async function test_zip_extension() {
|
|
let xpi = createTempWebExtensionFile({
|
|
background() {
|
|
/* globals browser */
|
|
browser.test.sendMessage("started", "Hello.");
|
|
},
|
|
});
|
|
xpi.moveTo(null, xpi.leafName.replace(/\.xpi$/, ".zip"));
|
|
|
|
let extension = ExtensionTestUtils.loadExtensionXPI(xpi);
|
|
await extension.startup();
|
|
|
|
let msg = await extension.awaitMessage("started");
|
|
equal(msg, "Hello.", "Got expected background script message");
|
|
|
|
await extension.unload();
|
|
});
|