165 lines
4.9 KiB
JavaScript
165 lines
4.9 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
const { AMBrowserExtensionsImport, AddonManager } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/AddonManager.sys.mjs"
|
|
);
|
|
const { AddonTestUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/AddonTestUtils.sys.mjs"
|
|
);
|
|
const { ChromeMigrationUtils } = ChromeUtils.importESModule(
|
|
"resource:///modules/ChromeMigrationUtils.sys.mjs"
|
|
);
|
|
const { ChromeProfileMigrator } = ChromeUtils.importESModule(
|
|
"resource:///modules/ChromeProfileMigrator.sys.mjs"
|
|
);
|
|
|
|
AddonTestUtils.init(this);
|
|
AddonTestUtils.overrideCertDB();
|
|
AddonTestUtils.createAppInfo(
|
|
"xpcshell@tests.mozilla.org",
|
|
"XPCShell",
|
|
"42",
|
|
"42"
|
|
);
|
|
|
|
const TEST_SERVER = AddonTestUtils.createHttpServer({ hosts: ["example.com"] });
|
|
|
|
const PROFILE = {
|
|
id: "Default",
|
|
name: "Person 1",
|
|
};
|
|
|
|
const IMPORTED_ADDON_1 = {
|
|
name: "A Firefox extension",
|
|
version: "1.0",
|
|
browser_specific_settings: { gecko: { id: "some-ff@extension" } },
|
|
};
|
|
|
|
// Setup chrome user data path for all platforms.
|
|
ChromeMigrationUtils.getDataPath = () => {
|
|
return Promise.resolve(
|
|
do_get_file("Library/Application Support/Google/Chrome/").path
|
|
);
|
|
};
|
|
|
|
const mockAddonRepository = ({ addons = [] } = {}) => {
|
|
return {
|
|
async getMappedAddons(browserID, extensionIDs) {
|
|
Assert.equal(browserID, "chrome", "expected browser ID");
|
|
// Sort extension IDs to have a predictable order.
|
|
extensionIDs.sort();
|
|
Assert.deepEqual(
|
|
extensionIDs,
|
|
["fake-extension-1", "fake-extension-2"],
|
|
"expected an array of 2 extension IDs"
|
|
);
|
|
return Promise.resolve({
|
|
addons,
|
|
matchedIDs: [],
|
|
unmatchedIDs: [],
|
|
});
|
|
},
|
|
};
|
|
};
|
|
|
|
add_setup(async function setup() {
|
|
await AddonTestUtils.promiseStartupManager();
|
|
|
|
// Create a Firefox XPI that we can use during the import.
|
|
const xpi = AddonTestUtils.createTempWebExtensionFile({
|
|
manifest: IMPORTED_ADDON_1,
|
|
});
|
|
TEST_SERVER.registerFile(`/addons/addon-1.xpi`, xpi);
|
|
|
|
// Override the `AddonRepository` in `AMBrowserExtensionsImport` with our own
|
|
// mock so that we control the add-ons that are mapped to the list of Chrome
|
|
// extension IDs.
|
|
const addons = [
|
|
{
|
|
id: IMPORTED_ADDON_1.browser_specific_settings.gecko.id,
|
|
name: IMPORTED_ADDON_1.name,
|
|
version: IMPORTED_ADDON_1.version,
|
|
sourceURI: Services.io.newURI(`http://example.com/addons/addon-1.xpi`),
|
|
icons: {},
|
|
},
|
|
];
|
|
AMBrowserExtensionsImport._addonRepository = mockAddonRepository({ addons });
|
|
|
|
registerCleanupFunction(() => {
|
|
// Clear the add-on repository override.
|
|
AMBrowserExtensionsImport._addonRepository = null;
|
|
});
|
|
});
|
|
|
|
add_task(
|
|
{ pref_set: [["browser.migrate.chrome.extensions.enabled", true]] },
|
|
async function test_import_extensions() {
|
|
const migrator = await MigrationUtils.getMigrator("chrome");
|
|
Assert.ok(
|
|
await migrator.isSourceAvailable(),
|
|
"Sanity check the source exists"
|
|
);
|
|
|
|
let promiseTopic = TestUtils.topicObserved(
|
|
"webextension-imported-addons-pending"
|
|
);
|
|
await promiseMigration(
|
|
migrator,
|
|
MigrationUtils.resourceTypes.EXTENSIONS,
|
|
PROFILE,
|
|
true
|
|
);
|
|
await promiseTopic;
|
|
// When this property is `true`, the UI should show a badge on the appmenu
|
|
// button, and the user can finalize the import later.
|
|
Assert.ok(
|
|
AMBrowserExtensionsImport.canCompleteOrCancelInstalls,
|
|
"expected some add-ons to have been imported"
|
|
);
|
|
|
|
// Let's actually complete the import programatically below.
|
|
promiseTopic = TestUtils.topicObserved(
|
|
"webextension-imported-addons-complete"
|
|
);
|
|
await AMBrowserExtensionsImport.completeInstalls();
|
|
await Promise.all([
|
|
AddonTestUtils.promiseInstallEvent("onInstallEnded"),
|
|
promiseTopic,
|
|
]);
|
|
|
|
// The add-on should be installed and therefore it can be uninstalled.
|
|
const addon = await AddonManager.getAddonByID(
|
|
IMPORTED_ADDON_1.browser_specific_settings.gecko.id
|
|
);
|
|
await addon.uninstall();
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Test that, for now at least, the extension resource type is only made
|
|
* available for Chrome and none of the derivitive browsers.
|
|
*/
|
|
add_task(
|
|
{ pref_set: [["browser.migrate.chrome.extensions.enabled", true]] },
|
|
async function test_only_chrome_migrates_extensions() {
|
|
for (const key of MigrationUtils.availableMigratorKeys) {
|
|
let migrator = await MigrationUtils.getMigrator(key);
|
|
|
|
if (migrator instanceof ChromeProfileMigrator && key != "chrome") {
|
|
info("Testing migrator with key " + key);
|
|
Assert.ok(
|
|
await migrator.isSourceAvailable(),
|
|
"First check the source exists"
|
|
);
|
|
let resourceTypes = await migrator.getMigrateData(PROFILE);
|
|
Assert.ok(
|
|
!(resourceTypes & MigrationUtils.resourceTypes.EXTENSIONS),
|
|
"Should not offer the extension resource type"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
);
|