diff options
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpcshell/test_filepointer.js')
-rw-r--r-- | toolkit/mozapps/extensions/test/xpcshell/test_filepointer.js | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_filepointer.js b/toolkit/mozapps/extensions/test/xpcshell/test_filepointer.js new file mode 100644 index 0000000000..c72737d4fe --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_filepointer.js @@ -0,0 +1,327 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Tests that various operations with file pointers work and do not affect the +// source files + +const ID1 = "addon1@tests.mozilla.org"; +const ID2 = "addon2@tests.mozilla.org"; + +const profileDir = gProfD.clone(); +profileDir.append("extensions"); +profileDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755); + +const sourceDir = gProfD.clone(); +sourceDir.append("source"); + +function promiseWriteWebExtension(path, data) { + let files = ExtensionTestCommon.generateFiles(data); + return AddonTestUtils.promiseWriteFilesToDir(path, files); +} + +function promiseWritePointer(aId, aName) { + let path = PathUtils.join(profileDir.path, aName || aId); + + let target = PathUtils.join(sourceDir.path, do_get_expected_addon_name(aId)); + + return IOUtils.writeUTF8(path, target); +} + +function promiseWriteRelativePointer(aId, aName) { + let path = PathUtils.join(profileDir.path, aName || aId); + + let absTarget = sourceDir.clone(); + absTarget.append(do_get_expected_addon_name(aId)); + + let relTarget = absTarget.getRelativeDescriptor(profileDir); + + return IOUtils.writeUTF8(path, relTarget); +} + +add_task(async function setup() { + ok(TEST_UNPACKED, "Pointer files only work with unpacked directories"); + + // Unpacked extensions are never signed, so this can only run with + // signature checks disabled. + Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, false); + + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); +}); + +// Tests that installing a new add-on by pointer works +add_task(async function test_new_pointer_install() { + let target = PathUtils.join(sourceDir.path, ID1); + await promiseWriteWebExtension(target, { + manifest: { + version: "1.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + await promiseWritePointer(ID1); + await promiseStartupManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + let file = getAddonFile(addon); + equal(file.parent.path, sourceDir.path); + + let rootUri = do_get_addon_root_uri(sourceDir, ID1); + let uri = addon.getResourceURI(); + equal(uri.spec, rootUri); + + // Check that upgrade is disabled for addons installed by file-pointers. + equal(addon.permissions & AddonManager.PERM_CAN_UPGRADE, 0); +}); + +// Tests that installing the addon from some other source doesn't clobber +// the original sources +add_task(async function test_addon_over_pointer() { + let xpi = AddonTestUtils.createTempWebExtensionFile({ + manifest: { + version: "2.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + + let install = await AddonManager.getInstallForFile( + xpi, + "application/x-xpinstall" + ); + await install.install(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "2.0"); + + let url = addon.getResourceURI(); + if (url instanceof Ci.nsIJARURI) { + url = url.JARFile; + } + let { file } = url.QueryInterface(Ci.nsIFileURL); + equal(file.parent.path, profileDir.path); + + let rootUri = do_get_addon_root_uri(profileDir, ID1); + let uri = addon.getResourceURI(); + equal(uri.spec, rootUri); + + let source = sourceDir.clone(); + source.append(ID1); + ok(source.exists()); + + await addon.uninstall(); +}); + +// Tests that uninstalling doesn't clobber the original sources +add_task(async function test_uninstall_pointer() { + await promiseWritePointer(ID1); + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + await addon.uninstall(); + + let source = sourceDir.clone(); + source.append(ID1); + ok(source.exists()); +}); + +// Tests that misnaming a pointer doesn't clobber the sources +add_task(async function test_bad_pointer() { + await promiseWritePointer(ID2, ID1); + + let [a1, a2] = await AddonManager.getAddonsByIDs([ID1, ID2]); + equal(a1, null); + equal(a2, null); + + let source = sourceDir.clone(); + source.append(ID1); + ok(source.exists()); + + let pointer = profileDir.clone(); + pointer.append(ID2); + ok(!pointer.exists()); +}); + +// Tests that changing the ID of an existing add-on doesn't clobber the sources +add_task(async function test_bad_pointer_id() { + let dir = sourceDir.clone(); + dir.append(ID1); + + // Make sure the modification time changes enough to be detected. + setExtensionModifiedTime(dir, dir.lastModifiedTime - 5000); + await promiseWritePointer(ID1); + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + await promiseWriteWebExtension(dir.path, { + manifest: { + version: "1.0", + browser_specific_settings: { gecko: { id: ID2 } }, + }, + }); + setExtensionModifiedTime(dir, dir.lastModifiedTime - 5000); + + await promiseRestartManager(); + + let [a1, a2] = await AddonManager.getAddonsByIDs([ID1, ID2]); + equal(a1, null); + equal(a2, null); + + let source = sourceDir.clone(); + source.append(ID1); + ok(source.exists()); + + let pointer = profileDir.clone(); + pointer.append(ID1); + ok(!pointer.exists()); +}); + +// Removing the pointer file should uninstall the add-on +add_task(async function test_remove_pointer() { + let dir = sourceDir.clone(); + dir.append(ID1); + + await promiseWriteWebExtension(dir.path, { + manifest: { + version: "1.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + + setExtensionModifiedTime(dir, dir.lastModifiedTime - 5000); + await promiseWritePointer(ID1); + + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + let pointer = profileDir.clone(); + pointer.append(ID1); + pointer.remove(false); + + await promiseRestartManager(); + + addon = await AddonManager.getAddonByID(ID1); + equal(addon, null); +}); + +// Removing the pointer file and replacing it with a directory should work +add_task(async function test_replace_pointer() { + await promiseWritePointer(ID1); + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + let pointer = profileDir.clone(); + pointer.append(ID1); + pointer.remove(false); + + await promiseWriteWebExtension(PathUtils.join(profileDir.path, ID1), { + manifest: { + version: "2.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + + await promiseRestartManager(); + + addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "2.0"); + + await addon.uninstall(); +}); + +// Changes to the source files should be detected +add_task(async function test_change_pointer_sources() { + await promiseWritePointer(ID1); + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + let dir = sourceDir.clone(); + dir.append(ID1); + await promiseWriteWebExtension(dir.path, { + manifest: { + version: "2.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + setExtensionModifiedTime(dir, dir.lastModifiedTime - 5000); + + await promiseRestartManager(); + + addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "2.0"); + + await addon.uninstall(); +}); + +// Removing the add-on the pointer file points at should uninstall the add-on +add_task(async function test_remove_pointer_target() { + let target = PathUtils.join(sourceDir.path, ID1); + await promiseWriteWebExtension(target, { + manifest: { + version: "1.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + await promiseWritePointer(ID1); + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + notEqual(addon, null); + equal(addon.version, "1.0"); + + await IOUtils.remove(target, { recursive: true }); + + await promiseRestartManager(); + + addon = await AddonManager.getAddonByID(ID1); + equal(addon, null); + + let pointer = profileDir.clone(); + pointer.append(ID1); + ok(!pointer.exists()); +}); + +// Tests that installing a new add-on by pointer with a relative path works +add_task(async function test_new_relative_pointer() { + let target = PathUtils.join(sourceDir.path, ID1); + await promiseWriteWebExtension(target, { + manifest: { + version: "1.0", + browser_specific_settings: { gecko: { id: ID1 } }, + }, + }); + await promiseWriteRelativePointer(ID1); + await promiseRestartManager(); + + let addon = await AddonManager.getAddonByID(ID1); + equal(addon.version, "1.0"); + + let { file } = addon.getResourceURI().QueryInterface(Ci.nsIFileURL); + equal(file.parent.path, sourceDir.path); + + let rootUri = do_get_addon_root_uri(sourceDir, ID1); + let uri = addon.getResourceURI(); + equal(uri.spec, rootUri); + + // Check that upgrade is disabled for addons installed by file-pointers. + equal(addon.permissions & AddonManager.PERM_CAN_UPGRADE, 0); +}); |