Bug 1300988 - Part 2: Move MockDocument to toolkit/modules and refactor unit test in passwordmgr. r=MattN draft
authorSteve Chung <schung@mozilla.com>
Tue, 18 Oct 2016 18:45:24 +0800
changeset 426803 bf23ad4432cc9a30fb1295dd6ed688a11ab597e3
parent 426802 1c5279fc5590ec2159b4b2a19c40ba2d84539c61
child 426804 8e1ce7951cd1f47731dea9536f519300115e4ebf
push id32805
push userschung@mozilla.com
push dateWed, 19 Oct 2016 05:07:51 +0000
reviewersMattN
bugs1300988
milestone52.0a1
Bug 1300988 - Part 2: Move MockDocument to toolkit/modules and refactor unit test in passwordmgr. r=MattN MozReview-Commit-ID: 16jZ7UzhVDf
toolkit/components/passwordmgr/test/unit/head.js
toolkit/modules/moz.build
toolkit/modules/tests/MockDocument.jsm
--- a/toolkit/components/passwordmgr/test/unit/head.js
+++ b/toolkit/components/passwordmgr/test/unit/head.js
@@ -8,16 +8,17 @@
 //// Globals
 
 let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/LoginRecipes.jsm");
 Cu.import("resource://gre/modules/LoginHelper.jsm");
+Cu.import("resource://testing-common/MockDocument.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths",
                                   "resource://gre/modules/DownloadPaths.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
@@ -92,54 +93,16 @@ function getTempFile(aLeafName)
 ////////////////////////////////////////////////////////////////////////////////
 
 const RecipeHelpers = {
   initNewParent() {
     return (new LoginRecipesParent({ defaults: null })).initializationPromise;
   },
 };
 
-const MockDocument = {
-  /**
-   * Create a document for the given URL containing the given HTML with the ownerDocument of all <form>s having a mocked location.
-   */
-  createTestDocument(aDocumentURL, aContent = "<form>", aType = "text/html") {
-    let parser = Cc["@mozilla.org/xmlextras/domparser;1"].
-                 createInstance(Ci.nsIDOMParser);
-    parser.init();
-    let parsedDoc = parser.parseFromString(aContent, aType);
-
-    for (let element of parsedDoc.forms) {
-      this.mockOwnerDocumentProperty(element, parsedDoc, aDocumentURL);
-    }
-    return parsedDoc;
-  },
-
-  mockOwnerDocumentProperty(aElement, aDoc, aURL) {
-    // Mock the document.location object so we can unit test without a frame. We use a proxy
-    // instead of just assigning to the property since it's not configurable or writable.
-    let document = new Proxy(aDoc, {
-      get(target, property, receiver) {
-        // document.location is normally null when a document is outside of a "browsing context".
-        // See https://html.spec.whatwg.org/#the-location-interface
-        if (property == "location") {
-          return new URL(aURL);
-        }
-        return target[property];
-      },
-    });
-
-    // Assign element.ownerDocument to the proxy so document.location works.
-    Object.defineProperty(aElement, "ownerDocument", {
-      value: document,
-    });
-  },
-
-};
-
 //// Initialization functions common to all tests
 
 add_task(function* test_common_initialize()
 {
   // Before initializing the service for the first time, we should copy the key
   // file required to decrypt the logins contained in the SQLite databases used
   // by migration tests.  This file is not required for the other tests.
   yield OS.File.copy(do_get_file("data/key3.db").path,
--- a/toolkit/modules/moz.build
+++ b/toolkit/modules/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
 BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
 MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
 MOCHITEST_CHROME_MANIFESTS += ['tests/chrome/chrome.ini']
 
 TESTING_JS_MODULES += [
+    'tests/MockDocument.jsm',
     'tests/PromiseTestUtils.jsm',
     'tests/xpcshell/TestIntegration.jsm',
 ]
 
 SPHINX_TREES['toolkit_modules'] = 'docs'
 
 EXTRA_JS_MODULES += [
     'addons/MatchPattern.jsm',
copy from toolkit/components/passwordmgr/test/unit/head.js
copy to toolkit/modules/tests/MockDocument.jsm
--- a/toolkit/components/passwordmgr/test/unit/head.js
+++ b/toolkit/modules/tests/MockDocument.jsm
@@ -1,106 +1,19 @@
 /**
- * Provides infrastructure for automated login components tests.
+ * Provides infrastructure for tests that would require mock document.
  */
 
 "use strict";
 
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/LoginRecipes.jsm");
-Cu.import("resource://gre/modules/LoginHelper.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths",
-                                  "resource://gre/modules/DownloadPaths.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
-                                  "resource://gre/modules/FileUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OS",
-                                  "resource://gre/modules/osfile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
-                                  "resource://gre/modules/Promise.jsm");
-
-const LoginInfo =
-      Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
-                             "nsILoginInfo", "init");
-
-// Import LoginTestUtils.jsm as LoginTestUtils.
-XPCOMUtils.defineLazyModuleGetter(this, "LoginTestUtils",
-                                  "resource://testing-common/LoginTestUtils.jsm");
-LoginTestUtils.Assert = Assert;
-const TestData = LoginTestUtils.testData;
-const newPropertyBag = LoginHelper.newPropertyBag;
-
-/**
- * All the tests are implemented with add_task, this starts them automatically.
- */
-function run_test()
-{
-  do_get_profile();
-  run_next_test();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Global helpers
-
-// Some of these functions are already implemented in other parts of the source
-// tree, see bug 946708 about sharing more code.
+this.EXPORTED_SYMBOLS = ["MockDocument"]
 
-// While the previous test file should have deleted all the temporary files it
-// used, on Windows these might still be pending deletion on the physical file
-// system.  Thus, start from a new base number every time, to make a collision
-// with a file that is still pending deletion highly unlikely.
-let gFileCounter = Math.floor(Math.random() * 1000000);
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
-/**
- * Returns a reference to a temporary file, that is guaranteed not to exist, and
- * to have never been created before.
- *
- * @param aLeafName
- *        Suggested leaf name for the file to be created.
- *
- * @return nsIFile pointing to a non-existent file in a temporary directory.
- *
- * @note It is not enough to delete the file if it exists, or to delete the file
- *       after calling nsIFile.createUnique, because on Windows the delete
- *       operation in the file system may still be pending, preventing a new
- *       file with the same name to be created.
- */
-function getTempFile(aLeafName)
-{
-  // Prepend a serial number to the extension in the suggested leaf name.
-  let [base, ext] = DownloadPaths.splitBaseNameAndExtension(aLeafName);
-  let leafName = base + "-" + gFileCounter + ext;
-  gFileCounter++;
-
-  // Get a file reference under the temporary directory for this test file.
-  let file = FileUtils.getFile("TmpD", [leafName]);
-  do_check_false(file.exists());
-
-  do_register_cleanup(function () {
-    if (file.exists()) {
-      file.remove(false);
-    }
-  });
-
-  return file;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-const RecipeHelpers = {
-  initNewParent() {
-    return (new LoginRecipesParent({ defaults: null })).initializationPromise;
-  },
-};
+Cu.importGlobalProperties(["URL"]);
 
 const MockDocument = {
   /**
    * Create a document for the given URL containing the given HTML with the ownerDocument of all <form>s having a mocked location.
    */
   createTestDocument(aDocumentURL, aContent = "<form>", aType = "text/html") {
     let parser = Cc["@mozilla.org/xmlextras/domparser;1"].
                  createInstance(Ci.nsIDOMParser);
@@ -130,47 +43,8 @@ const MockDocument = {
     // Assign element.ownerDocument to the proxy so document.location works.
     Object.defineProperty(aElement, "ownerDocument", {
       value: document,
     });
   },
 
 };
 
-//// Initialization functions common to all tests
-
-add_task(function* test_common_initialize()
-{
-  // Before initializing the service for the first time, we should copy the key
-  // file required to decrypt the logins contained in the SQLite databases used
-  // by migration tests.  This file is not required for the other tests.
-  yield OS.File.copy(do_get_file("data/key3.db").path,
-                     OS.Path.join(OS.Constants.Path.profileDir, "key3.db"));
-
-  // Ensure that the service and the storage module are initialized.
-  yield Services.logins.initializationPromise;
-
-  // Ensure that every test file starts with an empty database.
-  LoginTestUtils.clearData();
-
-  // Clean up after every test.
-  do_register_cleanup(() => LoginTestUtils.clearData());
-});
-
-/**
- * Compare two FormLike to see if they represent the same information. Elements
- * are compared using their @id attribute.
- */
-function formLikeEqual(a, b) {
-  Assert.strictEqual(Object.keys(a).length, Object.keys(b).length,
-                     "Check the formLikes have the same number of properties");
-
-  for (let propName of Object.keys(a)) {
-    if (propName == "elements") {
-      Assert.strictEqual(a.elements.length, b.elements.length, "Check element count");
-      for (let i = 0; i < a.elements.length; i++) {
-        Assert.strictEqual(a.elements[i].id, b.elements[i].id, "Check element " + i + " id");
-      }
-      continue;
-    }
-    Assert.strictEqual(a[propName], b[propName], "Compare formLike " + propName + " property");
-  }
-}