188 lines
6.4 KiB
JavaScript
188 lines
6.4 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
// We refer to addons that were sideloaded prior to disabling sideloading as legacy. We
|
|
// determine that they are legacy because they are in a SCOPE that is not included
|
|
// in AddonSettings.SCOPES_SIDELOAD.
|
|
//
|
|
// test_startup.js tests the legacy sideloading functionality still works as it should
|
|
// for ESR and some 3rd party distributions, which is to allow sideloading in all scopes.
|
|
//
|
|
// This file tests that locking down the sideload functionality works as we expect it to, which
|
|
// is to allow sideloading only in SCOPE_APPLICATION and SCOPE_PROFILE. We also allow the legacy
|
|
// sideloaded addons to be updated or removed.
|
|
//
|
|
// We first change the sideload scope so we can sideload some addons into locations outside
|
|
// the profile (ie. we create some legacy sideloads). We then reset it to test new sideloads.
|
|
//
|
|
// We expect new sideloads to only work in profile.
|
|
// We expect new sideloads to fail elsewhere.
|
|
// We expect to be able to change/uninstall legacy sideloads.
|
|
|
|
// This test uses add-on versions that follow the toolkit version but we
|
|
// started to encourage the use of a simpler format in Bug 1793925. We disable
|
|
// the pref below to avoid install errors.
|
|
Services.prefs.setBoolPref(
|
|
"extensions.webextensions.warnings-as-errors",
|
|
false
|
|
);
|
|
|
|
// IDs for scopes that should sideload when sideloading
|
|
// is not disabled.
|
|
let legacyIDs = [
|
|
getID(`legacy-global`),
|
|
getID(`legacy-user`),
|
|
getID(`legacy-app`),
|
|
getID(`legacy-profile`),
|
|
];
|
|
|
|
add_task(async function test_sideloads_legacy() {
|
|
let IDs = [];
|
|
|
|
// Create a "legacy" addon for each scope.
|
|
for (let [name, dir] of Object.entries(scopeDirectories)) {
|
|
let id = getID(`legacy-${name}`);
|
|
IDs.push(id);
|
|
await createWebExtension(id, initialVersion(name), dir);
|
|
}
|
|
|
|
await promiseStartupManager();
|
|
|
|
// SCOPE_APPLICATION will never sideload, so we expect 3 addons.
|
|
let sideloaded = await AddonManagerPrivate.getNewSideloads();
|
|
Assert.equal(sideloaded.length, 4, "four sideloaded addons");
|
|
let sideloadedIds = sideloaded.map(a => a.id);
|
|
for (let id of legacyIDs) {
|
|
Assert.ok(sideloadedIds.includes(id), `${id} is sideloaded`);
|
|
}
|
|
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_INSTALLED, []);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, []);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, []);
|
|
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
// Test that a sideload install in SCOPE_PROFILE is allowed, all others are
|
|
// disallowed.
|
|
add_task(async function test_sideloads_disabled() {
|
|
// First, reset our scope pref to disable sideloading. head_sideload.js set this to ALL.
|
|
Services.prefs.setIntPref(
|
|
"extensions.sideloadScopes",
|
|
AddonManager.SCOPE_PROFILE
|
|
);
|
|
|
|
// Create 4 new addons, only one of these, "profile" should
|
|
// sideload.
|
|
for (let [name, dir] of Object.entries(scopeDirectories)) {
|
|
await createWebExtension(getID(name), initialVersion(name), dir);
|
|
}
|
|
|
|
await promiseStartupManager();
|
|
|
|
// Test that the "profile" addon has been sideloaded.
|
|
let sideloaded = await AddonManagerPrivate.getNewSideloads();
|
|
Assert.equal(sideloaded.length, 1, "one sideloaded addon");
|
|
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_INSTALLED, [
|
|
getID("profile"),
|
|
]);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, []);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, []);
|
|
|
|
for (let [name] of Object.entries(scopeDirectories)) {
|
|
let id = getID(name);
|
|
let addon = await promiseAddonByID(id);
|
|
if (name === "profile") {
|
|
Assert.notEqual(addon, null);
|
|
Assert.equal(addon.id, id);
|
|
Assert.ok(addon.foreignInstall);
|
|
Assert.equal(addon.scope, AddonManager.SCOPE_PROFILE);
|
|
Assert.ok(addon.userDisabled);
|
|
Assert.ok(!addon.seen);
|
|
} else {
|
|
Assert.equal(addon, null, `addon ${id} is not installed`);
|
|
}
|
|
}
|
|
|
|
// Test that we still have the 3 legacy addons from the prior test, plus
|
|
// the new "profile" addon from this test.
|
|
let extensionAddons = await AddonManager.getAddonsByTypes(["extension"]);
|
|
Assert.equal(
|
|
extensionAddons.length,
|
|
5,
|
|
"five addons expected to be installed"
|
|
);
|
|
let IDs = extensionAddons.map(ext => ext.id);
|
|
for (let id of [getID("profile"), ...legacyIDs]) {
|
|
Assert.ok(IDs.includes(id), `${id} is installed`);
|
|
}
|
|
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
add_task(async function test_sideloads_changed() {
|
|
// Upgrade the manifest version
|
|
for (let [name, dir] of Object.entries(scopeDirectories)) {
|
|
let id = getID(name);
|
|
await createWebExtension(id, `${name}.1`, dir);
|
|
|
|
id = getID(`legacy-${name}`);
|
|
await createWebExtension(id, `${name}.1`, dir);
|
|
}
|
|
|
|
await promiseStartupManager();
|
|
let addons = await AddonManager.getAddonsByTypes(["extension"]);
|
|
Assert.equal(addons.length, 5, "addons installed");
|
|
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_INSTALLED, []);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, [
|
|
getID("profile"),
|
|
...legacyIDs,
|
|
]);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, []);
|
|
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
// Remove one just to test the startup changes
|
|
add_task(async function test_sideload_removal() {
|
|
let id = getID(`legacy-profile`);
|
|
let file = AddonTestUtils.getFileForAddon(profileDir, id);
|
|
file.remove(false);
|
|
Assert.ok(!file.exists());
|
|
|
|
await promiseStartupManager();
|
|
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_INSTALLED, []);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, []);
|
|
check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, [id]);
|
|
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
add_task(async function test_sideload_uninstall() {
|
|
await promiseStartupManager();
|
|
let addons = await AddonManager.getAddonsByTypes(["extension"]);
|
|
Assert.equal(addons.length, 4, "addons installed");
|
|
for (let addon of addons) {
|
|
let file = AddonTestUtils.getFileForAddon(
|
|
scopeToDir.get(addon.scope),
|
|
addon.id
|
|
);
|
|
await addon.uninstall();
|
|
// Addon file should still exist in non-profile directories.
|
|
Assert.equal(
|
|
addon.scope !== AddonManager.SCOPE_PROFILE,
|
|
file.exists(),
|
|
`file remains after uninstall for non-profile sideloads, scope ${addon.scope}`
|
|
);
|
|
}
|
|
addons = await AddonManager.getAddonsByTypes(["extension"]);
|
|
Assert.equal(addons.length, 0, "addons left");
|
|
|
|
await promiseShutdownManager();
|
|
});
|