diff options
Diffstat (limited to 'toolkit/mozapps/webextensions/test/xpcshell/test_reload.js')
-rw-r--r-- | toolkit/mozapps/webextensions/test/xpcshell/test_reload.js | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/toolkit/mozapps/webextensions/test/xpcshell/test_reload.js b/toolkit/mozapps/webextensions/test/xpcshell/test_reload.js new file mode 100644 index 000000000..5873d1980 --- /dev/null +++ b/toolkit/mozapps/webextensions/test/xpcshell/test_reload.js @@ -0,0 +1,235 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42"); + +const sampleAddon = { + id: "webextension1@tests.mozilla.org", + name: "webextension_1", +} + +const manifestSample = { + id: "bootstrap1@tests.mozilla.org", + version: "1.0", + bootstrap: true, + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "1" + }], +}; + +const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {}); + +function promiseAddonStartup() { + return new Promise(resolve => { + let listener = (extension) => { + Management.off("startup", listener); + resolve(extension); + }; + + Management.on("startup", listener); + }); +} + +function* installAddon(fixtureName, addonID) { + yield promiseInstallAllFiles([do_get_addon(fixtureName)]); + return promiseAddonByID(addonID); +} + +function* tearDownAddon(addon) { + addon.uninstall(); + yield promiseShutdownManager(); +} + +add_task(function* test_reloading_a_temp_addon() { + yield promiseRestartManager(); + yield AddonManager.installTemporaryAddon(do_get_addon(sampleAddon.name)); + const addon = yield promiseAddonByID(sampleAddon.id) + + var receivedOnUninstalled = false; + var receivedOnUninstalling = false; + var receivedOnInstalled = false; + var receivedOnInstalling = false; + + const onReload = new Promise(resolve => { + const listener = { + onUninstalling: (addonObj) => { + if (addonObj.id === sampleAddon.id) { + receivedOnUninstalling = true; + } + }, + onUninstalled: (addonObj) => { + if (addonObj.id === sampleAddon.id) { + receivedOnUninstalled = true; + } + }, + onInstalling: (addonObj) => { + receivedOnInstalling = true; + equal(addonObj.id, sampleAddon.id); + }, + onInstalled: (addonObj) => { + receivedOnInstalled = true; + equal(addonObj.id, sampleAddon.id); + // This should be the last event called. + AddonManager.removeAddonListener(listener); + resolve(); + }, + } + AddonManager.addAddonListener(listener); + }); + + yield addon.reload(); + yield onReload; + + // Make sure reload() doesn't trigger uninstall events. + equal(receivedOnUninstalled, false, "reload should not trigger onUninstalled"); + equal(receivedOnUninstalling, false, "reload should not trigger onUninstalling"); + + // Make sure reload() triggers install events, like an upgrade. + equal(receivedOnInstalling, true, "reload should trigger onInstalling"); + equal(receivedOnInstalled, true, "reload should trigger onInstalled"); + + yield tearDownAddon(addon); +}); + +add_task(function* test_can_reload_permanent_addon() { + yield promiseRestartManager(); + const addon = yield installAddon(sampleAddon.name, sampleAddon.id); + + let disabledCalled = false; + let enabledCalled = false; + AddonManager.addAddonListener({ + onDisabled: (aAddon) => { + do_check_false(enabledCalled); + disabledCalled = true + }, + onEnabled: (aAddon) => { + do_check_true(disabledCalled); + enabledCalled = true + } + }) + + yield addon.reload(); + + do_check_true(disabledCalled); + do_check_true(enabledCalled); + + notEqual(addon, null); + equal(addon.appDisabled, false); + equal(addon.userDisabled, false); + + yield tearDownAddon(addon); +}); + +add_task(function* test_reload_to_invalid_version_fails() { + yield promiseRestartManager(); + let tempdir = gTmpD.clone(); + + // The initial version of the add-on will be compatible, and will therefore load + const addonId = "invalid_version_cannot_be_reloaded@tests.mozilla.org"; + let manifest = { + name: "invalid_version_cannot_be_reloaded", + description: "test invalid_version_cannot_be_reloaded", + manifest_version: 2, + version: "1.0", + applications: { + gecko: { + id: addonId, + } + }, + }; + + let addonDir = yield promiseWriteWebManifestForExtension(manifest, tempdir, "invalid_version"); + yield AddonManager.installTemporaryAddon(addonDir); + yield promiseAddonStartup(); + + let addon = yield promiseAddonByID(addonId); + notEqual(addon, null); + equal(addon.id, addonId); + equal(addon.version, "1.0"); + equal(addon.appDisabled, false); + equal(addon.userDisabled, false); + addonDir.remove(true); + + // update the manifest to make the add-on version incompatible, so the reload will reject + manifest.applications.gecko.strict_min_version = "1"; + manifest.applications.gecko.strict_max_version = "1"; + manifest.version = "2.0"; + + addonDir = yield promiseWriteWebManifestForExtension(manifest, tempdir, "invalid_version", false); + let expectedMsg = new RegExp("Add-on invalid_version_cannot_be_reloaded@tests.mozilla.org is not compatible with application version. " + + "add-on minVersion: 1. add-on maxVersion: 1."); + + yield Assert.rejects(addon.reload(), + expectedMsg, + "Reload rejects when application version does not fall between minVersion and maxVersion"); + + let reloadedAddon = yield promiseAddonByID(addonId); + notEqual(reloadedAddon, null); + equal(reloadedAddon.id, addonId); + equal(reloadedAddon.version, "1.0"); + equal(reloadedAddon.appDisabled, false); + equal(reloadedAddon.userDisabled, false); + + yield tearDownAddon(reloadedAddon); + addonDir.remove(true); +}); + +add_task(function* test_manifest_changes_are_refreshed() { + yield promiseRestartManager(); + let tempdir = gTmpD.clone(); + + const unpackedAddon = writeInstallRDFToDir( + Object.assign({}, manifestSample, { + name: "Test Bootstrap 1", + }), tempdir, manifestSample.id, "bootstrap.js"); + + yield AddonManager.installTemporaryAddon(unpackedAddon); + const addon = yield promiseAddonByID(manifestSample.id); + notEqual(addon, null); + equal(addon.name, "Test Bootstrap 1"); + + writeInstallRDFToDir(Object.assign({}, manifestSample, { + name: "Test Bootstrap 1 (reloaded)", + }), tempdir, manifestSample.id); + + yield addon.reload(); + + const reloadedAddon = yield promiseAddonByID(manifestSample.id); + notEqual(reloadedAddon, null); + equal(reloadedAddon.name, "Test Bootstrap 1 (reloaded)"); + + yield tearDownAddon(reloadedAddon); + unpackedAddon.remove(true); +}); + +add_task(function* test_reload_fails_on_installation_errors() { + yield promiseRestartManager(); + let tempdir = gTmpD.clone(); + + const unpackedAddon = writeInstallRDFToDir( + Object.assign({}, manifestSample, { + name: "Test Bootstrap 1", + }), tempdir, manifestSample.id, "bootstrap.js"); + + yield AddonManager.installTemporaryAddon(unpackedAddon); + const addon = yield promiseAddonByID(manifestSample.id); + notEqual(addon, null); + + // Trigger an installation error with an empty manifest. + writeInstallRDFToDir({}, tempdir, manifestSample.id); + + yield Assert.rejects(addon.reload(), /No ID in install manifest/); + + // The old add-on should be active. I.E. the broken reload will not + // disturb it. + const oldAddon = yield promiseAddonByID(manifestSample.id); + notEqual(oldAddon, null); + equal(oldAddon.isActive, true); + equal(oldAddon.name, "Test Bootstrap 1"); + + yield tearDownAddon(addon); + unpackedAddon.remove(true); +}); |