Bug 1300992 - Part 2: Return the filtered profile result, r?MattN draft
authorsteveck-chung <schung@mozilla.com>
Fri, 06 Jan 2017 15:37:28 +0800
changeset 463432 e5a555ecca01cdeff0200d16625ded9245bcac1d
parent 463431 6212470148077c115740989102267774823e592e
child 542673 66a85dcd70ffccf626707070c438391698f764db
push id42060
push userbmo:schung@mozilla.com
push dateThu, 19 Jan 2017 02:52:54 +0000
reviewersMattN
bugs1300992
milestone53.0a1
Bug 1300992 - Part 2: Return the filtered profile result, r?MattN MozReview-Commit-ID: 828bJhAGAAb
browser/extensions/formautofill/FormAutofillParent.jsm
browser/extensions/formautofill/ProfileStorage.jsm
browser/extensions/formautofill/test/unit/test_profileStorage.js
--- a/browser/extensions/formautofill/FormAutofillParent.jsm
+++ b/browser/extensions/formautofill/FormAutofillParent.jsm
@@ -130,29 +130,23 @@ let FormAutofillParent = {
    * @param  {string} data.searchString
    *         The typed string for filtering out the matched profile.
    * @param  {string} data.info
    *         The input autocomplete property's information.
    * @param  {nsIFrameMessageManager} target
    *         Content's message manager.
    */
   _getProfiles({searchString, info}, target) {
-    // TODO: These mock data should be replaced by form autofill API
-    // let profiles = this._profileStore.getAll();
-    let profiles = [{
-      guid: "test-guid-1",
-      organization: "Sesame Street",
-      streetAddress: "123 Sesame Street.",
-      tel: "1-345-345-3456",
-    }, {
-      guid: "test-guid-2",
-      organization: "Mozilla",
-      streetAddress: "331 E. Evelyn Avenue",
-      tel: "1-650-903-0800",
-    }];
+    let profiles = [];
+
+    if (info && info.fieldName) {
+      profiles = this._profileStore.getByFilter({searchString, info});
+    } else {
+      profiles = this._profileStore.getAll();
+    }
 
     target.messageManager.sendAsyncMessage("FormAutofill:Profiles", profiles);
   },
 
   /**
    * Transforms a word with hyphen into camel case.
    * (e.g. transforms "address-type" into "addressType".)
    *
--- a/browser/extensions/formautofill/ProfileStorage.jsm
+++ b/browser/extensions/formautofill/ProfileStorage.jsm
@@ -61,16 +61,30 @@ const VALID_FIELDS = [
   "addressLevel2",
   "addressLevel1",
   "postalCode",
   "country",
   "tel",
   "email",
 ];
 
+// TODO: Remove this once we can add profile from preference.
+const MOCK_MODE = false;
+const MOCK_STORAGE = [{
+  guid: "test-guid-1",
+  organization: "Sesame Street",
+  streetAddress: "123 Sesame Street.",
+  tel: "1-345-345-3456",
+}, {
+  guid: "test-guid-2",
+  organization: "Mozilla",
+  streetAddress: "331 E. Evelyn Avenue",
+  tel: "1-650-903-0800",
+}];
+
 function ProfileStorage(path) {
   this._path = path;
 }
 
 ProfileStorage.prototype = {
   /**
    * Loads the profile data from file to memory.
    *
@@ -205,24 +219,53 @@ ProfileStorage.prototype = {
    */
   getAll() {
     this._store.ensureDataReady();
 
     // Profiles are cloned to avoid accidental modifications from outside.
     return this._store.data.profiles.map(this._clone);
   },
 
+  /**
+   * Returns the filtered profiles based on input's information and searchString.
+   *
+   * @returns {Array.<Profile>}
+   *          An array containing clones of matched profiles.
+   */
+  getByFilter({info, searchString}) {
+    this._store.ensureDataReady();
+
+    // Profiles are cloned to avoid accidental modifications from outside.
+    return this._findByFilter({info, searchString}).map(this._clone);
+  },
+
   _clone(profile) {
     return Object.assign({}, profile);
   },
 
   _findByGUID(guid) {
     return this._store.data.profiles.find(profile => profile.guid == guid);
   },
 
+  _findByFilter({info, searchString}) {
+    let profiles = MOCK_MODE ? MOCK_STORAGE : this._store.data.profiles;
+    return profiles.filter(profile => {
+      // Return true if string is not provided and field exists.
+      // TODO: We'll need to check if the address is for billing or shipping.
+      let name = info.fieldName;
+
+      if (!searchString) {
+        return !!profile[name];
+      }
+
+      let re = new RegExp("^" + searchString, "i");
+      return re.test(profile[name]);
+    });
+  },
+
   _normalizeProfile(profile) {
     let result = {};
     for (let key in profile) {
       if (!VALID_FIELDS.includes(key)) {
         throw new Error(`"${key}" is not a valid field.`);
       }
       if (typeof profile[key] !== "string" &&
           typeof profile[key] !== "number") {
--- a/browser/extensions/formautofill/test/unit/test_profileStorage.js
+++ b/browser/extensions/formautofill/test/unit/test_profileStorage.js
@@ -104,16 +104,43 @@ add_task(function* test_get() {
   // Modifying output shouldn't affect the storage.
   profile.organization = "test";
   do_check_profile_matches(profileStorage.get(guid), TEST_PROFILE_1);
 
   Assert.throws(() => profileStorage.get("INVALID_GUID"),
     /No matching profile\./);
 });
 
+add_task(function* test_getByFilter() {
+  let path = getTempFile(TEST_STORE_FILE_NAME).path;
+  yield prepareTestProfiles(path);
+
+  let profileStorage = new ProfileStorage(path);
+  yield profileStorage.initialize();
+
+  let filter = {fieldName: "streetAddress", searchString: "Some"};
+  let profiles = profileStorage.getByFilter(filter);
+  do_check_eq(profiles.length, 1);
+  do_check_profile_matches(profiles[0], TEST_PROFILE_2);
+
+  filter = {fieldName: "country", searchString: "u"};
+  profiles = profileStorage.getByFilter(filter);
+  do_check_eq(profiles.length, 2);
+  do_check_profile_matches(profiles[0], TEST_PROFILE_1);
+  do_check_profile_matches(profiles[1], TEST_PROFILE_2);
+
+  filter = {fieldName: "streetAddress", searchString: "test"};
+  profiles = profileStorage.getByFilter(filter);
+  do_check_eq(profiles.length, 0);
+
+  filter = {fieldName: "streetAddress", searchString: ""};
+  profiles = profileStorage.getByFilter(filter);
+  do_check_eq(profiles.length, 2);
+});
+
 add_task(function* test_add() {
   let path = getTempFile(TEST_STORE_FILE_NAME).path;
   yield prepareTestProfiles(path);
 
   let profileStorage = new ProfileStorage(path);
   yield profileStorage.initialize();
 
   let profiles = profileStorage.getAll();