summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/webextensions/test/xpcshell/test_proxies.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/webextensions/test/xpcshell/test_proxies.js')
-rw-r--r--toolkit/mozapps/webextensions/test/xpcshell/test_proxies.js240
1 files changed, 240 insertions, 0 deletions
diff --git a/toolkit/mozapps/webextensions/test/xpcshell/test_proxies.js b/toolkit/mozapps/webextensions/test/xpcshell/test_proxies.js
new file mode 100644
index 000000000..7b28c78f2
--- /dev/null
+++ b/toolkit/mozapps/webextensions/test/xpcshell/test_proxies.js
@@ -0,0 +1,240 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Tests the semantics of extension proxy files and symlinks
+
+Components.utils.import("resource://gre/modules/AppConstants.jsm");
+Components.utils.import("resource://gre/modules/osfile.jsm");
+
+var ADDONS = [
+ {
+ id: "proxy1@tests.mozilla.org",
+ dirId: "proxy1@tests.mozilla.com",
+ type: "proxy"
+ },
+ {
+ id: "proxy2@tests.mozilla.org",
+ type: "proxy"
+ },
+ {
+ id: "symlink1@tests.mozilla.org",
+ dirId: "symlink1@tests.mozilla.com",
+ type: "symlink"
+ },
+ {
+ id: "symlink2@tests.mozilla.org",
+ type: "symlink"
+ }
+];
+
+var METADATA = {
+ version: "2.0",
+ targetApplications: [{
+ id: "xpcshell@tests.mozilla.org",
+ minVersion: "2",
+ maxVersion: "2"
+ }]
+}
+
+const ios = AM_Cc["@mozilla.org/network/io-service;1"].getService(AM_Ci.nsIIOService);
+
+const LocalFile = Components.Constructor("@mozilla.org/file/local;1",
+ "nsILocalFile", "initWithPath");
+const Process = Components.Constructor("@mozilla.org/process/util;1",
+ "nsIProcess", "init");
+
+const gHaveSymlinks = AppConstants.platform != "win";
+
+
+function createSymlink(aSource, aDest) {
+ if (aSource instanceof AM_Ci.nsIFile)
+ aSource = aSource.path;
+ if (aDest instanceof AM_Ci.nsIFile)
+ aDest = aDest.path;
+
+ return OS.File.unixSymLink(aSource, aDest);
+}
+
+function writeFile(aData, aFile) {
+ if (!aFile.parent.exists())
+ aFile.parent.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+
+ var fos = AM_Cc["@mozilla.org/network/file-output-stream;1"].
+ createInstance(AM_Ci.nsIFileOutputStream);
+ fos.init(aFile,
+ FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE,
+ FileUtils.PERMS_FILE, 0);
+ fos.write(aData, aData.length);
+ fos.close();
+}
+
+function checkAddonsExist() {
+ for (let addon of ADDONS) {
+ let file = addon.directory.clone();
+ file.append("install.rdf");
+ do_check_true(file.exists(), Components.stack.caller);
+ }
+}
+
+
+const profileDir = gProfD.clone();
+profileDir.append("extensions");
+
+
+function run_test() {
+ createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
+
+ add_task(run_proxy_tests);
+
+ if (gHaveSymlinks)
+ add_task(run_symlink_tests);
+
+ run_next_test();
+}
+
+function* run_proxy_tests() {
+ if (!gHaveSymlinks) {
+ ADDONS = ADDONS.filter(a => a.type != "symlink");
+ }
+
+ for (let addon of ADDONS) {
+ addon.directory = gTmpD.clone();
+ addon.directory.append(addon.id);
+
+ addon.proxyFile = profileDir.clone();
+ addon.proxyFile.append(addon.dirId || addon.id);
+
+ METADATA.id = addon.id;
+ METADATA.name = addon.id;
+ writeInstallRDFToDir(METADATA, gTmpD);
+
+ if (addon.type == "proxy") {
+ writeFile(addon.directory.path, addon.proxyFile)
+ }
+ else if (addon.type == "symlink") {
+ yield createSymlink(addon.directory, addon.proxyFile)
+ }
+ }
+
+ startupManager();
+
+ // Check that all add-ons original sources still exist after invalid
+ // add-ons have been removed at startup.
+ checkAddonsExist();
+
+ return new Promise(resolve => {
+ AddonManager.getAddonsByIDs(ADDONS.map(addon => addon.id), resolve);
+ }).then(addons => {
+ try {
+ for (let [i, addon] of addons.entries()) {
+ // Ensure that valid proxied add-ons were installed properly on
+ // platforms that support the installation method.
+ print(ADDONS[i].id,
+ ADDONS[i].dirId,
+ ADDONS[i].dirId != null,
+ ADDONS[i].type == "symlink");
+ do_check_eq(addon == null,
+ ADDONS[i].dirId != null);
+
+ if (addon != null) {
+ let fixURL = url => {
+ if (AppConstants.platform == "macosx")
+ return url.replace(RegExp(`^file:///private/`), "file:///");
+ return url;
+ };
+
+ // Check that proxied add-ons do not have upgrade permissions.
+ do_check_eq(addon.permissions & AddonManager.PERM_CAN_UPGRADE, 0);
+
+ // Check that getResourceURI points to the right place.
+ do_check_eq(ios.newFileURI(ADDONS[i].directory).spec,
+ fixURL(addon.getResourceURI().spec),
+ `Base resource URL resolves as expected`);
+
+ let file = ADDONS[i].directory.clone();
+ file.append("install.rdf");
+
+ do_check_eq(ios.newFileURI(file).spec,
+ fixURL(addon.getResourceURI("install.rdf").spec),
+ `Resource URLs resolve as expected`);
+
+ addon.uninstall();
+ }
+ }
+
+ // Check that original sources still exist after explicit uninstall.
+ restartManager();
+ checkAddonsExist();
+
+ shutdownManager();
+
+ // Check that all of the proxy files have been removed and remove
+ // the original targets.
+ for (let addon of ADDONS) {
+ equal(addon.proxyFile.exists(), addon.dirId != null,
+ `Proxy file ${addon.proxyFile.path} should exist?`);
+ addon.directory.remove(true);
+ try {
+ addon.proxyFile.remove(false);
+ } catch (e) {}
+ }
+ }
+ catch (e) {
+ do_throw(e);
+ }
+ });
+}
+
+function* run_symlink_tests() {
+ // Check that symlinks are not followed out of a directory tree
+ // when deleting an add-on.
+
+ METADATA.id = "unpacked@test.mozilla.org";
+ METADATA.name = METADATA.id;
+ METADATA.unpack = "true";
+
+ let tempDirectory = gTmpD.clone();
+ tempDirectory.append(METADATA.id);
+
+ let tempFile = tempDirectory.clone();
+ tempFile.append("test.txt");
+ tempFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
+
+ let addonDirectory = profileDir.clone();
+ addonDirectory.append(METADATA.id);
+
+ writeInstallRDFToDir(METADATA, profileDir);
+
+ let symlink = addonDirectory.clone();
+ symlink.append(tempDirectory.leafName);
+ yield createSymlink(tempDirectory, symlink);
+
+ // Make sure that the symlink was created properly.
+ let file = symlink.clone();
+ file.append(tempFile.leafName);
+ file.normalize();
+ do_check_eq(file.path.replace(/^\/private\//, "/"), tempFile.path);
+
+ startupManager();
+
+ return new Promise(resolve => {
+ AddonManager.getAddonByID(METADATA.id, resolve);
+ }).then(addon => {
+ do_check_neq(addon, null);
+
+ addon.uninstall();
+
+ restartManager();
+ shutdownManager();
+
+ // Check that the install directory is gone.
+ do_check_false(addonDirectory.exists());
+
+ // Check that the temp file is not gone.
+ do_check_true(tempFile.exists());
+
+ tempDirectory.remove(true);
+ });
+}
+