Bug 1420853 - Ensure only fields valid for the given country are saved. r=MattN
authorJared Wein <jwein@mozilla.com>
Fri, 19 Oct 2018 16:36:45 +0000
changeset 490538 95fe4f9c32033b78245886e1e83f70675624977b
parent 490537 96304d13c406be1eb813e7c8cadabd04a8aad12d
child 490539 0e7248074acf71bb6553a68c53299f2fd1b35329
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersMattN
bugs1420853
milestone64.0a1
Bug 1420853 - Ensure only fields valid for the given country are saved. r=MattN Differential Revision: https://phabricator.services.mozilla.com/D9034
browser/components/payments/content/paymentDialogWrapper.js
browser/components/payments/test/browser/browser_address_edit.js
browser/extensions/formautofill/test/browser/browser_editAddressDialog.js
--- a/browser/components/payments/content/paymentDialogWrapper.js
+++ b/browser/components/payments/content/paymentDialogWrapper.js
@@ -577,17 +577,20 @@ var paymentDialogWrapper = {
       stateChange: {},
     };
     try {
       let isTemporary = record.isTemporary;
       let collection = isTemporary ? this.temporaryStore[collectionName] :
                                      formAutofillStorage[collectionName];
 
       if (guid) {
-        let preserveOldProperties = true;
+        // We only care to preserve old properties for credit cards,
+        // because credit cards don't get their full record sent to the
+        // unprivileged frame (the cc-number is excluded).
+        let preserveOldProperties = collectionName == "creditCards";
         await collection.update(guid, record, preserveOldProperties);
       } else {
         responseMessage.guid = await collection.add(record);
       }
 
       if (isTemporary && collectionName == "addresses") {
         // there will be no formautofill-storage-changed event to update state
         // so add updated collection here
--- a/browser/components/payments/test/browser/browser_address_edit.js
+++ b/browser/components/payments/test/browser/browser_address_edit.js
@@ -587,8 +587,146 @@ add_task(async function test_private_per
        "Check street-address in response");
     is(responseAddress.country, addressToAdd.country, "Check country in response");
   });
   // verify formautofill store doesnt have the new temp addresses
   is((await formAutofillStorage.addresses.getAll()).length, 1,
      "Original 1 stored address at end of test");
 });
 
+add_task(async function test_hiddenFieldNotSaved() {
+  await setup();
+
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: BLANK_PAGE_URL,
+  }, async browser => {
+    let {win, frame} =
+      await setupPaymentDialog(browser, {
+        methodData: [PTU.MethodData.basicCard],
+        details: Object.assign({}, PTU.Details.twoShippingOptions, PTU.Details.total2USD),
+        options: PTU.Options.requestShippingOption,
+        merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
+      }
+    );
+
+    let newAddress = Object.assign({}, PTU.Addresses.TimBL);
+    newAddress["given-name"] = "hiddenFields";
+
+    let shippingAddressChangePromise = ContentTask.spawn(browser, {
+      eventName: "shippingaddresschange",
+    }, PTU.ContentTasks.awaitPaymentRequestEventPromise);
+
+    let options = {
+      expectPersist: true,
+      isEditing: false,
+    };
+    await navigateToAddAddressPage(frame);
+    info("navigated to add address page");
+    await fillInShippingAddressForm(frame, newAddress, options);
+    info("filled in TimBL address");
+
+    await spawnPaymentDialogTask(frame, async (args) => {
+      let countryField = content.document.getElementById("country");
+      await content.fillField(countryField, "DE");
+    });
+    info("changed selected country to Germany");
+
+    await submitAddressForm(frame, null, options);
+    await shippingAddressChangePromise;
+    info("got shippingaddresschange event");
+
+    await spawnPaymentDialogTask(frame, async () => {
+      let {
+        PaymentTestUtils: PTU,
+      } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
+
+      let {savedAddresses} = await PTU.DialogContentUtils.getCurrentState(content);
+      is(Object.keys(savedAddresses).length, 2, "2 saved addresses");
+      let savedAddress = Object.values(savedAddresses)
+                               .find(address => address["given-name"] == "hiddenFields");
+      ok(savedAddress, "found the saved address");
+      is(savedAddress.country, "DE", "check country");
+      is(savedAddress["address-level2"], PTU.Addresses.TimBL["address-level2"],
+         "check address-level2");
+      is(savedAddress["address-level1"], undefined, "address-level1 should not be saved");
+    });
+
+    info("clicking cancel");
+    spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
+
+    await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
+  });
+  await cleanupFormAutofillStorage();
+});
+
+add_task(async function test_hiddenFieldRemovedWhenCountryChanged() {
+  await setup();
+
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: BLANK_PAGE_URL,
+  }, async browser => {
+    let {win, frame} =
+      await setupPaymentDialog(browser, {
+        methodData: [PTU.MethodData.basicCard],
+        details: Object.assign({}, PTU.Details.twoShippingOptions, PTU.Details.total2USD),
+        options: PTU.Options.requestShippingOption,
+        merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
+      }
+    );
+
+    let shippingAddressChangePromise = ContentTask.spawn(browser, {
+      eventName: "shippingaddresschange",
+    }, PTU.ContentTasks.awaitPaymentRequestEventPromise);
+
+    await spawnPaymentDialogTask(frame, async (args) => {
+      let {
+        PaymentTestUtils: PTU,
+      } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
+
+      let picker = content.document
+                     .querySelector("address-picker[selected-state-key='selectedShippingAddress']");
+      Cu.waiveXrays(picker).dropdown.popupBox.focus();
+      EventUtils.synthesizeKey(PTU.Addresses.TimBL["given-name"], {}, content.window);
+
+      let editLink = content.document.querySelector("address-picker .edit-link");
+      is(editLink.textContent, "Edit", "Edit link text");
+
+      editLink.click();
+
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "address-page" && !!state["address-page"].guid;
+      }, "Check edit page state");
+
+      let countryField = content.document.getElementById("country");
+      await content.fillField(countryField, "DE");
+      info("changed selected country to Germany");
+    });
+
+    let options = {
+      isEditing: true,
+    };
+    await submitAddressForm(frame, null, options);
+    await shippingAddressChangePromise;
+    info("got shippingaddresschange event");
+
+    await spawnPaymentDialogTask(frame, async () => {
+      let {
+        PaymentTestUtils: PTU,
+      } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
+
+      let {savedAddresses} = await PTU.DialogContentUtils.getCurrentState(content);
+      is(Object.keys(savedAddresses).length, 1, "1 saved address");
+      let savedAddress = Object.values(savedAddresses)[0];
+      is(savedAddress.country, "DE", "check country");
+      is(savedAddress["address-level2"], PTU.Addresses.TimBL["address-level2"],
+         "check address-level2");
+      is(savedAddress["address-level1"], undefined, "address-level1 should not be saved");
+    });
+
+    info("clicking cancel");
+    spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
+
+    await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
+  });
+  await cleanupFormAutofillStorage();
+});
--- a/browser/extensions/formautofill/test/browser/browser_editAddressDialog.js
+++ b/browser/extensions/formautofill/test/browser/browser_editAddressDialog.js
@@ -420,8 +420,62 @@ add_task(async function test_combined_na
                                   givenNameLabelRect.top + givenNameLabelRect.height / 2);
 
     is(el, givenNameLabel, "Check that the label text is visible in the error state");
     is(win.getComputedStyle(givenNameField).getPropertyValue("border-top-color"),
        "rgba(0, 0, 0, 0)", "Border should be transparent so that only the error outline shows");
     doc.querySelector("#cancel").click();
   });
 });
+
+add_task(async function test_hiddenFieldNotSaved() {
+  await testDialog(EDIT_ADDRESS_DIALOG_URL, win => {
+    let doc = win.document;
+    doc.querySelector("#address-level2").focus();
+    EventUtils.synthesizeKey(TEST_ADDRESS_1["address-level2"], {}, win);
+    doc.querySelector("#address-level1").focus();
+    EventUtils.synthesizeKey(TEST_ADDRESS_1["address-level1"], {}, win);
+    doc.querySelector("#country").focus();
+    EventUtils.synthesizeKey("Germany", {}, win);
+    doc.querySelector("#save").focus();
+    EventUtils.synthesizeKey("VK_RETURN", {}, win);
+  });
+  let addresses = await getAddresses();
+  is(addresses[0].country, "DE", "check country");
+  is(addresses[0]["address-level2"], TEST_ADDRESS_1["address-level2"], "check address-level2");
+  is(addresses[0]["address-level1"], undefined, "address-level1 should not be saved");
+
+  await removeAllRecords();
+});
+
+add_task(async function test_hiddenFieldRemovedWhenCountryChanged() {
+  let addresses = await getAddresses();
+  ok(!addresses.length, "no addresses at start of test");
+  await testDialog(EDIT_ADDRESS_DIALOG_URL, win => {
+    let doc = win.document;
+    doc.querySelector("#address-level2").focus();
+    EventUtils.synthesizeKey(TEST_ADDRESS_1["address-level2"], {}, win);
+    doc.querySelector("#address-level1").focus();
+    EventUtils.synthesizeKey(TEST_ADDRESS_1["address-level1"], {}, win);
+    doc.querySelector("#save").focus();
+    EventUtils.synthesizeKey("VK_RETURN", {}, win);
+  });
+  addresses = await getAddresses();
+  is(addresses[0].country, "US", "check country");
+  is(addresses[0]["address-level2"], TEST_ADDRESS_1["address-level2"], "check address-level2");
+  is(addresses[0]["address-level1"], TEST_ADDRESS_1["address-level1"], "check address-level1");
+
+  await testDialog(EDIT_ADDRESS_DIALOG_URL, win => {
+    let doc = win.document;
+    doc.querySelector("#country").focus();
+    EventUtils.synthesizeKey("Germany", {}, win);
+    win.document.querySelector("#save").click();
+  }, {
+    record: addresses[0],
+  });
+  addresses = await getAddresses();
+
+  is(addresses.length, 1, "only one address is in storage");
+  is(addresses[0]["address-level2"], TEST_ADDRESS_1["address-level2"], "check address-level2");
+  is(addresses[0]["address-level1"], undefined, "address-level1 should be removed");
+  is(addresses[0].country, "DE", "country changed");
+  await removeAllRecords();
+});