зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1429181 - Consider supportedNetworks when determining if payment method is valid. r=MattN
* A new accepted-cards element to represent the labeled list of card icons * Add the accepted cards section to the summary and card add/edit page * mochitest for the accepted-cards element * Make cc-type a required field and validate it against the list of supported networks * Add verification of the pay button disabling when card network is not supported Depends on D5823 Differential Revision: https://phabricator.services.mozilla.com/D5824 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a3ee1b5ad2
Коммит
3b20596ca5
|
@ -13,6 +13,7 @@ browser.jar:
|
|||
res/payments (res/paymentRequest.*)
|
||||
res/payments/components/ (res/components/*.css)
|
||||
res/payments/components/ (res/components/*.js)
|
||||
res/payments/components/ (res/components/*.svg)
|
||||
res/payments/containers/ (res/containers/*.js)
|
||||
res/payments/containers/ (res/containers/*.css)
|
||||
res/payments/containers/ (res/containers/*.svg)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
accepted-cards {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.accepted-cards-label {
|
||||
display: inline-block;
|
||||
margin-inline-end: 1em;
|
||||
color: GrayText;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.accepted-cards-list {
|
||||
display: inline-block;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.accepted-cards-list > .accepted-cards-item {
|
||||
display: inline-block;
|
||||
width: 47px;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
margin-inline-end: 8px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
/* placeholders for specific card icons we don't yet have assets for */
|
||||
.accepted-cards-item[data-network-id] {
|
||||
background-image: url("./card-icon.svg");
|
||||
}
|
||||
.accepted-cards-item[data-network-id]:after {
|
||||
content: attr(data-network-id);
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
font-size: 0.7rem;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
width: 36px;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* 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/. */
|
||||
|
||||
import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
|
||||
import paymentRequest from "../paymentRequest.js";
|
||||
/* import-globals-from ../unprivileged-fallbacks.js */
|
||||
|
||||
/**
|
||||
* <accepted-cards></accepted-cards>
|
||||
*/
|
||||
|
||||
export default class AcceptedCards extends PaymentStateSubscriberMixin(HTMLElement) {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._listEl = document.createElement("ul");
|
||||
this._listEl.classList.add("accepted-cards-list");
|
||||
this._labelEl = document.createElement("span");
|
||||
this._labelEl.classList.add("accepted-cards-label");
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.label = this.getAttribute("label");
|
||||
this.appendChild(this._labelEl);
|
||||
|
||||
this._listEl.textContent = "";
|
||||
let allNetworks = PaymentDialogUtils.getCreditCardNetworks();
|
||||
for (let network of allNetworks) {
|
||||
let item = document.createElement("li");
|
||||
item.classList.add("accepted-cards-item");
|
||||
item.dataset.networkId = network;
|
||||
this._listEl.appendChild(item);
|
||||
}
|
||||
this.appendChild(this._listEl);
|
||||
// Only call the connected super callback(s) once our markup is fully
|
||||
// connected
|
||||
super.connectedCallback();
|
||||
}
|
||||
|
||||
render(state) {
|
||||
let acceptedNetworks = paymentRequest.getAcceptedNetworks(state.request);
|
||||
for (let item of this._listEl.children) {
|
||||
let network = item.dataset.networkId;
|
||||
item.hidden = !(network && acceptedNetworks.includes(network));
|
||||
}
|
||||
}
|
||||
|
||||
set label(value) {
|
||||
this._labelEl.textContent = value;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("accepted-cards", AcceptedCards);
|
|
@ -17,8 +17,8 @@ export default class BasicCardOption extends ObservedPropertiesMixin(RichOption)
|
|||
"cc-exp",
|
||||
"cc-name",
|
||||
"cc-number",
|
||||
"cc-type",
|
||||
"guid",
|
||||
"type", // XXX Bug 1429181.
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -29,14 +29,14 @@ export default class BasicCardOption extends ObservedPropertiesMixin(RichOption)
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
for (let name of ["cc-name", "cc-number", "cc-exp", "type"]) {
|
||||
for (let name of ["cc-name", "cc-number", "cc-exp", "cc-type"]) {
|
||||
this[`_${name}`] = document.createElement("span");
|
||||
this[`_${name}`].classList.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
for (let name of ["cc-name", "cc-number", "cc-exp", "type"]) {
|
||||
for (let name of ["cc-name", "cc-number", "cc-exp", "cc-type"]) {
|
||||
this.appendChild(this[`_${name}`]);
|
||||
}
|
||||
super.connectedCallback();
|
||||
|
@ -47,14 +47,16 @@ export default class BasicCardOption extends ObservedPropertiesMixin(RichOption)
|
|||
let ccNumber = basicCard["cc-number"] || "";
|
||||
let ccExp = basicCard["cc-exp"] || "";
|
||||
let ccName = basicCard["cc-name"] || "";
|
||||
return ccNumber + " " + ccExp + " " + ccName;
|
||||
// XXX: Bug 1491040, displaying cc-type in this context may need its own localized string
|
||||
let ccType = basicCard["cc-type"] || "";
|
||||
return `${ccType} ${ccNumber} ${ccExp} ${ccName}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
this["_cc-name"].textContent = this.ccName;
|
||||
this["_cc-number"].textContent = this.ccNumber;
|
||||
this["_cc-exp"].textContent = this.ccExp;
|
||||
this._type.textContent = this.type;
|
||||
this["_cc-type"].textContent = this.ccType;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 47 30">
|
||||
<rect x="0" y="0" width="47" height="22" rx="4" ry="4" fill="#000" fill-opacity="0.2">
|
||||
</rect>
|
||||
<rect x="0" y="5" width="47" height="12" fill="#fff" fill-opacity="1">
|
||||
</rect>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 250 B |
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from ../../../../../browser/extensions/formautofill/content/autofillEditForms.js*/
|
||||
import AcceptedCards from "../components/accepted-cards.js";
|
||||
import LabelledCheckbox from "../components/labelled-checkbox.js";
|
||||
import PaymentRequestPage from "../components/payment-request-page.js";
|
||||
import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
|
||||
|
@ -37,6 +38,8 @@ export default class BasicCardForm extends PaymentStateSubscriberMixin(PaymentRe
|
|||
this.persistCheckbox = new LabelledCheckbox();
|
||||
this.persistCheckbox.className = "persist-checkbox";
|
||||
|
||||
this.acceptedCardsList = new AcceptedCards();
|
||||
|
||||
// page footer
|
||||
this.cancelButton = document.createElement("button");
|
||||
this.cancelButton.className = "cancel-button";
|
||||
|
@ -102,6 +105,7 @@ export default class BasicCardForm extends PaymentStateSubscriberMixin(PaymentRe
|
|||
|
||||
this.body.appendChild(this.persistCheckbox);
|
||||
this.body.appendChild(this.genericErrorText);
|
||||
this.body.appendChild(this.acceptedCardsList);
|
||||
// Only call the connected super callback(s) once our markup is fully
|
||||
// connected, including the shared form fetched asynchronously.
|
||||
super.connectedCallback();
|
||||
|
@ -128,6 +132,7 @@ export default class BasicCardForm extends PaymentStateSubscriberMixin(PaymentRe
|
|||
this.persistCheckbox.label = this.dataset.persistCheckboxLabel;
|
||||
this.addressAddLink.textContent = this.dataset.addressAddLinkLabel;
|
||||
this.addressEditLink.textContent = this.dataset.addressEditLinkLabel;
|
||||
this.acceptedCardsList.label = this.dataset.acceptedCardsLabel;
|
||||
|
||||
// The next line needs an onboarding check since we don't set previousId
|
||||
// when navigating to add/edit directly from the summary page.
|
||||
|
|
|
@ -9,6 +9,7 @@ import paymentRequest from "../paymentRequest.js";
|
|||
|
||||
import "../components/currency-amount.js";
|
||||
import "../components/payment-request-page.js";
|
||||
import "../components/accepted-cards.js";
|
||||
import "./address-picker.js";
|
||||
import "./address-form.js";
|
||||
import "./basic-card-form.js";
|
||||
|
@ -52,6 +53,7 @@ export default class PaymentDialog extends PaymentStateSubscriberMixin(HTMLEleme
|
|||
this._payerRelatedEls = contents.querySelectorAll(".payer-related");
|
||||
this._payerAddressPicker = contents.querySelector("address-picker.payer-related");
|
||||
this._paymentMethodPicker = contents.querySelector("payment-method-picker");
|
||||
this._acceptedCardsList = contents.querySelector("accepted-cards");
|
||||
|
||||
this._header = contents.querySelector("header");
|
||||
|
||||
|
@ -346,6 +348,10 @@ export default class PaymentDialog extends PaymentStateSubscriberMixin(HTMLEleme
|
|||
this._payerAddressPicker.dataset.addAddressTitle = this.dataset.payerTitleAdd;
|
||||
this._payerAddressPicker.dataset.editAddressTitle = this.dataset.payerTitleEdit;
|
||||
|
||||
// hide the accepted cards list if the merchant didn't specify a preference
|
||||
let acceptedNetworks = paymentRequest.getAcceptedNetworks(state.request);
|
||||
this._acceptedCardsList.hidden = !acceptedNetworks.length;
|
||||
|
||||
this._renderPayButton(state);
|
||||
|
||||
for (let page of this._mainContainer.querySelectorAll(":scope > .page")) {
|
||||
|
|
|
@ -31,8 +31,6 @@ export default class PaymentMethodPicker extends RichPicker {
|
|||
|
||||
get fieldNames() {
|
||||
let fieldNames = [...BasicCardOption.recordAttributes];
|
||||
// Type is not a required field though it may be present.
|
||||
fieldNames.splice(fieldNames.indexOf("type"), 1);
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
|
@ -76,6 +74,23 @@ export default class PaymentMethodPicker extends RichPicker {
|
|||
super.render(state);
|
||||
}
|
||||
|
||||
isSelectedOptionValid(state) {
|
||||
let hasMissingFields = this.missingFieldsOfSelectedOption().length;
|
||||
if (hasMissingFields) {
|
||||
return false;
|
||||
}
|
||||
let selectedOption = this.selectedOption;
|
||||
if (!selectedOption) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let acceptedNetworks = paymentRequest.getAcceptedNetworks(state.request);
|
||||
let selectedCard = state.savedBasicCards[selectedOption.value];
|
||||
let isSupported = selectedCard["cc-type"] &&
|
||||
acceptedNetworks.includes(selectedCard["cc-type"]);
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
get selectedStateKey() {
|
||||
return this.getAttribute("selected-state-key");
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ export default class RichPicker extends PaymentStateSubscriberMixin(HTMLElement)
|
|||
this.editLink.hidden = !this.dropdown.value;
|
||||
|
||||
this.classList.toggle("invalid-selected-option",
|
||||
this.missingFieldsOfSelectedOption().length);
|
||||
!this.isSelectedOptionValid(state));
|
||||
}
|
||||
|
||||
get selectedOption() {
|
||||
|
@ -71,6 +71,10 @@ export default class RichPicker extends PaymentStateSubscriberMixin(HTMLElement)
|
|||
return [];
|
||||
}
|
||||
|
||||
isSelectedOptionValid() {
|
||||
return !this.missingFieldsOfSelectedOption().length;
|
||||
}
|
||||
|
||||
missingFieldsOfSelectedOption() {
|
||||
let selectedOption = this.selectedOption;
|
||||
if (!selectedOption) {
|
||||
|
|
|
@ -292,6 +292,7 @@ let BASIC_CARDS_1 = {
|
|||
"cc-name": "John Smith",
|
||||
"cc-exp-month": 6,
|
||||
"cc-exp-year": 2024,
|
||||
"cc-type": "visa",
|
||||
"cc-given-name": "John",
|
||||
"cc-additional-name": "",
|
||||
"cc-family-name": "Smith",
|
||||
|
@ -309,6 +310,7 @@ let BASIC_CARDS_1 = {
|
|||
"cc-name": "Jane Doe",
|
||||
"cc-exp-month": 5,
|
||||
"cc-exp-year": 2023,
|
||||
"cc-type": "mastercard",
|
||||
"cc-given-name": "Jane",
|
||||
"cc-additional-name": "",
|
||||
"cc-family-name": "Doe",
|
||||
|
@ -327,6 +329,7 @@ let BASIC_CARDS_1 = {
|
|||
"cc-given-name": "Jane",
|
||||
"cc-additional-name": "",
|
||||
"cc-family-name": "Fields",
|
||||
"cc-type": "discover",
|
||||
},
|
||||
"missing-cc-name": {
|
||||
methodName: "basic-card",
|
||||
|
@ -340,6 +343,7 @@ let BASIC_CARDS_1 = {
|
|||
"cc-exp-month": 8,
|
||||
"cc-exp-year": 2024,
|
||||
"cc-exp": "2024-08",
|
||||
"cc-type": "amex",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -277,6 +277,18 @@ var paymentRequest = {
|
|||
let cards = Object.assign({}, state.savedBasicCards, state.tempBasicCards);
|
||||
return cards;
|
||||
},
|
||||
|
||||
getAcceptedNetworks(request) {
|
||||
let basicCardMethod = request.paymentMethods
|
||||
.find(method => method.supportedMethods == "basic-card");
|
||||
let merchantNetworks = basicCardMethod && basicCardMethod.data &&
|
||||
basicCardMethod.data.supportedNetworks;
|
||||
if (merchantNetworks && merchantNetworks.length) {
|
||||
return merchantNetworks;
|
||||
}
|
||||
// fallback to the complete list if the merchant didn't specify
|
||||
return PaymentDialogUtils.getCreditCardNetworks();
|
||||
},
|
||||
};
|
||||
|
||||
paymentRequest.init();
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
<!ENTITY timeoutErrorPage.doneButton.label "Close">
|
||||
<!ENTITY webPaymentsBranding.label "&brandShortName; Checkout">
|
||||
<!ENTITY invalidOption.label "Missing or invalid information">
|
||||
<!ENTITY acceptedCards.label "Merchant accepts:">
|
||||
]>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
@ -92,6 +93,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="components/accepted-cards.css"/>
|
||||
<link rel="stylesheet" href="containers/address-form.css"/>
|
||||
<link rel="stylesheet" href="containers/basic-card-form.css"/>
|
||||
<link rel="stylesheet" href="containers/order-details.css"/>
|
||||
|
@ -145,6 +147,7 @@
|
|||
data-invalid-label="&invalidOption.label;"
|
||||
label="&paymentMethodsLabel;">
|
||||
</payment-method-picker>
|
||||
<accepted-cards hidden="hidden" label="&acceptedCards.label;"></accepted-cards>
|
||||
<address-picker class="payer-related"
|
||||
label="&payerLabel;"
|
||||
data-add-link-label="&payer.addLink.label;"
|
||||
|
@ -182,6 +185,7 @@
|
|||
data-update-button-label="&basicCardPage.updateButton.label;"
|
||||
data-cancel-button-label="&cancelPaymentButton.label;"
|
||||
data-persist-checkbox-label="&basicCardPage.persistCheckbox.label;"
|
||||
data-accepted-cards-label="&acceptedCards.label;"
|
||||
data-field-required-symbol="&fieldRequiredSymbol;"
|
||||
hidden="hidden"></basic-card-form>
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ var PaymentDialogUtils = {
|
|||
return `${address.name} (${address.guid})`;
|
||||
},
|
||||
|
||||
getCreditCardNetworks(address) {
|
||||
getCreditCardNetworks() {
|
||||
// Shim for list of known and supported credit card network ids as exposed by
|
||||
// toolkit/modules/CreditCard.jsm
|
||||
return [
|
||||
|
|
|
@ -181,6 +181,16 @@ var PaymentTestUtils = {
|
|||
EventUtils.synthesizeKey(option.textContent, {}, content.window);
|
||||
},
|
||||
|
||||
selectPaymentOptionByGuid: guid => {
|
||||
let doc = content.document;
|
||||
let methodPicker = doc.querySelector("payment-method-picker");
|
||||
let select = Cu.waiveXrays(methodPicker).dropdown.popupBox;
|
||||
let option = select.querySelector(`[guid="${guid}"]`);
|
||||
select.focus();
|
||||
// eslint-disable-next-line no-undef
|
||||
EventUtils.synthesizeKey(option.label, {}, content.window);
|
||||
},
|
||||
|
||||
/**
|
||||
* Click the primary button for the current page
|
||||
*
|
||||
|
|
|
@ -202,3 +202,60 @@ add_task(async function test_localized() {
|
|||
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_supportedNetworks() {
|
||||
await setupFormAutofillStorage();
|
||||
await cleanupFormAutofillStorage();
|
||||
|
||||
let address1GUID = await addAddressRecord(PTU.Addresses.TimBL);
|
||||
let visaCardGUID = await addCardRecord(Object.assign({}, PTU.BasicCards.JohnDoe, {
|
||||
billingAddressGUID: address1GUID,
|
||||
}));
|
||||
let masterCardGUID = await addCardRecord(Object.assign({}, PTU.BasicCards.JaneMasterCard, {
|
||||
billingAddressGUID: address1GUID,
|
||||
}));
|
||||
|
||||
let cardMethod = {
|
||||
supportedMethods: "basic-card",
|
||||
data: {
|
||||
supportedNetworks: ["visa"],
|
||||
},
|
||||
};
|
||||
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: BLANK_PAGE_URL,
|
||||
}, async browser => {
|
||||
let {win, frame} =
|
||||
await setupPaymentDialog(browser, {
|
||||
methodData: [cardMethod],
|
||||
details,
|
||||
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
|
||||
}
|
||||
);
|
||||
|
||||
await spawnPaymentDialogTask(frame, () => {
|
||||
let acceptedCards = content.document.querySelector("accepted-cards");
|
||||
ok(acceptedCards && !content.isHidden(acceptedCards),
|
||||
"accepted-cards element is present and visible");
|
||||
});
|
||||
|
||||
info("select the mastercard");
|
||||
await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.selectPaymentOptionByGuid,
|
||||
masterCardGUID);
|
||||
|
||||
await spawnPaymentDialogTask(frame, async () => {
|
||||
ok(content.document.getElementById("pay").disabled, "pay button should be disabled");
|
||||
});
|
||||
|
||||
info("select the visa");
|
||||
await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.selectPaymentOptionByGuid,
|
||||
visaCardGUID);
|
||||
await spawnPaymentDialogTask(frame, async () => {
|
||||
ok(!content.document.getElementById("pay").disabled, "pay button should not be disabled");
|
||||
});
|
||||
|
||||
await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
|
||||
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,3 +28,4 @@ skip-if = !e10s
|
|||
[test_ObservedPropertiesMixin.html]
|
||||
[test_PaymentsStore.html]
|
||||
[test_PaymentStateSubscriberMixin.html]
|
||||
[test_accepted_cards.html]
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test the accepted-cards element
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the accepted-cards element</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/AddTask.js"></script>
|
||||
<script src="sinon-2.3.2.js"></script>
|
||||
<script src="payments_common.js"></script>
|
||||
<script src="../../res/vendor/custom-elements.min.js"></script>
|
||||
<script src="../../res/unprivileged-fallbacks.js"></script>
|
||||
|
||||
<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/components/accepted-cards.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display">
|
||||
<accepted-cards label="Accepted:"></accepted-cards>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script type="module">
|
||||
/** Test the accepted-cards component **/
|
||||
|
||||
import "../../res/components/accepted-cards.js";
|
||||
import {requestStore} from "../../res/mixins/PaymentStateSubscriberMixin.js";
|
||||
let emptyState = requestStore.getState();
|
||||
let acceptedElem = document.querySelector("accepted-cards");
|
||||
let allNetworks = PaymentDialogUtils.getCreditCardNetworks();
|
||||
|
||||
add_task(async function test_reConnected() {
|
||||
let itemsCount = acceptedElem.querySelectorAll(".accepted-cards-item").length;
|
||||
is(itemsCount, allNetworks.length, "Same number of items as there are supported networks");
|
||||
|
||||
let container = acceptedElem.parentNode;
|
||||
let removed = container.removeChild(acceptedElem);
|
||||
container.appendChild(removed);
|
||||
let newItemsCount = acceptedElem.querySelectorAll(".accepted-cards-item").length;
|
||||
is(itemsCount, newItemsCount, "Number of items doesnt changed when re-connected");
|
||||
});
|
||||
|
||||
add_task(async function test_noSupportedNetworksIndicated() {
|
||||
let paymentMethods = [{
|
||||
supportedMethods: "basic-card",
|
||||
}];
|
||||
requestStore.setState({
|
||||
request: Object.assign({}, emptyState.request, {
|
||||
paymentMethods,
|
||||
}),
|
||||
});
|
||||
await asyncElementRendered();
|
||||
|
||||
let showingItems = acceptedElem.querySelectorAll(".accepted-cards-item:not([hidden])");
|
||||
is(showingItems.length, allNetworks.length,
|
||||
"Expected all items to be showing when no supportedNetworks are indicated");
|
||||
for (let network of allNetworks) {
|
||||
ok(acceptedElem.querySelector(`[data-network-id='${network}']:not([hidden])`),
|
||||
`Item for the ${network} network expected to be visible`);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_someAccepted() {
|
||||
let supportedNetworks = ["discover", "amex"];
|
||||
let paymentMethods = [{
|
||||
supportedMethods: "basic-card",
|
||||
data: {
|
||||
supportedNetworks,
|
||||
},
|
||||
}];
|
||||
requestStore.setState({
|
||||
request: Object.assign({}, emptyState.request, {
|
||||
paymentMethods,
|
||||
}),
|
||||
});
|
||||
await asyncElementRendered();
|
||||
|
||||
let showingItems = acceptedElem.querySelectorAll(".accepted-cards-item:not([hidden])");
|
||||
is(showingItems.length, 2,
|
||||
"Expected 2 items to be showing when 2 supportedNetworks are indicated");
|
||||
for (let network of allNetworks) {
|
||||
if (supportedNetworks.includes(network)) {
|
||||
ok(acceptedElem.querySelector(`[data-network-id='${network}']:not([hidden])`),
|
||||
`Item for the ${network} network expected to be visible`);
|
||||
} else {
|
||||
ok(acceptedElem.querySelector(`[data-network-id='${network}'][hidden]`),
|
||||
`Item for the ${network} network expected to be hidden`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче