Bug 1468153 - Update the edit strings (Add/Update) and the failure strings to use the hostname. r?mattn draft
authorJared Wein <jwein@mozilla.com>
Mon, 30 Jul 2018 14:22:52 -0400
changeset 824372 892eff3fa7d9672187650508ca9196baeee22612
parent 824238 dead9fcddd4a25fd36d54ab7eb782d7d9b8bb7a1
child 824452 d2be3b1189d3c9b7ec98883c24f237a91817c422
child 824460 2176d0bf2e006210f6f38ccc127571a3d9f793b7
push id117883
push userbmo:jaws@mozilla.com
push dateMon, 30 Jul 2018 18:23:49 +0000
reviewersmattn
bugs1468153
milestone63.0a1
Bug 1468153 - Update the edit strings (Add/Update) and the failure strings to use the hostname. r?mattn MozReview-Commit-ID: HcOMsP5zWBg
browser/components/payments/res/containers/address-form.js
browser/components/payments/res/containers/basic-card-form.js
browser/components/payments/res/containers/completion-error-page.js
browser/components/payments/res/paymentRequest.xhtml
browser/components/payments/test/mochitest/mochitest.ini
browser/components/payments/test/mochitest/test_address_form.html
browser/components/payments/test/mochitest/test_basic_card_form.html
browser/components/payments/test/mochitest/test_completion_error_page.html
--- a/browser/components/payments/res/containers/address-form.js
+++ b/browser/components/payments/res/containers/address-form.js
@@ -108,34 +108,35 @@ export default class AddressForm extends
       request,
     } = state;
 
     if (this.id && page && page.id !== this.id) {
       log.debug(`AddressForm: no need to further render inactive page: ${page.id}`);
       return;
     }
 
+    let editing = !!addressPage.guid;
     this.cancelButton.textContent = this.dataset.cancelButtonLabel;
     this.backButton.textContent = this.dataset.backButtonLabel;
-    this.saveButton.textContent = this.dataset.saveButtonLabel;
+    this.saveButton.textContent = editing ? this.dataset.updateButtonLabel :
+                                            this.dataset.addButtonLabel;
     this.persistCheckbox.label = this.dataset.persistCheckboxLabel;
 
     this.backButton.hidden = page.onboardingWizard;
     this.cancelButton.hidden = !page.onboardingWizard;
 
     if (addressPage.addressFields) {
       this.setAttribute("address-fields", addressPage.addressFields);
     } else {
       this.removeAttribute("address-fields");
     }
 
     this.pageTitleHeading.textContent = addressPage.title;
     this.genericErrorText.textContent = page.error;
 
-    let editing = !!addressPage.guid;
     let addresses = paymentRequest.getAddresses(state);
 
     // If an address is selected we want to edit it.
     if (editing) {
       record = addresses[addressPage.guid];
       if (!record) {
         throw new Error("Trying to edit a non-existing address: " + addressPage.guid);
       }
--- a/browser/components/payments/res/containers/basic-card-form.js
+++ b/browser/components/payments/res/containers/basic-card-form.js
@@ -110,35 +110,36 @@ export default class BasicCardForm exten
       "basic-card-page": basicCardPage,
     } = state;
 
     if (this.id && page && page.id !== this.id) {
       log.debug(`BasicCardForm: no need to further render inactive page: ${page.id}`);
       return;
     }
 
+    let editing = !!basicCardPage.guid;
     this.cancelButton.textContent = this.dataset.cancelButtonLabel;
     this.backButton.textContent = this.dataset.backButtonLabel;
-    this.saveButton.textContent = this.dataset.saveButtonLabel;
+    this.saveButton.textContent = editing ? this.dataset.updateButtonLabel :
+                                            this.dataset.addButtonLabel;
     this.persistCheckbox.label = this.dataset.persistCheckboxLabel;
     this.addressAddLink.textContent = this.dataset.addressAddLinkLabel;
     this.addressEditLink.textContent = this.dataset.addressEditLinkLabel;
 
     // The next line needs an onboarding check since we don't set previousId
     // when navigating to add/edit directly from the summary page.
     this.backButton.hidden = !page.previousId && page.onboardingWizard;
     this.cancelButton.hidden = !page.onboardingWizard;
 
     let record = {};
     let basicCards = paymentRequest.getBasicCards(state);
     let addresses = paymentRequest.getAddresses(state);
 
     this.genericErrorText.textContent = page.error;
 
-    let editing = !!basicCardPage.guid;
     this.form.querySelector("#cc-number").disabled = editing;
 
     // If a card is selected we want to edit it.
     if (editing) {
       this.pageTitleHeading.textContent = this.dataset.editBasicCardTitle;
       record = basicCards[basicCardPage.guid];
       if (!record) {
         throw new Error("Trying to edit a non-existing card: " + basicCardPage.guid);
--- a/browser/components/payments/res/containers/completion-error-page.js
+++ b/browser/components/payments/res/containers/completion-error-page.js
@@ -34,23 +34,29 @@ export default class CompletionErrorPage
   render(state) {
     let { page } = state;
 
     if (this.id && page && page.id !== this.id) {
       log.debug(`CompletionErrorPage: no need to further render inactive page: ${page.id}`);
       return;
     }
 
+    let {request} = this.requestStore.getState();
+    let {displayHost} = request.topLevelPrincipal.URI;
+    for (let key of ["pageTitle", "suggestion-1", "suggestion-2", "suggestion-3"]) {
+      this.dataset[key] = this.dataset[key].replace("**host-name**", displayHost);
+    }
+
     this.pageTitleHeading.textContent = this.dataset.pageTitle;
     this.doneButton.textContent = this.dataset.doneButtonLabel;
 
     this.suggestionsList.textContent = "";
-
-     // FIXME: should come from this.dataset.suggestionN when those strings are created
-    this.suggestions[0] = "First suggestion";
+    this.suggestions[0] = this.dataset["suggestion-1"];
+    this.suggestions[1] = this.dataset["suggestion-2"];
+    this.suggestions[2] = this.dataset["suggestion-3"];
 
     let suggestionsFragment = document.createDocumentFragment();
     for (let suggestionText of this.suggestions) {
       let listNode = document.createElement("li");
       listNode.textContent = suggestionText;
       suggestionsFragment.appendChild(listNode);
     }
     this.suggestionsList.appendChild(suggestionsFragment);
--- a/browser/components/payments/res/paymentRequest.xhtml
+++ b/browser/components/payments/res/paymentRequest.xhtml
@@ -42,32 +42,34 @@
   <!ENTITY successPaymentButton.label    "Done">
   <!ENTITY unknownPaymentButton.label    "Unknown">
   <!ENTITY orderDetailsLabel          "Order Details">
   <!ENTITY orderTotalLabel            "Total">
   <!ENTITY basicCardPage.error.genericSave    "There was an error saving the payment card.">
   <!ENTITY basicCardPage.addressAddLink.label "Add">
   <!ENTITY basicCardPage.addressEditLink.label "Edit">
   <!ENTITY basicCardPage.backButton.label     "Back">
-  <!ENTITY basicCardPage.saveButton.label     "Save">
+  <!ENTITY basicCardPage.addButton.label      "Add">
+  <!ENTITY basicCardPage.updateButton.label   "Update">
   <!ENTITY basicCardPage.persistCheckbox.label     "Save credit card to &brandShortName; (Security code will not be saved)">
   <!ENTITY addressPage.error.genericSave      "There was an error saving the address.">
   <!ENTITY addressPage.cancelButton.label     "Cancel">
   <!ENTITY addressPage.backButton.label       "Back">
-  <!ENTITY addressPage.saveButton.label       "Save">
+  <!ENTITY addressPage.addButton.label        "Add">
+  <!ENTITY addressPage.updateButton.label     "Update">
   <!ENTITY addressPage.persistCheckbox.label  "Save address to &brandShortName;">
   <!ENTITY failErrorPage.title  "Sorry! Something went wrong with the payment process.">
   <!ENTITY failErrorPage.suggestion1  "Check your credit card has not expired.">
   <!ENTITY failErrorPage.suggestion2  "Make sure your credit card information is accurate.">
-  <!ENTITY failErrorPage.suggestion3  "If no other solutions work, check with shopping.com.">
+  <!ENTITY failErrorPage.suggestion3  "If no other solutions work, check with **host-name**.">
   <!ENTITY failErrorPage.doneButton.label     "OK">
-  <!ENTITY timeoutErrorPage.title  "Whoops! Shopping.com took too long to respond.">
+  <!ENTITY timeoutErrorPage.title  "Whoops! **host-name** took too long to respond.">
   <!ENTITY timeoutErrorPage.suggestion1  "Try again later.">
   <!ENTITY timeoutErrorPage.suggestion2  "Check your network connection." >
-  <!ENTITY timeoutErrorPage.suggestion3  "If no other solutions work, check with shopping.com.">
+  <!ENTITY timeoutErrorPage.suggestion3  "If no other solutions work, check with **host-name**.">
   <!ENTITY timeoutErrorPage.doneButton.label     "OK">
 ]>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title>&paymentSummaryTitle;</title>
 
   <!-- chrome: is needed for global.dtd -->
   <meta http-equiv="Content-Security-Policy" content="default-src 'self' chrome:"/>
@@ -149,35 +151,43 @@
                        data-add-basic-card-title="&basicCard.addPage.title;"
                        data-edit-basic-card-title="&basicCard.editPage.title;"
                        data-error-generic-save="&basicCardPage.error.genericSave;"
                        data-address-add-link-label="&basicCardPage.addressAddLink.label;"
                        data-address-edit-link-label="&basicCardPage.addressEditLink.label;"
                        data-billing-address-title-add="&billingAddress.addPage.title;"
                        data-billing-address-title-edit="&billingAddress.editPage.title;"
                        data-back-button-label="&basicCardPage.backButton.label;"
-                       data-save-button-label="&basicCardPage.saveButton.label;"
+                       data-add-button-label="&basicCardPage.addButton.label;"
+                       data-update-button-label="&basicCardPage.updateButton.label;"
                        data-cancel-button-label="&cancelPaymentButton.label;"
                        data-persist-checkbox-label="&basicCardPage.persistCheckbox.label;"
                        hidden="hidden"></basic-card-form>
 
       <address-form id="address-page"
                     data-error-generic-save="&addressPage.error.genericSave;"
                     data-cancel-button-label="&addressPage.cancelButton.label;"
                     data-back-button-label="&addressPage.backButton.label;"
-                    data-save-button-label="&addressPage.saveButton.label;"
+                    data-add-button-label="&addressPage.addButton.label;"
+                    data-update-button-label="&addressPage.updateButton.label;"
                     data-persist-checkbox-label="&addressPage.persistCheckbox.label;"
                     hidden="hidden"></address-form>
 
       <completion-error-page id="completion-timeout-error" class="illustrated"
                   data-page-title="&timeoutErrorPage.title;"
+                  data-suggestion-1="&timeoutErrorPage.suggestion1;"
+                  data-suggestion-2="&timeoutErrorPage.suggestion2;"
+                  data-suggestion-3="&timeoutErrorPage.suggestion3;"
                   data-done-button-label="&timeoutErrorPage.doneButton.label;"
                   hidden="hidden"></completion-error-page>
       <completion-error-page id="completion-fail-error" class="illustrated"
                   data-page-title="&failErrorPage.title;"
+                  data-suggestion-1="&failErrorPage.suggestion1;"
+                  data-suggestion-2="&failErrorPage.suggestion2;"
+                  data-suggestion-3="&failErrorPage.suggestion3;"
                   data-done-button-label="&failErrorPage.doneButton.label;"
                   hidden="hidden"></completion-error-page>
     </div>
 
     <div id="disabled-overlay" hidden="hidden">
       <!-- overlay to prevent changes while waiting for a response from the merchant -->
     </div>
   </template>
--- a/browser/components/payments/test/mochitest/mochitest.ini
+++ b/browser/components/payments/test/mochitest/mochitest.ini
@@ -8,16 +8,17 @@ support-files =
    ../../../../../testing/modules/sinon-2.3.2.js
    ../../res/**
    payments_common.js
 skip-if = !e10s
 
 [test_address_form.html]
 [test_address_picker.html]
 [test_basic_card_form.html]
+[test_completion_error_page.html]
 [test_currency_amount.html]
 [test_labelled_checkbox.html]
 [test_order_details.html]
 [test_payer_address_picker.html]
 [test_payment_dialog.html]
 [test_payment_dialog_required_top_level_items.html]
 [test_payment_details_item.html]
 [test_payment_method_picker.html]
--- a/browser/components/payments/test/mochitest/test_address_form.html
+++ b/browser/components/payments/test/mochitest/test_address_form.html
@@ -103,17 +103,17 @@ add_task(async function test_backButton(
   let {page} = await stateChangePromise;
   is(page.id, "payment-summary", "Check initial page after appending");
 
   form.remove();
 });
 
 add_task(async function test_saveButton() {
   let form = new AddressForm();
-  form.dataset.saveButtonLabel = "Save";
+  form.dataset.addButtonLabel = "Add";
   form.dataset.errorGenericSave = "Generic error";
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   form.form.querySelector("#given-name").focus();
   sendString("Jaws");
   form.form.querySelector("#family-name").focus();
@@ -130,17 +130,17 @@ add_task(async function test_saveButton(
   sendString("00001");
   form.form.querySelector("#country option[value='US']").selected = true;
   form.form.querySelector("#email").focus();
   sendString("test@example.com");
   form.form.querySelector("#tel").focus();
   sendString("+15555551212");
 
   let messagePromise = promiseContentToChromeMessage("updateAutofillRecord");
-  is(form.saveButton.textContent, "Save", "Check label");
+  is(form.saveButton.textContent, "Add", "Check label");
   form.saveButton.scrollIntoView();
   synthesizeMouseAtCenter(form.saveButton, {});
 
   let details = await messagePromise;
   ok(typeof(details.messageID) == "number" && details.messageID > 0, "Check messageID type");
   delete details.messageID;
   is(details.collectionName, "addresses", "Check collectionName");
   isDeeply(details, {
@@ -178,16 +178,17 @@ add_task(async function test_genericErro
 
   ok(!isHidden(form.genericErrorText), "Error message should be visible");
   is(form.genericErrorText.textContent, "Generic Error", "Check error message");
   form.remove();
 });
 
 add_task(async function test_edit() {
   let form = new AddressForm();
+  form.dataset.updateButtonLabel = "Update";
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   let address1 = deepClone(PTU.Addresses.TimBL);
   address1.guid = "9864798564";
 
   await form.requestStore.setState({
@@ -216,16 +217,17 @@ add_task(async function test_edit() {
     "address-page": {
       guid: minimalAddress.guid,
     },
     savedAddresses: {
       [minimalAddress.guid]: deepClone(minimalAddress),
     },
   });
   await asyncElementRendered();
+  is(form.saveButton.textContent, "Update", "Check label");
   checkAddressForm(form, minimalAddress);
 
   info("change to no selected address");
   await form.requestStore.setState({
     page: {
       id: "address-page",
     },
     "address-page": {},
@@ -233,17 +235,17 @@ add_task(async function test_edit() {
   await asyncElementRendered();
   checkAddressForm(form, {});
 
   form.remove();
 });
 
 add_task(async function test_restricted_address_fields() {
   let form = new AddressForm();
-  form.dataset.saveButtonLabel = "Save";
+  form.dataset.addButtonLabel = "Add";
   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");
--- a/browser/components/payments/test/mochitest/test_basic_card_form.html
+++ b/browser/components/payments/test/mochitest/test_basic_card_form.html
@@ -85,17 +85,17 @@ add_task(async function test_backButton(
   let {page} = await stateChangePromise;
   is(page.id, "payment-summary", "Check initial page after appending");
 
   form.remove();
 });
 
 add_task(async function test_saveButton() {
   let form = new BasicCardForm();
-  form.dataset.saveButtonLabel = "Save";
+  form.dataset.addButtonLabel = "Add";
   form.dataset.errorGenericSave = "Generic error";
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   ok(form.saveButton.disabled, "Save button should initially be disabled");
   form.form.querySelector("#cc-number").focus();
   sendString("4111 1111-1111 1111");
@@ -108,17 +108,17 @@ add_task(async function test_saveButton(
   form.form.querySelector("#cc-exp-year").focus();
   let year = (new Date()).getFullYear().toString();
   sendString(year);
   form.saveButton.focus();
   ok(!form.saveButton.disabled,
      "Save button should be enabled since the required fields are filled");
 
   let messagePromise = promiseContentToChromeMessage("updateAutofillRecord");
-  is(form.saveButton.textContent, "Save", "Check label");
+  is(form.saveButton.textContent, "Add", "Check label");
   synthesizeMouseAtCenter(form.saveButton, {});
 
   let details = await messagePromise;
   ok(typeof(details.messageID) == "number" && details.messageID > 0, "Check messageID type");
   delete details.messageID;
   is(details.collectionName, "creditCards", "Check collectionName");
   isDeeply(details, {
     collectionName: "creditCards",
@@ -231,16 +231,17 @@ add_task(async function test_add_noSelec
   });
 
   form.remove();
   await form.requestStore.reset();
 });
 
 add_task(async function test_edit() {
   let form = new BasicCardForm();
+  form.dataset.updateButtonLabel = "Update";
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   info("test year before current");
   let card1 = deepClone(PTU.BasicCards.JohnDoe);
   card1.guid = "9864798564";
   card1["cc-exp-year"] = 2011;
@@ -252,16 +253,17 @@ add_task(async function test_edit() {
     "basic-card-page": {
       guid: card1.guid,
     },
     savedBasicCards: {
       [card1.guid]: deepClone(card1),
     },
   });
   await asyncElementRendered();
+  is(form.saveButton.textContent, "Update", "Check label");
   checkCCForm(form, card1);
 
   info("test future year");
   card1["cc-exp-year"] = 2100;
 
   await form.requestStore.setState({
     savedBasicCards: {
       [card1.guid]: deepClone(card1),
copy from browser/components/payments/test/mochitest/test_labelled_checkbox.html
copy to browser/components/payments/test/mochitest/test_completion_error_page.html
--- a/browser/components/payments/test/mochitest/test_labelled_checkbox.html
+++ b/browser/components/payments/test/mochitest/test_completion_error_page.html
@@ -1,73 +1,71 @@
 <!DOCTYPE HTML>
 <html>
 <!--
-Test the labelled-checkbox component
+Test the completion-error-page component
 -->
 <head>
   <meta charset="utf-8">
-  <title>Test the labelled-checkbox component</title>
+  <title>Test the completion-error-page component</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/AddTask.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"/>
 </head>
 <body>
   <p id="display">
-    <labelled-checkbox id="box0"></labelled-checkbox>
-    <labelled-checkbox id="box1" label="the label" value="the value"></labelled-checkbox>
+    <completion-error-page id="completion-timeout-error" class="illustrated"
+            data-page-title="Sample Title"
+            data-suggestion-1="Sample suggestion"
+            data-suggestion-2="Sample suggestion"
+            data-suggestion-3="Sample suggestion"
+            data-done-button-label="OK"></completion-error-page>
   </p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 <script type="module">
-/** Test the labelled-checkbox component **/
+/** Test the completion-error-page component **/
 
-import "../../res/components/labelled-checkbox.js";
+import "../../res/containers/completion-error-page.js";
 
-let box0 = document.getElementById("box0");
-let box1 = document.getElementById("box1");
+let page = document.getElementById("completion-timeout-error");
 
 add_task(async function test_no_values() {
-  ok(box0, "box0 exists");
-  is(box0.label, null, "Initially un-labelled");
-  is(box0.value, null, "Check .value");
-  ok(!box0.checked, "Initially is not checked");
-  ok(!box0.querySelector("input:checked"), "has no checked inner input");
+  ok(page, "page exists");
+  is(page.dataset.pageTitle, "Sample Title", "Title set on page");
+  is(page.dataset["suggestion-1"], "Sample suggestion", "Suggestion 1 set on page");
+  is(page.dataset["suggestion-2"], "Sample suggestion", "Suggestion 2 set on page");
+  is(page.dataset["suggestion-3"], "Sample suggestion", "Suggestion 3 set on page");
 
-  box0.checked = true;
-  box0.value = "New value";
-  box0.label = "New label";
-
+  page.dataset.pageTitle = "Oh noes! **host-name** is having an issue";
+  page.dataset["suggestion-2"] = "You should probably blame **host-name**, not us";
+  const displayHost = "allizom.com";
+  let request = { topLevelPrincipal: { URI: { displayHost } } };
+  await page.requestStore.setState({
+    changesPrevented: false,
+    request: Object.assign({}, request, {completeStatus: ""}),
+    orderDetailsShowing: false,
+    page: {
+      id: "completion-timeout-error",
+    },
+  });
   await asyncElementRendered();
 
-  ok(box0.checked, "Becomes checked");
-  ok(box0.querySelector("input:checked"), "has a checked inner input");
-  is(box0.getAttribute("label"), "New label", "Assigned label");
-  is(box0.getAttribute("value"), "New value", "Assigned value");
+  is(page.requestStore.getState().request.topLevelPrincipal.URI.displayHost, displayHost,
+     "State should have the displayHost set properly");
+  is(page.dataset.pageTitle, `Oh noes! ${displayHost} is having an issue`,
+     "Title includes host-name");
+  is(page.dataset["suggestion-1"], "Sample suggestion", "Suggestion 1 set on page");
+  is(page.dataset["suggestion-2"], `You should probably blame ${displayHost}, not us`,
+     "Suggestion 2 includes host-name");
+  is(page.dataset["suggestion-3"], "Sample suggestion", "Suggestion 3 set on page");
 });
-
-add_task(async function test_initial_values() {
-  is(box1.label, "the label", "Initial label");
-  is(box1.value, "the value", "Initial value");
-  ok(!box1.checked, "Initially unchecked");
-  ok(!box1.querySelector("input:checked"), "has no checked inner input");
-
-  box1.checked = false;
-  box1.value = "New value";
-  box1.label = "New label";
-
-  await asyncElementRendered();
-
-  ok(!box1.checked, "Checked property remains falsey");
-  is(box1.getAttribute("value"), "New value", "Assigned value");
-  is(box1.getAttribute("label"), "New label", "Assigned label");
-});
-
 </script>
 
 </body>
 </html>