Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'android'
- Manifest: browser/components/migration/tests/unit/xpcshell.toml
/* Any copyright is dedicated to the Public Domain.
"use strict";
const { AMBrowserExtensionsImport, AddonManager } = ChromeUtils.importESModule(
"resource://gre/modules/AddonManager.sys.mjs"
);
const { AddonTestUtils } = ChromeUtils.importESModule(
);
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,
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"
);
}
}
}
);