Bug 1525516 - Fix bootstrapped extension tests after bug 1525445 broke them; rs=bustage-fix
authorGeoff Lankow <geoff@darktrojan.net>
Fri, 08 Feb 2019 16:57:34 +1300
changeset 34486 f430ecd9d97d67cc38b694be0cbf8c7c93cc3204
parent 34485 c77b06a780fba9dca82b265cdfb89ad844ee2a78
child 34487 13f5e1afe5a3691980b9671c0ebf5c6de7838e6b
push id390
push userclokep@gmail.com
push dateMon, 20 May 2019 17:04:42 +0000
reviewersbustage-fix
bugs1525516, 1525445
Bug 1525516 - Fix bootstrapped extension tests after bug 1525445 broke them; rs=bustage-fix
common/test/xpcshell/head_addons.js
common/test/xpcshell/test_bootstrap.js
common/test/xpcshell/test_bootstrap_const.js
common/test/xpcshell/test_bootstrap_globals.js
common/test/xpcshell/test_bootstrapped_chrome_manifest.js
common/test/xpcshell/test_manifest_locales.js
common/test/xpcshell/xpcshell.ini
--- a/common/test/xpcshell/head_addons.js
+++ b/common/test/xpcshell/head_addons.js
@@ -51,19 +51,17 @@ ChromeUtils.defineModuleGetter(this, "Te
 
 XPCOMUtils.defineLazyServiceGetter(this, "aomStartup",
                                    "@mozilla.org/addons/addon-manager-startup;1",
                                    "amIAddonManagerStartup");
 
 const {
   createAppInfo,
   createHttpServer,
-  createInstallRDF,
   createTempWebExtensionFile,
-  createUpdateRDF,
   getFileForAddon,
   manuallyInstall,
   manuallyUninstall,
   overrideBuiltIns,
   promiseAddonEvent,
   promiseCompleteAllInstalls,
   promiseCompleteInstall,
   promiseConsoleOutput,
@@ -822,17 +820,17 @@ function isExtensionInBootstrappedList(a
  * @param   aId
  *          An optional string to override the default installation aId
  * @param   aExtraFile
  *          An optional dummy file to create in the directory
  * @return  An nsIFile for the directory in which the add-on is installed.
  */
 async function promiseWriteInstallRDFToDir(aData, aDir, aId = aData.id, aExtraFile = null) {
   let files = {
-    "install.rdf": AddonTestUtils.createInstallRDF(aData),
+    "install.rdf": createInstallRDF(aData),
   };
   if (typeof aExtraFile === "object")
     Object.assign(files, aExtraFile);
   else
     files[aExtraFile] = "";
 
   let dir = aDir.clone();
   dir.append(aId);
@@ -855,17 +853,17 @@ async function promiseWriteInstallRDFToD
  * @param   aId
  *          An optional string to override the default installation aId
  * @param   aExtraFile
  *          An optional dummy file to create in the extension
  * @return  A file pointing to where the extension was installed
  */
 async function promiseWriteInstallRDFToXPI(aData, aDir, aId = aData.id, aExtraFile = null) {
   let files = {
-    "install.rdf": AddonTestUtils.createInstallRDF(aData),
+    "install.rdf": createInstallRDF(aData),
   };
   if (typeof aExtraFile === "object")
     Object.assign(files, aExtraFile);
   else
   if (aExtraFile)
     files[aExtraFile] = "";
 
   if (!aDir.exists())
@@ -1376,8 +1374,124 @@ function mockPluginHost(plugins) {
 
 async function setInitialState(addon, initialState) {
   if (initialState.userDisabled) {
     await addon.disable();
   } else if (initialState.userDisabled === false) {
     await addon.enable();
   }
 }
+
+/**
+ * Escapes any occurrences of &, ", < or > with XML entities.
+ *
+ * @param {string} str
+ *        The string to escape.
+ * @returns {string} The escaped string.
+ */
+function escapeXML(str) {
+  let replacements = {"&": "&amp;", '"': "&quot;", "'": "&apos;", "<": "&lt;", ">": "&gt;"};
+  return String(str).replace(/[&"''<>]/g, m => replacements[m]);
+}
+
+/**
+ * A tagged template function which escapes any XML metacharacters in
+ * interpolated values.
+ *
+ * @param {Array<string>} strings
+ *        An array of literal strings extracted from the templates.
+ * @param {Array} values
+ *        An array of interpolated values extracted from the template.
+ * @returns {string}
+ *        The result of the escaped values interpolated with the literal
+ *        strings.
+ */
+function escaped(strings, ...values) {
+  let result = [];
+
+  for (let [i, string] of strings.entries()) {
+    result.push(string);
+    if (i < values.length) {
+      result.push(escapeXML(values[i]));
+    }
+  }
+
+  return result.join("");
+}
+
+function _writeProps(obj, props, indent = "  ") {
+  let items = [];
+  for (let prop of props) {
+    if (obj[prop] !== undefined)
+      items.push(escaped`${indent}<em:${prop}>${obj[prop]}</em:${prop}>\n`);
+  }
+  return items.join("");
+}
+
+function _writeArrayProps(obj, props, indent = "  ") {
+  let items = [];
+  for (let prop of props) {
+    for (let val of obj[prop] || [])
+      items.push(escaped`${indent}<em:${prop}>${val}</em:${prop}>\n`);
+  }
+  return items.join("");
+}
+
+function _writeLocaleStrings(data) {
+  let items = [];
+
+  items.push(this._writeProps(data, ["name", "description", "creator", "homepageURL"]));
+  items.push(this._writeArrayProps(data, ["developer", "translator", "contributor"]));
+
+  return items.join("");
+}
+
+function createInstallRDF(data) {
+  let defaults = {
+    bootstrap: true,
+    version: "1.0",
+    name: `Test Extension ${data.id}`,
+    targetApplications: [
+      {
+        "id": "xpcshell@tests.mozilla.org",
+        "minVersion": "1",
+        "maxVersion": "64.*",
+      },
+    ],
+  };
+
+  var rdf = '<?xml version="1.0"?>\n';
+  rdf += '<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\n' +
+         '     xmlns:em="http://www.mozilla.org/2004/em-rdf#">\n';
+
+  rdf += '<Description about="urn:mozilla:install-manifest">\n';
+
+  data = Object.assign({}, defaults, data);
+
+  let props = ["id", "version", "type", "internalName", "updateURL",
+               "optionsURL", "optionsType", "aboutURL", "iconURL",
+               "skinnable", "bootstrap", "strictCompatibility"];
+  rdf += _writeProps(data, props);
+
+  rdf += _writeLocaleStrings(data);
+
+  for (let platform of data.targetPlatforms || [])
+    rdf += escaped`<em:targetPlatform>${platform}</em:targetPlatform>\n`;
+
+  for (let app of data.targetApplications || []) {
+    rdf += "<em:targetApplication><Description>\n";
+    rdf += _writeProps(app, ["id", "minVersion", "maxVersion"]);
+    rdf += "</Description></em:targetApplication>\n";
+  }
+
+  for (let localized of data.localized || []) {
+    rdf += "<em:localized><Description>\n";
+    rdf += _writeArrayProps(localized, ["locale"]);
+    rdf += _writeLocaleStrings(localized);
+    rdf += "</Description></em:localized>\n";
+  }
+
+  for (let dep of data.dependencies || [])
+    rdf += escaped`<em:dependency><Description em:id="${dep}"/></em:dependency>\n`;
+
+  rdf += "</Description>\n</RDF>\n";
+  return rdf;
+}
--- a/common/test/xpcshell/test_bootstrap.js
+++ b/common/test/xpcshell/test_bootstrap.js
@@ -29,54 +29,54 @@ const profileDir = gProfD.clone();
 profileDir.append("extensions");
 const userExtDir = gProfD.clone();
 userExtDir.append("extensions2");
 userExtDir.append(gAppInfo.ID);
 registerDirectory("XREUSysExt", userExtDir.parent);
 
 const ADDONS = {
   test_bootstrap1_1: {
-    "install.rdf": {
+    "install.rdf": createInstallRDF({
       id: "bootstrap1@tests.mozilla.org",
 
       name: "Test Bootstrap 1",
 
       iconURL: "chrome://foo/skin/icon.png",
       aboutURL: "chrome://foo/content/about.xul",
       optionsURL: "chrome://foo/content/options.xul",
-    },
+    }),
     "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS,
   },
   test_bootstrap1_2: {
-    "install.rdf": {
+    "install.rdf": createInstallRDF({
       id: "bootstrap1@tests.mozilla.org",
       version: "2.0",
 
       name: "Test Bootstrap 1",
-    },
+    }),
     "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS,
   },
   test_bootstrap1_3: {
-    "install.rdf": {
+    "install.rdf": createInstallRDF({
       id: "bootstrap1@tests.mozilla.org",
       version: "3.0",
 
       name: "Test Bootstrap 1",
 
       targetApplications: [{
         id: "undefined",
         minVersion: "1",
         maxVersion: "1"}],
-    },
+    }),
     "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS,
   },
   test_bootstrap2_1: {
-    "install.rdf": {
+    "install.rdf": createInstallRDF({
       id: "bootstrap2@tests.mozilla.org",
-    },
+    }),
     "bootstrap.js": BOOTSTRAP_MONITOR_BOOTSTRAP_JS,
   },
 };
 
 var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]});
 
 const XPIS = {};
 for (let [name, addon] of Object.entries(ADDONS)) {
@@ -1067,17 +1067,17 @@ add_task(async function test_22() {
 
 // Tests that installing from a URL doesn't require a restart
 add_task(async function test_23() {
   prepare_test({}, [
     "onNewInstall",
   ]);
 
   let url = "http://example.com/addons/test_bootstrap1_1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url, {});
 
   ensure_test_completed();
 
   notEqual(install, null);
 
   await new Promise(resolve => {
     prepare_test({}, [
       "onDownloadStarted",
--- a/common/test/xpcshell/test_bootstrap_const.js
+++ b/common/test/xpcshell/test_bootstrap_const.js
@@ -1,19 +1,19 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
 
 const ADDONS = {
   test_bootstrap_const: {
-    "install.rdf": {
+    "install.rdf": createInstallRDF({
       "id": "bootstrap@tests.mozilla.org",
-    },
+    }),
     "bootstrap.js": "var {Services} = ChromeUtils.import(\"resource://gre/modules/Services.jsm\");\n\nconst install = function() {\n  Services.obs.notifyObservers(null, \"addon-install\");\n};\n",
   },
 };
 
 add_task(async function() {
   await promiseStartupManager();
 
   let sawInstall = false;
--- a/common/test/xpcshell/test_bootstrap_globals.js
+++ b/common/test/xpcshell/test_bootstrap_globals.js
@@ -4,19 +4,19 @@
 
 // This verifies that bootstrap.js has the expected globals defined
 var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
 
 const ADDONS = {
   bootstrap_globals: {
-    "install.rdf": {
+    "install.rdf": createInstallRDF({
       "id": "bootstrap_globals@tests.mozilla.org",
-    },
+    }),
     "bootstrap.js": String.raw`var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var seenGlobals = new Set();
 var scope = this;
 function checkGlobal(name, type) {
   if (scope[name] && typeof(scope[name]) == type)
     seenGlobals.add(name);
 }
--- a/common/test/xpcshell/test_bootstrapped_chrome_manifest.js
+++ b/common/test/xpcshell/test_bootstrapped_chrome_manifest.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const ADDON = {
-  "install.rdf": {
+  "install.rdf": createInstallRDF({
     "id": "bug675371@tests.mozilla.org",
-  },
+  }),
   "chrome.manifest": `content bug675371 .`,
   "test.js": `var active = true;`,
 };
 
 add_task(async function run_test() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
   await promiseStartupManager();
 });
--- a/common/test/xpcshell/test_manifest_locales.js
+++ b/common/test/xpcshell/test_manifest_locales.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 const ID = "bug397778@tests.mozilla.org";
 
-const ADDON = {
+const ADDON = createInstallRDF({
   id: "bug397778@tests.mozilla.org",
   version: "1.0",
   name: "Fallback Name",
   description: "Fallback Description",
   bootstrap: true,
 
   targetApplications: [{
     id: "xpcshell@tests.mozilla.org",
@@ -53,17 +53,17 @@ const ADDON = {
       description: "en Description",
     },
     {
       locale: ["en-CA"],
       name: "en-CA Name",
       description: "en-CA Description",
     },
   ],
-};
+});
 
 add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1");
   Services.locale.requestedLocales = ["fr-FR"];
 
   await promiseStartupManager();
   await promiseInstallXPI(ADDON);
 });
--- a/common/test/xpcshell/xpcshell.ini
+++ b/common/test/xpcshell/xpcshell.ini
@@ -1,10 +1,9 @@
 [DEFAULT]
-skip-if = true # all skipped due to bug 1525516
 tags = addons
 head = head_addons.js
 support-files =
   data/**
 
 [test_bootstrap.js]
 [test_bootstrap_const.js]
 [test_bootstrap_globals.js]