Bug 1447777 - Move state.completionState to state.request.completeStatus. r=MattN
authorSam Foster <sfoster@mozilla.com>
Thu, 19 Jul 2018 19:45:58 -0700
changeset 427618 b4ecdfcd8f9f39a3993905762f42aa0284920ffb
parent 427617 08339a56f3aea3c680eb6668995f460ca4799b33
child 427619 9daa53881b7ae80bf6b093dac5d7744cf7fd18b1
push id34308
push usershindli@mozilla.com
push dateSat, 21 Jul 2018 09:36:16 +0000
treeherdermozilla-central@9daa53881b7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1447777
milestone63.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 1447777 - Move state.completionState to state.request.completeStatus. r=MattN * Spot-fix order details test to clone request before modifying it MozReview-Commit-ID: AXjI1veRSk9
browser/components/payments/res/containers/payment-dialog.js
browser/components/payments/res/debugging.js
browser/components/payments/res/mixins/PaymentStateSubscriberMixin.js
browser/components/payments/res/paymentRequest.css
browser/components/payments/test/mochitest/test_order_details.html
browser/components/payments/test/mochitest/test_payer_address_picker.html
browser/components/payments/test/mochitest/test_payment_dialog.html
--- a/browser/components/payments/res/containers/payment-dialog.js
+++ b/browser/components/payments/res/containers/payment-dialog.js
@@ -199,28 +199,32 @@ export default class PaymentDialog exten
       this.requestStore.setState({
         selectedPayerAddress: Object.keys(addresses)[0] || null,
       });
     }
   }
 
   _renderPayButton(state) {
     this._payButton.disabled = state.changesPrevented;
-    switch (state.completionState) {
+    let completeStatus = state.request.completeStatus;
+    switch (completeStatus) {
       case "initial":
       case "processing":
       case "success":
       case "fail":
       case "unknown":
         break;
+      case "":
+        completeStatus = "initial";
+        break;
       default:
-        throw new Error("Invalid completionState");
+        throw new Error(`Invalid completeStatus: ${completeStatus}`);
     }
 
-    this._payButton.textContent = this._payButton.dataset[state.completionState + "Label"];
+    this._payButton.textContent = this._payButton.dataset[completeStatus + "Label"];
   }
 
   stateChangeCallback(state) {
     super.stateChangeCallback(state);
 
     // Don't dispatch change events for initial selectedShipping* changes at initialization
     // if requestShipping is false.
     if (state.request.paymentOptions.requestShipping) {
@@ -296,23 +300,19 @@ export default class PaymentDialog exten
     this._payerAddressPicker.dataset.editAddressTitle = this.dataset.payerTitleEdit;
 
     this._renderPayButton(state);
 
     for (let page of this._mainContainer.querySelectorAll(":scope > .page")) {
       page.hidden = state.page.id != page.id;
     }
 
-    let {
-      changesPrevented,
-      completionState,
-    } = state;
-    if (changesPrevented) {
+    if (state.changesPrevented) {
       this.setAttribute("changes-prevented", "");
     } else {
       this.removeAttribute("changes-prevented");
     }
-    this.setAttribute("completion-state", completionState);
-    this._disabledOverlay.hidden = !changesPrevented;
+    this.setAttribute("complete-status", request.completeStatus);
+    this._disabledOverlay.hidden = !state.changesPrevented;
   }
 }
 
 customElements.define("payment-dialog", PaymentDialog);
--- a/browser/components/payments/res/debugging.js
+++ b/browser/components/payments/res/debugging.js
@@ -402,43 +402,48 @@ let buttonActions = {
       region: "Can only ship to regions that start with M",
     };
     requestStore.setState({
       request,
     });
   },
 
   setStateDefault() {
-    requestStore.setState({
-      completionState: "initial",
+    let request = Object.assign({}, requestStore.getState().request, {
+      completeStatus: "initial",
     });
+    requestStore.setState({ request });
   },
 
   setStateProcessing() {
-    requestStore.setState({
-      completionState: "processing",
+    let request = Object.assign({}, requestStore.getState().request, {
+      completeStatus: "processing",
     });
+    requestStore.setState({ request });
   },
 
   setStateSuccess() {
-    requestStore.setState({
-      completionState: "success",
+    let request = Object.assign({}, requestStore.getState().request, {
+      completeStatus: "success",
     });
+    requestStore.setState({ request });
   },
 
   setStateFail() {
-    requestStore.setState({
-      completionState: "fail",
+    let request = Object.assign({}, requestStore.getState().request, {
+      completeStatus: "fail",
     });
+    requestStore.setState({ request });
   },
 
   setStateUnknown() {
-    requestStore.setState({
-      completionState: "unknown",
+    let request = Object.assign({}, requestStore.getState().request, {
+      completeStatus: "unknown",
     });
+    requestStore.setState({ request });
   },
 };
 
 window.addEventListener("click", function onButtonClick(evt) {
   let id = evt.target.id;
   if (!id || typeof(buttonActions[id]) != "function") {
     return;
   }
--- a/browser/components/payments/res/mixins/PaymentStateSubscriberMixin.js
+++ b/browser/components/payments/res/mixins/PaymentStateSubscriberMixin.js
@@ -8,17 +8,16 @@ import PaymentsStore from "../PaymentsSt
  * A mixin for a custom element to observe store changes to information about a payment request.
  */
 
 /**
  * State of the payment request dialog.
  */
 export let requestStore = new PaymentsStore({
   changesPrevented: false,
-  completionState: "initial",
   orderDetailsShowing: false,
   "basic-card-page": {
     guid: null,
     // preserveFieldValues: true,
   },
   "address-page": {
     guid: null,
     title: "",
@@ -28,16 +27,17 @@ export let requestStore = new PaymentsSt
   page: {
     id: "payment-summary",
     previousId: null,
     // onboardingWizard: true,
     // error: "",
     // selectedStateKey: "",
   },
   request: {
+    completeStatus: "initial",
     tabId: null,
     topLevelPrincipal: {URI: {displayHost: null}},
     requestId: null,
     paymentMethods: [],
     paymentDetails: {
       id: null,
       totalItem: {label: null, amount: {currency: null, value: 0}},
       displayItems: [],
--- a/browser/components/payments/res/paymentRequest.css
+++ b/browser/components/payments/res/paymentRequest.css
@@ -130,20 +130,20 @@ payment-dialog #pay::before {
   content: url(chrome://browser/skin/connection-secure.svg);
   fill: currentColor;
   height: 16px;
   margin-right: 0.5em;
   vertical-align: text-bottom;
   width: 16px;
 }
 
-payment-dialog[changes-prevented][completion-state="fail"] #pay,
-payment-dialog[changes-prevented][completion-state="unknown"] #pay,
-payment-dialog[changes-prevented][completion-state="processing"] #pay,
-payment-dialog[changes-prevented][completion-state="success"] #pay {
+payment-dialog[changes-prevented][complete-status="fail"] #pay,
+payment-dialog[changes-prevented][complete-status="unknown"] #pay,
+payment-dialog[changes-prevented][complete-status="processing"] #pay,
+payment-dialog[changes-prevented][complete-status="success"] #pay {
   /* Show the pay button above #disabled-overlay */
   position: relative;
   z-index: 1;
 }
 
 #cancel {
   margin-left: auto;
 }
--- a/browser/components/payments/test/mochitest/test_order_details.html
+++ b/browser/components/payments/test/mochitest/test_order_details.html
@@ -122,74 +122,69 @@ add_task(async function test_list_popula
   await asyncElementRendered();
 
   is(orderDetails.mainItemsList.childElementCount, 2, "main list has correct # children");
   is(orderDetails.footerItemsList.childElementCount, 1, "footer list has correct # children");
 });
 
 add_task(async function test_additionalDisplayItems() {
   setup();
-  let state = requestStore.getState();
-  let request = state.request;
-  let paymentDetails = request.paymentDetails;
-
-  paymentDetails.modifiers = [{
-    additionalDisplayItems: [
-      {
-        label: "Card fee",
-        amount: { currency: "USD", value: "1.50" },
+  let request = Object.assign({}, requestStore.getState().request);
+  request.paymentDetails = Object.assign({}, request.paymentDetails, {
+    modifiers: [{
+      additionalDisplayItems: [
+        {
+          label: "Card fee",
+          amount: { currency: "USD", value: "1.50" },
+        },
+      ],
+      supportedMethods: "basic-card",
+      total: {
+        label: "Total due",
+        amount: { currency: "USD", value: "3.50" },
       },
-    ],
-    supportedMethods: "basic-card",
-    total: {
-      label: "Total due",
-      amount: { currency: "USD", value: "3.50" },
-    },
-  }];
-
-  Object.assign(request, { paymentDetails });
-  requestStore.setState(state);
+    }],
+  });
+  requestStore.setState({ request });
   await asyncElementRendered();
 
   is(orderDetails.mainItemsList.childElementCount, 0,
      "main list added 0 children from additionalDisplayItems");
   is(orderDetails.footerItemsList.childElementCount, 1,
      "footer list added children from additionalDisplayItems");
 });
 
 
 add_task(async function test_total() {
   setup();
-  let request = requestStore.getState().request;
-  let paymentDetails = request.paymentDetails;
-  paymentDetails.totalItem = { label: "foo", amount: { currency: "JPY", value: "5" }};
-
-  Object.assign(request, { paymentDetails });
+  let request = Object.assign({}, requestStore.getState().request);
+  request.paymentDetails = Object.assign({}, request.paymentDetails, {
+    totalItem: { label: "foo", amount: { currency: "JPY", value: "5" }},
+  });
   requestStore.setState({ request });
   await asyncElementRendered();
 
   is(orderDetails.totalAmountElem.value, "5", "total amount gets updated");
   is(orderDetails.totalAmountElem.currency, "JPY", "total currency gets updated");
 });
 
 add_task(async function test_modified_total() {
   setup();
-  let state = requestStore.getState();
-  let request = state.request;
-  let paymentDetails = request.paymentDetails;
-  paymentDetails.totalItem = { label: "foo", amount: { currency: "JPY", value: "5" }};
-  paymentDetails.modifiers = [{
-    supportedMethods: "basic-card",
-    total: {
-      label: "Total due",
-      amount: { currency: "USD", value: "3.5" },
-    },
-  }];
-  Object.assign(request, { paymentDetails });
-  requestStore.setState(state);
+  let request = Object.assign({}, requestStore.getState().request);
+  request.paymentDetails = Object.assign({}, request.paymentDetails, {
+    totalItem: { label: "foo", amount: { currency: "JPY", value: "5" }},
+    modifiers: [{
+      supportedMethods: "basic-card",
+      total: {
+        label: "Total due",
+        amount: { currency: "USD", value: "3.5" },
+      },
+    }],
+  });
+  requestStore.setState({request});
   await asyncElementRendered();
 
   is(orderDetails.totalAmountElem.value, "3.5", "total amount uses modifier total");
   is(orderDetails.totalAmountElem.currency, "USD", "total currency uses modifier currency");
 });
 
 </script>
 
--- a/browser/components/payments/test/mochitest/test_payer_address_picker.html
+++ b/browser/components/payments/test/mochitest/test_payer_address_picker.html
@@ -127,19 +127,20 @@ add_task(async function setup_once() {
     let imported = document.importNode(template, true);
     displayEl.appendChild(imported);
   }
 
   elDialog = new PaymentDialog();
   displayEl.appendChild(elDialog);
   elPicker = elDialog.querySelector("address-picker.payer-related");
 
-  initialState = Object.assign({}, elDialog.requestStore.getState(), {
+  let {request} = elDialog.requestStore.getState();
+  initialState = Object.assign({}, {
     changesPrevented: false,
-    completionState: "initial",
+    request: Object.assign({}, request, { completeStatus: "initial" }),
     orderDetailsShowing: false,
   });
 });
 
 async function setup() {
   // reset the store back to a known, default state
   elDialog.requestStore.setState(deepClone(initialState));
   await asyncElementRendered();
--- a/browser/components/payments/test/mochitest/test_payment_dialog.html
+++ b/browser/components/payments/test/mochitest/test_payment_dialog.html
@@ -31,17 +31,17 @@ Test the payment-dialog custom element
 /** Test the payment-dialog element **/
 
 /* global sinon */
 
 import PaymentDialog from "../../res/containers/payment-dialog.js";
 
 let el1;
 
-let completionStates = [
+let completeStatuses = [
     ["processing", "Processing"],
     ["success", "Done"],
     ["fail", "Fail"],
     ["unknown", "Unknown"],
 ];
 
 /* test that:
   the view-all-items button exists
@@ -65,19 +65,20 @@ add_task(async function setup_once() {
   el1 = new PaymentDialog();
   displayEl.appendChild(el1);
 
   sinon.spy(el1, "render");
   sinon.spy(el1, "stateChangeCallback");
 });
 
 async function setup() {
+  let {request} = el1.requestStore.getState();
   await el1.requestStore.setState({
     changesPrevented: false,
-    completionState: "initial",
+    request: Object.assign({}, request, {completeStatus: "initial"}),
     orderDetailsShowing: false,
   });
 
   el1.render.reset();
   el1.stateChangeCallback.reset();
 }
 
 add_task(async function test_initialState() {
@@ -139,44 +140,45 @@ add_task(async function test_changesPrev
   is(state.changesPrevented, false, "changesPrevented is initially false");
   let disabledOverlay = document.getElementById("disabled-overlay");
   ok(disabledOverlay.hidden, "Overlay should initially be hidden");
   await el1.requestStore.setState({changesPrevented: true});
   await asyncElementRendered();
   ok(!disabledOverlay.hidden, "Overlay should prevent changes");
 });
 
-add_task(async function test_completionState() {
+add_task(async function test_completeStatus() {
   await setup();
-  let state = el1.requestStore.getState();
-  is(state.completionState, "initial", "completionState is initially initial");
+  let {request} = el1.requestStore.getState();
+  is(request.completeStatus, "initial", "completeStatus is initially initial");
   let payButton = document.getElementById("pay");
   is(payButton.textContent, "Pay", "Check default label");
   ok(!payButton.disabled, "Button is enabled");
-  for (let [completionState, label] of completionStates) {
-    await el1.requestStore.setState({completionState});
+  for (let [completeStatus, label] of completeStatuses) {
+    request.completeStatus = completeStatus;
+    await el1.requestStore.setState({request});
     await asyncElementRendered();
     is(payButton.textContent, label, "Check payButton label");
     ok(!payButton.disabled, "Button is still enabled");
   }
 });
 
-add_task(async function test_completionStateChangesPrevented() {
+add_task(async function test_completeStatusChangesPrevented() {
   await setup();
   let state = el1.requestStore.getState();
-  is(state.completionState, "initial", "completionState is initially initial");
+  is(state.request.completeStatus, "initial", "completeStatus 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");
 
-  for (let [completionState, label] of completionStates) {
+  for (let [status, label] of completeStatuses) {
     await el1.requestStore.setState({
       changesPrevented: true,
-      completionState,
+      request: Object.assign(state.request, { completeStatus: status }),
     });
     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");