summaryrefslogtreecommitdiffstats
path: root/browser/components/payments/test/mochitest/test_address_picker.html
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/payments/test/mochitest/test_address_picker.html')
-rw-r--r--browser/components/payments/test/mochitest/test_address_picker.html278
1 files changed, 278 insertions, 0 deletions
diff --git a/browser/components/payments/test/mochitest/test_address_picker.html b/browser/components/payments/test/mochitest/test_address_picker.html
new file mode 100644
index 0000000000..5a3f1b398a
--- /dev/null
+++ b/browser/components/payments/test/mochitest/test_address_picker.html
@@ -0,0 +1,278 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Test the address-picker component
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test the address-picker component</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <script src="payments_common.js"></script>
+ <script src="../../res/unprivileged-fallbacks.js"></script>
+ <script src="autofillEditForms.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="../../res/containers/rich-picker.css"/>
+ <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/>
+ <link rel="stylesheet" type="text/css" href="../../res/components/address-option.css"/>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <p id="display">
+ <address-picker id="picker1"
+ data-field-separator=", "
+ data-invalid-label="Picker1: Missing or Invalid"
+ selected-state-key="selectedShippingAddress"></address-picker>
+ </p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<script type="module">
+/** Test the address-picker component **/
+
+import "../../res/containers/address-picker.js";
+
+let picker1 = document.getElementById("picker1");
+
+add_task(async function test_empty() {
+ ok(picker1, "Check picker1 exists");
+ let {savedAddresses} = picker1.requestStore.getState();
+ is(Object.keys(savedAddresses).length, 0, "Check empty initial state");
+ is(picker1.editLink.hidden, true, "Check that picker edit link is hidden");
+ is(picker1.dropdown.popupBox.children.length, 0, "Check dropdown is empty");
+});
+
+add_task(async function test_initialSet() {
+ picker1.requestStore.setState({
+ savedAddresses: {
+ "48bnds6854t": {
+ "address-level1": "MI",
+ "address-level2": "Some City",
+ "country": "US",
+ "guid": "48bnds6854t",
+ "name": "Mr. Foo",
+ "postal-code": "90210",
+ "street-address": "123 Sesame Street,\nApt 40",
+ "tel": "+1 519 555-5555",
+ timeLastUsed: 200,
+ },
+ "68gjdh354j": {
+ "address-level1": "CA",
+ "address-level2": "Mountain View",
+ "country": "US",
+ "guid": "68gjdh354j",
+ "name": "Mrs. Bar",
+ "postal-code": "94041",
+ "street-address": "P.O. Box 123",
+ "tel": "+1 650 555-5555",
+ timeLastUsed: 300,
+ },
+ "abcde12345": {
+ "address-level2": "Mountain View",
+ "country": "US",
+ "guid": "abcde12345",
+ "name": "Mrs. Fields",
+ timeLastUsed: 100,
+ },
+ },
+ });
+ await asyncElementRendered();
+ let options = picker1.dropdown.popupBox.children;
+ is(options.length, 3, "Check dropdown has all addresses");
+ ok(options[0].textContent.includes("Mrs. Bar"), "Check first address based on timeLastUsed");
+ ok(options[1].textContent.includes("Mr. Foo"), "Check second address based on timeLastUsed");
+ ok(options[2].textContent.includes("Mrs. Fields"), "Check third address based on timeLastUsed");
+});
+
+add_task(async function test_update() {
+ picker1.requestStore.setState({
+ savedAddresses: {
+ "48bnds6854t": {
+ // Same GUID, different values to trigger an update
+ "address-level1": "MI-edit",
+ // address-level2 was cleared which means it's not returned
+ "country": "CA",
+ "guid": "48bnds6854t",
+ "name": "Mr. Foo-edit",
+ "postal-code": "90210-1234",
+ "street-address": "new-edit",
+ "tel": "+1 650 555-5555",
+ },
+ "68gjdh354j": {
+ "address-level1": "CA",
+ "address-level2": "Mountain View",
+ "country": "US",
+ "guid": "68gjdh354j",
+ "name": "Mrs. Bar",
+ "postal-code": "94041",
+ "street-address": "P.O. Box 123",
+ "tel": "+1 650 555-5555",
+ },
+ "abcde12345": {
+ "address-level2": "Mountain View",
+ "country": "US",
+ "guid": "abcde12345",
+ "name": "Mrs. Fields",
+ },
+ },
+ });
+ await asyncElementRendered();
+ let options = picker1.dropdown.popupBox.children;
+ is(options.length, 3, "Check dropdown still has all addresses");
+ ok(options[0].textContent.includes("Mr. Foo-edit"), "Check updated name in first address");
+ ok(!options[0].getAttribute("address-level2"), "Check removed first address-level2");
+ ok(options[1].textContent.includes("Mrs. Bar"), "Check that name is the same in second address");
+ ok(options[1].getAttribute("street-address").includes("P.O. Box 123"),
+ "Check second address is the same");
+ ok(options[2].textContent.includes("Mrs. Fields"),
+ "Check that name is the same in third address");
+ is(options[2].getAttribute("street-address"), null, "Check third address is missing");
+});
+
+add_task(async function test_change_selected_address() {
+ let options = picker1.dropdown.popupBox.children;
+ is(picker1.dropdown.selectedOption, null, "Should default to no selected option");
+ is(picker1.editLink.hidden, true, "Picker edit link should be hidden when no option is selected");
+ let {selectedShippingAddress} = picker1.requestStore.getState();
+ is(selectedShippingAddress, null, "store should have no option selected");
+ ok(!picker1.classList.contains("invalid-selected-option"), "No validation on an empty selection");
+ ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden");
+
+ picker1.dropdown.popupBox.focus();
+ synthesizeKey(options[2].getAttribute("name"), {});
+ await asyncElementRendered();
+
+ let selectedOption = picker1.dropdown.selectedOption;
+ is(selectedOption, options[2], "Selected option should now be the third option");
+ selectedShippingAddress = picker1.requestStore.getState().selectedShippingAddress;
+ is(selectedShippingAddress, selectedOption.getAttribute("guid"),
+ "store should have third option selected");
+ // The third option is missing some fields. Make sure that it is marked as such.
+ ok(picker1.classList.contains("invalid-selected-option"), "The third option is missing fields");
+ ok(!isHidden(picker1.invalidLabel), "The invalid label should be visible");
+ is(picker1.invalidLabel.innerText, picker1.dataset.invalidLabel, "Check displayed error text");
+
+ picker1.dropdown.popupBox.focus();
+ synthesizeKey(options[1].getAttribute("name"), {});
+ await asyncElementRendered();
+
+ selectedOption = picker1.dropdown.selectedOption;
+ is(selectedOption, options[1], "Selected option should now be the second option");
+ selectedShippingAddress = picker1.requestStore.getState().selectedShippingAddress;
+ is(selectedShippingAddress, selectedOption.getAttribute("guid"),
+ "store should have second option selected");
+ ok(!picker1.classList.contains("invalid-selected-option"), "The second option has all fields");
+ ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden");
+});
+
+add_task(async function test_address_combines_name_street_level2_level1_postalCode_country() {
+ let options = picker1.dropdown.popupBox.children;
+ let richoption1 = picker1.dropdown.querySelector(".rich-select-selected-option");
+ /* eslint-disable max-len */
+ is(richoption1.innerText,
+ `${options[1].getAttribute("name")}, ${options[1].getAttribute("street-address")}
+${options[1].getAttribute("address-level2")}, ${options[1].getAttribute("address-level1")}, ${options[1].getAttribute("postal-code")}, ${options[1].getAttribute("country")}`,
+ "The address shown should be human readable and include all fields");
+ /* eslint-enable max-len */
+
+ picker1.dropdown.popupBox.focus();
+ synthesizeKey(options[2].getAttribute("name"), {});
+ await asyncElementRendered();
+
+ richoption1 = picker1.dropdown.querySelector(".rich-select-selected-option");
+ // "Missing …" text is rendered via a pseudo element content and isn't included in innerText
+ is(richoption1.innerText, "Mrs. Fields, \nMountain View, , US",
+ "The address shown should be human readable and include all fields");
+
+ picker1.dropdown.popupBox.focus();
+ synthesizeKey(options[1].getAttribute("name"), {});
+ await asyncElementRendered();
+});
+
+add_task(async function test_delete() {
+ picker1.requestStore.setState({
+ savedAddresses: {
+ // 48bnds6854t and abcde12345 was deleted
+ "68gjdh354j": {
+ "address-level1": "CA",
+ "address-level2": "Mountain View",
+ "country": "US",
+ "guid": "68gjdh354j",
+ "name": "Mrs. Bar",
+ "postal-code": "94041",
+ "street-address": "P.O. Box 123",
+ "tel": "+1 650 555-5555",
+ },
+ },
+ });
+ await asyncElementRendered();
+ let options = picker1.dropdown.popupBox.children;
+ is(options.length, 1, "Check dropdown has one remaining address");
+ ok(options[0].textContent.includes("Mrs. Bar"), "Check remaining address");
+});
+
+add_task(async function test_merchantError() {
+ picker1.requestStore.setState({
+ selectedShippingAddress: "68gjdh354j",
+ });
+ await asyncElementRendered();
+
+ is(picker1.selectedStateKey, "selectedShippingAddress", "Check selectedStateKey");
+
+ let state = picker1.requestStore.getState();
+ let {
+ request,
+ } = state;
+ ok(!picker1.classList.contains("invalid-selected-option"), "No validation on a valid option");
+ ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden");
+
+ let requestWithShippingAddressErrors = deepClone(request);
+ Object.assign(requestWithShippingAddressErrors.paymentDetails, {
+ shippingAddressErrors: {
+ country: "Your country is not supported",
+ },
+ });
+ picker1.requestStore.setState({
+ request: requestWithShippingAddressErrors,
+ });
+ await asyncElementRendered();
+
+ ok(picker1.classList.contains("invalid-selected-option"), "The merchant error applies");
+ ok(!isHidden(picker1.invalidLabel), "The merchant error should be visible");
+ is(picker1.invalidLabel.innerText, "Your country is not supported", "Check displayed error text");
+
+ info("update the request to remove the errors");
+ picker1.requestStore.setState({
+ request,
+ });
+ await asyncElementRendered();
+ ok(!picker1.classList.contains("invalid-selected-option"),
+ "No errors visible when merchant errors cleared");
+ ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden");
+
+ info("Set billing address and payer errors which aren't relevant to this picker");
+ let requestWithNonShippingAddressErrors = deepClone(request);
+ Object.assign(requestWithNonShippingAddressErrors.paymentDetails, {
+ payerErrors: {
+ name: "Your name is too short",
+ },
+ paymentMethodErrors: {
+ billingAddress: {
+ country: "Your billing country is not supported",
+ },
+ },
+ shippingAddressErrors: {},
+ });
+ picker1.requestStore.setState({
+ request: requestWithNonShippingAddressErrors,
+ });
+ await asyncElementRendered();
+ ok(!picker1.classList.contains("invalid-selected-option"), "No errors on a shipping picker");
+ ok(isHidden(picker1.invalidLabel), "The invalid label should still be hidden");
+});
+</script>
+
+</body>
+</html>