Bug 1379588 - Part 2: Make createRecords support creditcard. r=lchang
authorsteveck-chung <schung@mozilla.com>
Mon, 24 Jul 2017 12:16:41 +0800
changeset 420688 4c921604f3926453f1082fc0f780a40ae6cfc4d9
parent 420687 02fd97e1217ba21a2711cc9bb319b856ca974ee0
child 420689 3cad3569c8b97531bfc23af7af110178cb6f6dd5
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslchang
bugs1379588
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1379588 - Part 2: Make createRecords support creditcard. r=lchang MozReview-Commit-ID: Co4uQ04kK6L
browser/extensions/formautofill/FormAutofillContent.jsm
browser/extensions/formautofill/FormAutofillHandler.jsm
browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -372,29 +372,38 @@ var FormAutofillContent = {
     }
 
     let handler = this._formsDetails.get(formElement);
     if (!handler) {
       this.log.debug("Form element could not map to an existing handler");
       return true;
     }
 
-    let pendingAddress = handler.createProfile();
-    if (Object.keys(pendingAddress).length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD) {
-      this.log.debug(`Not saving since there are only ${Object.keys(pendingAddress).length} usable fields`);
+    let {addressRecord, creditCardRecord} = handler.createRecords();
+
+    if (!addressRecord && !creditCardRecord) {
       return true;
     }
 
-    this._onFormSubmit({
-      address: {
+    let data = {};
+    if (addressRecord) {
+      data.address = {
         guid: handler.address.filledRecordGUID,
-        record: pendingAddress,
-      },
-      // creditCard: {}
-    }, domWin);
+        record: addressRecord,
+      };
+    }
+
+    if (creditCardRecord) {
+      data.creditCard = {
+        guid: handler.creditCard.filledRecordGUID,
+        record: creditCardRecord,
+      };
+    }
+
+    this._onFormSubmit(data, domWin);
 
     return true;
   },
 
   receiveMessage({name, data}) {
     switch (name) {
       case "FormAutofill:enabledStatus": {
         if (data) {
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -398,30 +398,52 @@ FormAutofillHandler.prototype = {
         this.winUtils.removeManuallyManagedState(element, mmStateValue);
       }
     }
 
     fieldDetail.state = nextState;
   },
 
   /**
-   * Return the profile that is converted from fieldDetails and only non-empty fields
-   * are included.
+   * Return the records that is converted from address/creditCard fieldDetails and
+   * only valid form records are included.
    *
    * @returns {Object} The new profile that convert from details with trimmed result.
    */
-  createProfile() {
-    let profile = {};
+  createRecords() {
+    let records = {};
 
-    this.address.fieldDetails.forEach(detail => {
-      let element = detail.elementWeakRef.get();
-      // Remove the unnecessary spaces
-      let value = element && element.value.trim();
-      if (!value) {
+    ["address", "creditCard"].forEach(type => {
+      let details = this[type].fieldDetails;
+      if (!details || details.length == 0) {
         return;
       }
 
-      profile[detail.fieldName] = value;
+      let recordName = `${type}Record`;
+      records[recordName] = {};
+      details.forEach(detail => {
+        let element = detail.elementWeakRef.get();
+        // Remove the unnecessary spaces
+        let value = element && element.value.trim();
+        if (!value) {
+          return;
+        }
+
+        records[recordName][detail.fieldName] = value;
+      });
     });
 
-    return profile;
+    if (records.addressRecord &&
+        Object.keys(records.addressRecord).length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD) {
+      log.debug("No address record saving since there are only",
+                     Object.keys(records.addressRecord).length,
+                     "usable fields");
+      delete records.addressRecord;
+    }
+
+    if (records.creditCardRecord && !records.creditCardRecord["cc-number"]) {
+      log.debug("No credit card record saving since card number is empty");
+      delete records.creditCardRecord;
+    }
+
+    return records;
   },
 };
--- a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
+++ b/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
@@ -4,62 +4,134 @@ Cu.import("resource://formautofill/FormA
 
 const MOCK_DOC = MockDocument.createTestDocument("http://localhost:8080/test/",
                    `<form id="form1">
                       <input id="street-addr" autocomplete="street-address">
                       <input id="city" autocomplete="address-level2">
                       <input id="country" autocomplete="country">
                       <input id="email" autocomplete="email">
                       <input id="tel" autocomplete="tel">
+                      <input id="cc-name" autocomplete="cc-name">
+                      <input id="cc-number" autocomplete="cc-number">
+                      <input id="cc-exp-month" autocomplete="cc-exp-month">
+                      <input id="cc-exp-year" autocomplete="cc-exp-year">
                       <input id="submit" type="submit">
                     </form>`);
 const TARGET_ELEMENT_ID = "street-addr";
 
 const TESTCASES = [
   {
-    description: "Should not trigger saving if the number of fields is less than 3",
+    description: "Should not trigger address saving if the number of fields is less than 3",
     formValue: {
       "street-addr": "331 E. Evelyn Avenue",
       "tel": "1-650-903-0800",
     },
     expectedResult: {
       formSubmission: false,
     },
   },
   {
-    description: "Trigger profile saving",
+    description: "Should not trigger credit card saving if number is empty",
+    formValue: {
+      "cc-name": "John Doe",
+      "cc-exp-month": 12,
+      "cc-exp-year": 2000,
+    },
+    expectedResult: {
+      formSubmission: false,
+    },
+  },
+  {
+    description: "Trigger address saving",
     formValue: {
       "street-addr": "331 E. Evelyn Avenue",
       "country": "USA",
       "tel": "1-650-903-0800",
     },
     expectedResult: {
       formSubmission: true,
-      profile: {
+      records: {
         address: {
           guid: null,
           record: {
             "street-address": "331 E. Evelyn Avenue",
             "country": "USA",
             "tel": "1-650-903-0800",
           },
         },
       },
     },
   },
   {
+    description: "Trigger credit card saving",
+    formValue: {
+      "cc-name": "John Doe",
+      "cc-number": "1234567812345678",
+      "cc-exp-month": 12,
+      "cc-exp-year": 2000,
+    },
+    expectedResult: {
+      formSubmission: true,
+      records: {
+        creditCard: {
+          guid: null,
+          record: {
+            "cc-name": "John Doe",
+            "cc-number": "1234567812345678",
+            "cc-exp-month": 12,
+            "cc-exp-year": 2000,
+          },
+        },
+      },
+    },
+  },
+  {
+    description: "Trigger address and credit card saving",
+    formValue: {
+      "street-addr": "331 E. Evelyn Avenue",
+      "country": "USA",
+      "tel": "1-650-903-0800",
+      "cc-name": "John Doe",
+      "cc-number": "1234567812345678",
+      "cc-exp-month": 12,
+      "cc-exp-year": 2000,
+    },
+    expectedResult: {
+      formSubmission: true,
+      records: {
+        address: {
+          guid: null,
+          record: {
+            "street-address": "331 E. Evelyn Avenue",
+            "country": "USA",
+            "tel": "1-650-903-0800",
+          },
+        },
+        creditCard: {
+          guid: null,
+          record: {
+            "cc-name": "John Doe",
+            "cc-number": "1234567812345678",
+            "cc-exp-month": 12,
+            "cc-exp-year": 2000,
+          },
+        },
+      },
+    },
+  },
+  {
     description: "Profile saved with trimmed string",
     formValue: {
       "street-addr": "331 E. Evelyn Avenue  ",
       "country": "USA",
       "tel": "  1-650-903-0800",
     },
     expectedResult: {
       formSubmission: true,
-      profile: {
+      records: {
         address: {
           guid: null,
           record: {
             "street-address": "331 E. Evelyn Avenue",
             "country": "USA",
             "tel": "1-650-903-0800",
           },
         },
@@ -71,17 +143,17 @@ const TESTCASES = [
     formValue: {
       "street-addr": "331 E. Evelyn Avenue",
       "country": "USA",
       "email": "  ",
       "tel": "1-650-903-0800",
     },
     expectedResult: {
       formSubmission: true,
-      profile: {
+      records: {
         address: {
           guid: null,
           record: {
             "street-address": "331 E. Evelyn Avenue",
             "country": "USA",
             "tel": "1-650-903-0800",
           },
         },
@@ -96,31 +168,32 @@ add_task(async function handle_earlyform
   sinon.spy(FormAutofillContent, "_onFormSubmit");
 
   do_check_eq(FormAutofillContent.notify(fakeForm), true);
   do_check_eq(FormAutofillContent._onFormSubmit.called, false);
   FormAutofillContent._onFormSubmit.restore();
 });
 
 TESTCASES.forEach(testcase => {
-  add_task(async function check_profile_saving_is_called_correctly() {
+  add_task(async function check_records_saving_is_called_correctly() {
     do_print("Starting testcase: " + testcase.description);
 
     let form = MOCK_DOC.getElementById("form1");
+    form.reset();
     for (let key in testcase.formValue) {
       let input = MOCK_DOC.getElementById(key);
       input.value = testcase.formValue[key];
     }
     sinon.stub(FormAutofillContent, "_onFormSubmit");
 
     let element = MOCK_DOC.getElementById(TARGET_ELEMENT_ID);
     FormAutofillContent.identifyAutofillFields(element);
     FormAutofillContent.notify(form);
 
     do_check_eq(FormAutofillContent._onFormSubmit.called,
                 testcase.expectedResult.formSubmission);
     if (FormAutofillContent._onFormSubmit.called) {
       Assert.deepEqual(FormAutofillContent._onFormSubmit.args[0][0],
-                       testcase.expectedResult.profile);
+                       testcase.expectedResult.records);
     }
     FormAutofillContent._onFormSubmit.restore();
   });
 });