Bug 1440504 - Restrict fields on the payer contact page to those requested by the PaymentOptions object. r=MattN

MozReview-Commit-ID: 1aW0eTo6HYM

--HG--
extra : rebase_source : c42e58e33ede46f85d249526d0fadd106583eaed
This commit is contained in:
Jared Wein 2018-05-03 11:36:44 -04:00
Родитель a8c00743a6
Коммит 6ae2cdaf2a
8 изменённых файлов: 258 добавлений и 5 удалений

Просмотреть файл

@ -0,0 +1,21 @@
/* 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/. */
/* Hide all form fields that are not explicitly requested
* by the paymentOptions object.
*/
address-form[address-fields]:not([address-fields~='name']) #name-container,
address-form[address-fields] #organization-container,
address-form[address-fields] #street-address-container,
address-form[address-fields] #address-level2-container,
address-form[address-fields] #address-level1-container,
address-form[address-fields] #postal-code-container,
address-form[address-fields] #country-container,
address-form[address-fields] #country-warning-message,
address-form[address-fields]:not([address-fields~='email']) #email-container,
address-form[address-fields]:not([address-fields~='tel']) #tel-container {
/* !important is needed because autofillEditForms.js sets
inline styles on the form fields with display: flex; */
display: none !important;
}

Просмотреть файл

@ -81,6 +81,12 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
savedAddresses,
} = state;
if (page.addressFields) {
this.setAttribute("address-fields", page.addressFields);
} else {
this.removeAttribute("address-fields");
}
this.pageTitle.textContent = page.title;
this.genericErrorText.textContent = page.error;
@ -130,7 +136,6 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
let record = this.formHandler.buildFormObject();
let {
page,
selectedStateKey,
} = this.requestStore.getState();
paymentRequest.updateAutofillRecord("addresses", record, page.guid, {
@ -141,7 +146,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement
},
},
preserveOldProperties: true,
selectedStateKey,
selectedStateKey: page.selectedStateKey,
successStateChange: {
page: {
id: "payment-summary",

Просмотреть файл

@ -166,6 +166,7 @@ export default class AddressPicker extends PaymentStateSubscriberMixin(HTMLEleme
page: {
id: "address-page",
selectedStateKey: this.selectedStateKey,
addressFields: this.getAttribute("address-fields"),
},
};

Просмотреть файл

@ -66,7 +66,7 @@ let REQUEST_1 = {
error: "",
},
paymentOptions: {
requestPayerName: false,
requestPayerName: true,
requestPayerEmail: false,
requestPayerPhone: false,
requestShipping: true,

Просмотреть файл

@ -59,6 +59,7 @@
<link rel="stylesheet" href="components/basic-card-option.css"/>
<link rel="stylesheet" href="components/shipping-option.css"/>
<link rel="stylesheet" href="components/payment-details-item.css"/>
<link rel="stylesheet" href="containers/address-form.css"/>
<link rel="stylesheet" href="containers/order-details.css"/>
<script src="unprivileged-fallbacks.js"></script>

Просмотреть файл

@ -339,6 +339,15 @@ var PaymentTestUtils = {
requestShippingOption: {
requestShipping: true,
},
requestPayerNameAndEmail: {
requestPayerName: true,
requestPayerEmail: true,
},
requestPayerNameEmailAndPhone: {
requestPayerName: true,
requestPayerEmail: true,
requestPayerPhone: true,
},
},
Addresses: {

Просмотреть файл

@ -38,12 +38,16 @@ add_task(async function test_add_link() {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return Object.keys(state.savedAddresses).length == 0;
}, "No saved addresses when starting test");
let addLink = content.document.querySelector("address-picker a");
is(addLink.textContent, "Add", "Add link text");
addLink.click();
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "address-page" && !state.page.guid;
}, "Check add page state");
@ -116,12 +120,16 @@ add_task(async function test_edit_link() {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return Object.keys(state.savedAddresses).length == 1;
}, "One saved address when starting test");
let editLink = content.document.querySelector("address-picker a:nth-of-type(2)");
is(editLink.textContent, "Edit", "Edit link text");
editLink.click();
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "address-page" && !!state.page.guid;
}, "Check edit page state");
@ -165,3 +173,175 @@ add_task(async function test_edit_link() {
});
await cleanupFormAutofillStorage();
});
add_task(async function test_add_payer_contact_name_email_link() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async browser => {
let {win, frame} =
await setupPaymentDialog(browser, {
methodData: [PTU.MethodData.basicCard],
details: PTU.Details.total60USD,
options: PTU.Options.requestPayerNameAndEmail,
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
}
);
const EXPECTED_ADDRESS = {
"given-name": "Deraj",
"family-name": "Niew",
"email": "test@example.com",
};
await spawnPaymentDialogTask(frame, async (address) => {
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return Object.keys(state.savedAddresses).length == 0;
}, "No saved addresses when starting test");
let addLink = content.document.querySelector("address-picker.payer-related a");
is(addLink.textContent, "Add", "Add link text");
addLink.click();
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "address-page" && !state.page.guid;
}, "Check add page state");
let title = content.document.querySelector("address-form h1");
is(title.textContent, "Add Payer Contact", "Page title should be set");
info("filling fields");
for (let [key, val] of Object.entries(address)) {
let field = content.document.getElementById(key);
if (!field) {
ok(false, `${key} field not found`);
}
field.value = val;
ok(!field.disabled, `Field #${key} shouldn't be disabled`);
}
info("check that non-payer requested fields are hidden");
for (let selector of ["#organization", "#tel"]) {
ok(content.document.querySelector(selector).getBoundingClientRect().height == 0,
selector + " should be hidden");
}
content.document.querySelector("address-form button:last-of-type").click();
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return Object.keys(state.savedAddresses).length == 1;
}, "Check address was added");
let addressGUIDs = Object.keys(state.savedAddresses);
is(addressGUIDs.length, 1, "Check there is one addresses");
let savedAddress = state.savedAddresses[addressGUIDs[0]];
for (let [key, val] of Object.entries(address)) {
is(savedAddress[key], val, "Check " + key);
}
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "payment-summary";
}, "Switched back to payment-summary");
}, EXPECTED_ADDRESS);
info("clicking cancel");
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
});
});
add_task(async function test_edit_payer_contact_name_email_phone_link() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async browser => {
let {win, frame} =
await setupPaymentDialog(browser, {
methodData: [PTU.MethodData.basicCard],
details: PTU.Details.total60USD,
options: PTU.Options.requestPayerNameEmailAndPhone,
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
}
);
const EXPECTED_ADDRESS = {
"given-name": "Deraj",
"family-name": "Niew",
"email": "test@example.com",
"tel": "+15555551212",
};
await spawnPaymentDialogTask(frame, async (address) => {
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
return Object.keys(state.savedAddresses).length == 1;
}, "One saved addresses when starting test");
let editLink =
content.document.querySelector("address-picker.payer-related a:nth-of-type(2)");
is(editLink.textContent, "Edit", "Edit link text");
editLink.click();
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
info("state.page.id: " + state.page.id + "; state.page.guid: " + state.page.guid);
return state.page.id == "address-page" && !!state.page.guid;
}, "Check edit page state");
let title = content.document.querySelector("address-form h1");
is(title.textContent, "Edit Payer Contact", "Page title should be set");
info("overwriting field values");
for (let [key, val] of Object.entries(address)) {
let field = content.document.getElementById(key);
field.value = val + "1";
ok(!field.disabled, `Field #${key} shouldn't be disabled`);
}
info("check that non-payer requested fields are hidden");
let formElements =
content.document.querySelectorAll("address-form :-moz-any(input, select, textarea");
let allowedFields = ["given-name", "additional-name", "family-name", "email", "tel"];
for (let element of formElements) {
let shouldBeVisible = allowedFields.includes(element.id);
if (shouldBeVisible) {
ok(element.getBoundingClientRect().height > 0, element.id + " should be visible");
} else {
ok(element.getBoundingClientRect().height == 0, element.id + " should be hidden");
}
}
content.document.querySelector("address-form button:last-of-type").click();
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
let addresses = Object.entries(state.savedAddresses);
return addresses.length == 1 &&
addresses[0][1]["given-name"] == address["given-name"] + "1";
}, "Check address was edited");
let addressGUIDs = Object.keys(state.savedAddresses);
is(addressGUIDs.length, 1, "Check there is still one address");
let savedAddress = state.savedAddresses[addressGUIDs[0]];
for (let [key, val] of Object.entries(address)) {
is(savedAddress[key], val + "1", "Check updated " + key);
}
await PTU.DialogContentUtils.waitForState(content, (state) => {
return state.page.id == "payment-summary";
}, "Switched back to payment-summary");
}, EXPECTED_ADDRESS);
info("clicking cancel");
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
});
});

Просмотреть файл

@ -17,6 +17,7 @@ Test the address-form element
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<link rel="stylesheet" type="text/css" href="../../res/paymentRequest.css"/>
<link rel="stylesheet" type="text/css" href="../../res/containers/address-form.css"/>
</head>
<body>
<p id="display">
@ -228,6 +229,41 @@ add_task(async function test_edit() {
form.remove();
});
add_task(async function test_restricted_address_fields() {
let form = new AddressForm();
form.dataset.saveButtonLabel = "Save";
form.dataset.errorGenericSave = "Generic error";
await form.promiseReady;
display.appendChild(form);
await asyncElementRendered();
form.setAttribute("address-fields", "name email tel");
ok(!isHidden(form.form.querySelector("#given-name")),
"given-name should be visible");
ok(!isHidden(form.form.querySelector("#additional-name")),
"additional-name should be visible");
ok(!isHidden(form.form.querySelector("#family-name")),
"family-name should be visible");
ok(isHidden(form.form.querySelector("#organization")),
"organization should be hidden");
ok(isHidden(form.form.querySelector("#street-address")),
"street-address should be hidden");
ok(isHidden(form.form.querySelector("#address-level2")),
"address-level2 should be hidden");
ok(isHidden(form.form.querySelector("#address-level1")),
"address-level1 should be hidden");
ok(isHidden(form.form.querySelector("#postal-code")),
"postal-code should be hidden");
ok(isHidden(form.form.querySelector("#country")),
"country should be hidden");
ok(!isHidden(form.form.querySelector("#email")),
"email should be visible");
ok(!isHidden(form.form.querySelector("#tel")),
"tel should be visible");
form.remove();
});
</script>
</body>