Bug 1429207 - Implement the 'failure' screen for when the merchant rejects the payment. r=MattN
authorJared Wein <jwein@mozilla.com>
Tue, 27 Feb 2018 22:09:34 -0500
changeset 461058 e1b30d54da0b0e797c2b17d1714eb299f3e38e7e
parent 461057 884c918d978c4b5fcc7062237ee67323689fadbc
child 461059 ce11f528665181313c1a75e31e4ef407184a940f
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1429207
milestone60.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 1429207 - Implement the 'failure' screen for when the merchant rejects the payment. r=MattN MozReview-Commit-ID: JfsMQ8EwhqW
toolkit/components/payments/res/containers/payment-dialog.js
toolkit/components/payments/res/debugging.html
toolkit/components/payments/res/debugging.js
toolkit/components/payments/res/paymentRequest.css
toolkit/components/payments/res/paymentRequest.xhtml
toolkit/components/payments/test/mochitest/test_payment_dialog.html
--- a/toolkit/components/payments/res/containers/payment-dialog.js
+++ b/toolkit/components/payments/res/containers/payment-dialog.js
@@ -151,16 +151,17 @@ class PaymentDialog extends PaymentState
   }
 
   _renderPayButton(state) {
     this._payButton.disabled = state.changesPrevented;
     switch (state.completionState) {
       case "initial":
       case "processing":
       case "success":
+      case "fail":
         break;
       default:
         throw new Error("Invalid completionState");
     }
 
     this._payButton.textContent = this._payButton.dataset[state.completionState + "Label"];
   }
 
--- a/toolkit/components/payments/res/debugging.html
+++ b/toolkit/components/payments/res/debugging.html
@@ -27,11 +27,12 @@
       <button id="delete1Card">Delete 1 Card</button>
       <h1>States</h1>
       <button id="setChangesPrevented">Prevent changes</button>
       <button id="setChangesAllowed">Allow changes</button>
       <button id="setShippingError">Shipping Error</button>
       <button id="setStateDefault">Default</button>
       <button id="setStateProcessing">Processing</button>
       <button id="setStateSuccess">Success</button>
+      <button id="setStateFail">Fail</button>
     </div>
   </body>
 </html>
--- a/toolkit/components/payments/res/debugging.js
+++ b/toolkit/components/payments/res/debugging.js
@@ -294,16 +294,22 @@ let buttonActions = {
     });
   },
 
   setStateSuccess() {
     requestStore.setState({
       completionState: "success",
     });
   },
+
+  setStateFail() {
+    requestStore.setState({
+      completionState: "fail",
+    });
+  },
 };
 
 window.addEventListener("click", function onButtonClick(evt) {
   let id = evt.target.id;
   if (!id || typeof(buttonActions[id]) != "function") {
     return;
   }
 
--- a/toolkit/components/payments/res/paymentRequest.css
+++ b/toolkit/components/payments/res/paymentRequest.css
@@ -77,16 +77,17 @@ payment-dialog > footer {
 }
 
 #pay {
   background-color: #0060df;
   color: white;
   border: none;
 }
 
+payment-dialog[changes-prevented][completion-state="fail"] #pay,
 payment-dialog[changes-prevented][completion-state="processing"] #pay,
 payment-dialog[changes-prevented][completion-state="success"] #pay {
   /* Show the pay button above #disabled-overlay */
   position: relative;
   z-index: 1;
 }
 
 #disabled-overlay {
--- a/toolkit/components/payments/res/paymentRequest.xhtml
+++ b/toolkit/components/payments/res/paymentRequest.xhtml
@@ -9,16 +9,17 @@
   <!ENTITY deliveryAddressLabel       "Delivery Address">
   <!ENTITY pickupAddressLabel         "Pickup Address">
   <!ENTITY shippingOptionsLabel       "Shipping Options">
   <!ENTITY paymentMethodsLabel        "Payment Method">
   <!ENTITY cancelPaymentButton.label   "Cancel">
   <!ENTITY approvePaymentButton.label  "Pay">
   <!ENTITY processingPaymentButton.label "Processing">
   <!ENTITY successPaymentButton.label    "Done">
+  <!ENTITY failPaymentButton.label       "Fail">
   <!ENTITY orderDetailsLabel          "Order Details">
   <!ENTITY orderTotalLabel            "Total">
 ]>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <meta http-equiv="Content-Security-Policy" content="default-src 'self'"/>
   <title></title>
   <link rel="stylesheet" href="paymentRequest.css"/>
@@ -84,16 +85,17 @@
           <payment-method-picker selected-state-key="selectedPaymentCard"></payment-method-picker>
         </section>
 
         <footer id="controls-container">
           <button id="cancel">&cancelPaymentButton.label;</button>
           <button id="pay"
                   data-initial-label="&approvePaymentButton.label;"
                   data-processing-label="&processingPaymentButton.label;"
+                  data-fail-label="&failPaymentButton.label;"
                   data-success-label="&successPaymentButton.label;"></button>
         </footer>
       </section>
       <section id="order-details-overlay" hidden="hidden">
         <h1>&orderDetailsLabel;</h1>
         <order-details></order-details>
       </section>
     </div>
--- a/toolkit/components/payments/test/mochitest/test_payment_dialog.html
+++ b/toolkit/components/payments/test/mochitest/test_payment_dialog.html
@@ -31,16 +31,22 @@ Test the payment-dialog custom element
 /** Test the payment-dialog element **/
 
 /* global sinon */
 /* import-globals-from payments_common.js */
 /* import-globals-from ../../res/mixins/PaymentStateSubscriberMixin.js */
 
 let el1;
 
+let completionStates = [
+    ["processing", "Processing"],
+    ["success", "Done"],
+    ["fail", "Fail"],
+];
+
 /* test that:
   the view-all-items button exists
   that clicking it changes the state on the store
   that clicking it causes render to be called
 
   that order details element's hidden state matches the state on the store
 */
 
@@ -112,57 +118,46 @@ add_task(async function test_changesPrev
 
 add_task(async function test_completionState() {
   await setup();
   let state = el1.requestStore.getState();
   is(state.completionState, "initial", "completionState is initially initial");
   let payButton = document.getElementById("pay");
   is(payButton.textContent, "Pay", "Check default label");
   ok(!payButton.disabled, "Button is enabled");
-  await el1.requestStore.setState({completionState: "processing"});
-  await asyncElementRendered();
-  is(payButton.textContent, "Processing", "Check processing label");
-  ok(!payButton.disabled, "Button is still enabled");
-  await el1.requestStore.setState({completionState: "success"});
-  await asyncElementRendered();
-  is(payButton.textContent, "Done", "Check success label");
-  ok(!payButton.disabled, "Button is still enabled");
+  for (let [completionState, label] of completionStates) {
+    await el1.requestStore.setState({completionState});
+    await asyncElementRendered();
+    is(payButton.textContent, label, "Check payButton label");
+    ok(!payButton.disabled, "Button is still enabled");
+  }
 });
 
 add_task(async function test_completionStateChangesPrevented() {
   await setup();
   let state = el1.requestStore.getState();
   is(state.completionState, "initial", "completionState is initially initial");
   is(state.changesPrevented, false, "changesPrevented is initially false");
   let payButton = document.getElementById("pay");
   is(payButton.textContent, "Pay", "Check default label");
   ok(!payButton.disabled, "Button is enabled");
 
-  await el1.requestStore.setState({
-    changesPrevented: true,
-    completionState: "processing",
-  });
-  await asyncElementRendered();
-  is(payButton.textContent, "Processing", "Check processing label");
-  ok(payButton.disabled, "Button is disabled");
-  let rect = payButton.getBoundingClientRect();
-  let visibleElement =
-    document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
-  ok(payButton === visibleElement, "Pay button is on top of the overlay");
-
-  await el1.requestStore.setState({
-    changesPrevented: true,
-    completionState: "success",
-  });
-  await asyncElementRendered();
-  is(payButton.textContent, "Done", "Check success label");
-  ok(payButton.disabled, "Button is disabled");
-  rect = payButton.getBoundingClientRect();
-  visibleElement = document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
-  ok(payButton === visibleElement, "Pay button is on top of the overlay");
+  for (let [completionState, label] of completionStates) {
+    await el1.requestStore.setState({
+      changesPrevented: true,
+      completionState,
+    });
+    await asyncElementRendered();
+    is(payButton.textContent, label, "Check payButton label");
+    ok(payButton.disabled, "Button is disabled");
+    let rect = payButton.getBoundingClientRect();
+    let visibleElement =
+      document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
+    ok(payButton === visibleElement, "Pay button is on top of the overlay");
+  }
 });
 
 add_task(async function test_disconnect() {
   await setup();
 
   el1.remove();
   await el1.requestStore.setState({orderDetailsShowing: true});
   await asyncElementRendered();