Bug 1544890 - Fix missing extension icon and permission prompt when installing an updated xpi found by backgroundUpdateCheck. r=mstriemer

Differential Revision: https://phabricator.services.mozilla.com/D68805

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Luca Greco 2020-04-15 09:20:46 +00:00
Родитель f692832064
Коммит 072f879ac7
4 изменённых файлов: 95 добавлений и 10 удалений

Просмотреть файл

@ -332,9 +332,11 @@ function checkForUpdate(addon) {
return new Promise(resolve => {
let listener = {
onUpdateAvailable(addon, install) {
attachUpdateHandler(install);
if (AddonManager.shouldAutoUpdate(addon)) {
// Make sure that an update handler is attached to all the install
// objects when updated xpis are going to be installed automatically.
attachUpdateHandler(install);
let failed = () => {
install.removeListener(updateListener);
resolve({ installed: false, pending: false, found: true });
@ -2852,6 +2854,14 @@ class AddonCard extends HTMLElement {
break;
}
case "install-update":
// Make sure that an update handler is attached to the install object
// before starting the update installation (otherwise the user would
// not be prompted for the new permissions requested if necessary),
// and also make sure that a prompt handler attached from a closed
// about:addons tab is replaced by the one attached by the currently
// active about:addons tab.
attachUpdateHandler(this.updateInstall);
this.updateInstall.install().then(
() => {
// The card will update with the new add-on when it gets

Просмотреть файл

@ -103,7 +103,7 @@ function attachUpdateHandler(install) {
info: {
type: "update",
addon: info.addon,
icon: info.addon.icon,
icon: info.addon.iconURL,
// Reference to the related AddonInstall object (used in
// AMTelemetry to link the recorded event to the other events from
// the same install flow).

Просмотреть файл

@ -1618,7 +1618,9 @@ var AddonTestUtils = {
reason = AddonTestUtils.updateReason,
...args
) {
let equal = this.testScope.equal;
// Retrieve the test assertion helper from the testScope
// (which is `equal` in xpcshell-test and `is` in mochitest)
let equal = this.testScope.equal || this.testScope.is;
return new Promise((resolve, reject) => {
let result = {};
addon.findUpdates(

Просмотреть файл

@ -6,13 +6,26 @@ const { AddonTestUtils } = ChromeUtils.import(
AddonTestUtils.initMochitest(this);
const server = AddonTestUtils.createHttpServer();
const initialAutoUpdate = AddonManager.autoUpdateDefault;
registerCleanupFunction(() => {
AddonManager.autoUpdateDefault = initialAutoUpdate;
});
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [["extensions.checkUpdateSecurity", false]],
});
Services.telemetry.clearEvents();
registerCleanupFunction(() => {
const { ExtensionsUI } = ChromeUtils.import(
"resource:///modules/ExtensionsUI.jsm"
);
info("Cleanup any pending notification before exiting the test");
ExtensionsUI.pendingNotifications.delete(window);
});
});
function loadDetailView(win, id) {
@ -159,17 +172,45 @@ add_task(async function testChangeAutoUpdates() {
]);
});
async function setupExtensionWithUpdate(id, { releaseNotes } = {}) {
await SpecialPowers.pushPrefEnv({
set: [["extensions.checkUpdateSecurity", false]],
function promisePermissionPrompt(addonId) {
return BrowserUtils.promiseObserved(
"webextension-permission-prompt",
subject => {
const { info } = subject.wrappedJSObject || {};
return !addonId || (info.addon && info.addon.id === addonId);
}
).then(({ subject }) => {
return subject.wrappedJSObject.info;
});
}
let server = AddonTestUtils.createHttpServer();
async function handlePermissionPrompt({ addonId, reject = false } = {}) {
const info = await promisePermissionPrompt(addonId);
// Assert that info.addon and info.icon are defined as expected.
is(
info.addon && info.addon.id,
addonId,
"Got the AddonWrapper in the permission prompt info"
);
ok(info.icon != null, "Got an addon icon in the permission prompt info");
if (reject) {
info.reject();
} else {
info.resolve();
}
}
async function setupExtensionWithUpdate(
id,
{ releaseNotes, cancelUpdate } = {}
) {
let serverHost = `http://localhost:${server.identity.primaryPort}`;
let updatesPath = `/ext-updates-${id}.json`;
let baseManifest = {
name: "Updates",
icons: { "48": "an-icon.png" },
applications: {
gecko: {
id,
@ -182,6 +223,11 @@ async function setupExtensionWithUpdate(id, { releaseNotes } = {}) {
manifest: {
...baseManifest,
version: "2",
// Include a permission in the updated extension, to make
// sure that we trigger the permission prompt as expected
// (and that we can accept or cancel the update by observing
// the underlying observerService notification).
permissions: ["http://*.example.com/*"],
},
});
@ -217,6 +263,8 @@ async function setupExtensionWithUpdate(id, { releaseNotes } = {}) {
},
});
handlePermissionPrompt({ addonId: id, reject: cancelUpdate });
let extension = ExtensionTestUtils.loadExtension({
manifest: {
...baseManifest,
@ -545,7 +593,7 @@ add_task(async function testReleaseNotesError() {
add_task(async function testUpdateCancelled() {
let id = "update@mochi.test";
let extension = await setupExtensionWithUpdate(id);
let extension = await setupExtensionWithUpdate(id, { cancelUpdate: true });
let win = await loadInitialView("extension");
let doc = win.document;
@ -567,7 +615,6 @@ add_task(async function testUpdateCancelled() {
// Force the install to be cancelled.
let install = card.updateInstall;
ok(install, "There was an install found");
install.promptHandler = Promise.reject().catch(() => {});
await installUpdate(card, "update-cancelled");
@ -748,3 +795,29 @@ add_task(async function testUpdatesShownOnLoad() {
await closeView(win);
await addon.unload();
});
add_task(async function testPromptOnBackgroundUpdateCheck() {
const id = "test-prompt-on-background-check@mochi.test";
const extension = await setupExtensionWithUpdate(id);
AddonManager.autoUpdateDefault = false;
const addon = await AddonManager.getAddonByID(id);
await AddonTestUtils.promiseFindAddonUpdates(
addon,
AddonManager.UPDATE_WHEN_PERIODIC_UPDATE
);
let win = await loadInitialView("extension");
let card = getAddonCard(win, id);
const promisePromptInfo = promisePermissionPrompt(id);
await installUpdate(card, "update-installed");
const promptInfo = await promisePromptInfo;
ok(promptInfo, "Got a permission prompt as expected");
AddonManager.autoUpdateDefault = true;
await closeView(win);
await extension.unload();
});