author | Matthew Noorenberghe <mozilla@noorenberghe.ca> |
Fri, 13 Apr 2018 17:25:13 -0700 | |
changeset 413973 | 69383ad18409381ba12aa29c84d550eaa07b75d0 |
parent 413972 | f22a918616f8457e25115c54e3517fc18265d8e2 |
child 413974 | a8aeb060a6c8fb048a334ea9bc6b2de0fe8d3bf2 |
push id | 33853 |
push user | cbrindusan@mozilla.com |
push date | Tue, 17 Apr 2018 09:51:13 +0000 |
treeherder | mozilla-central@8b0ba3f7d099 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jaws |
bugs | 1428472 |
milestone | 61.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
|
--- a/toolkit/components/payments/res/PaymentsStore.js +++ b/toolkit/components/payments/res/PaymentsStore.js @@ -8,16 +8,17 @@ * state propagation. */ export default class PaymentsStore { /** * @param {object} [defaultState = {}] The initial state of the store. */ constructor(defaultState = {}) { + this._defaultState = Object.assign({}, defaultState); this._state = defaultState; this._nextNotifification = 0; this._subscribers = new Set(); } /** * Get the current state as a shallow clone with a shallow freeze. * You shouldn't modify any part of the returned state object as that would bypass notifying @@ -25,16 +26,24 @@ export default class PaymentsStore { * * @returns {Object} containing the current state */ getState() { return Object.freeze(Object.assign({}, this._state)); } /** + * Used for testing to reset to the default state from the constructor. + * @returns {Promise} returned by setState. + */ + async reset() { + return this.setState(this._defaultState); + } + + /** * Augment the current state with the keys of `obj` and asynchronously notify * state subscribers. As a result, multiple synchronous state changes will lead * to a single subscriber notification which leads to better performance and * reduces partial state changes. * * @param {Object} obj The object to augment the state with. Keys in the object * will be shallow copied with Object.assign. *
--- a/toolkit/components/payments/res/containers/basic-card-form.js +++ b/toolkit/components/payments/res/containers/basic-card-form.js @@ -73,29 +73,32 @@ export default class BasicCardForm exten this.backButton.textContent = this.dataset.backButtonLabel; this.saveButton.textContent = this.dataset.saveButtonLabel; let record = {}; let { page, savedAddresses, savedBasicCards, + selectedShippingAddress, } = state; this.genericErrorText.textContent = page.error; let editing = !!page.guid; this.form.querySelector("#cc-number").disabled = editing; // If a card is selected we want to edit it. if (editing) { record = savedBasicCards[page.guid]; if (!record) { throw new Error("Trying to edit a non-existing card: " + page.guid); } + } else if (selectedShippingAddress) { + record.billingAddressGUID = selectedShippingAddress; } this.formHandler.loadRecord(record, savedAddresses); } handleEvent(event) { switch (event.type) { case "click": {
--- a/toolkit/components/payments/res/containers/payment-dialog.js +++ b/toolkit/components/payments/res/containers/payment-dialog.js @@ -9,16 +9,17 @@ import PaymentStateSubscriberMixin from import "../components/currency-amount.js"; import "./address-picker.js"; import "./basic-card-form.js"; import "./order-details.js"; import "./payment-method-picker.js"; import "./shipping-option-picker.js"; /* global paymentRequest */ +/* import-globals-from ../unprivileged-fallbacks.js */ /** * <payment-dialog></payment-dialog> */ export default class PaymentDialog extends PaymentStateSubscriberMixin(HTMLElement) { constructor() { super(); @@ -116,16 +117,17 @@ export default class PaymentDialog exten */ setStateFromParent(state) { let oldSavedAddresses = this.requestStore.getState().savedAddresses; this.requestStore.setState(state); // Check if any foreign-key constraints were invalidated. state = this.requestStore.getState(); let { + request: {paymentOptions: {requestShipping: requestShipping}}, savedAddresses, savedBasicCards, selectedPayerAddress, selectedPaymentCard, selectedShippingAddress, selectedShippingOption, } = state; let shippingOptions = state.request.paymentDetails.shippingOptions; @@ -141,18 +143,23 @@ export default class PaymentDialog exten if (oldShippingAddress && shippingAddress.guid == oldShippingAddress.guid && shippingAddress.timeLastModified != oldShippingAddress.timeLastModified) { delete this._cachedState.selectedShippingAddress; } } else { // assign selectedShippingAddress as value if it is undefined, // or if the address it pointed to was removed from storage + let defaultShippingAddress = null; + if (requestShipping) { + defaultShippingAddress = Object.keys(savedAddresses)[0]; + log.debug("selecting the default shipping address"); + } this.requestStore.setState({ - selectedShippingAddress: Object.keys(savedAddresses)[0] || null, + selectedShippingAddress: defaultShippingAddress || null, }); } // Ensure `selectedPaymentCard` never refers to a deleted payment card and refers // to a payment card if one exists. if (!savedBasicCards[selectedPaymentCard]) { this.requestStore.setState({ selectedPaymentCard: Object.keys(savedBasicCards)[0] || null,
--- a/toolkit/components/payments/res/debugging.js +++ b/toolkit/components/payments/res/debugging.js @@ -305,21 +305,21 @@ let buttonActions = { setChangesPrevented() { requestStore.setState({ changesPrevented: true, }); }, setRequest1() { - requestStore.setState({request: REQUEST_1}); + paymentDialog.setStateFromParent({request: REQUEST_1}); }, setRequest2() { - requestStore.setState({request: REQUEST_2}); + paymentDialog.setStateFromParent({request: REQUEST_2}); }, setRequestPayerName() { buttonActions.setPaymentOptions(); }, setRequestPayerEmail() { buttonActions.setPaymentOptions(); },
--- a/toolkit/components/payments/test/browser/browser_change_shipping.js +++ b/toolkit/components/payments/test/browser/browser_change_shipping.js @@ -138,16 +138,17 @@ add_task(async function test_address_edi gBrowser, url: BLANK_PAGE_URL, }, async browser => { let {win, frame} = await setupPaymentDialog(browser, { methodData: [PTU.MethodData.basicCard], details: PTU.Details.twoShippingOptions, merchantTaskFn: PTU.ContentTasks.createAndShowRequest, + options: PTU.Options.requestShippingOption, } ); let addressOptions = await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.getShippingAddresses); info("initial addressOptions: " + JSON.stringify(addressOptions)); let selectedIndex = addressOptions.selectedOptionIndex; let selectedAddressGuid = addressOptions.options[selectedIndex].guid; @@ -191,16 +192,17 @@ add_task(async function test_address_rem gBrowser, url: BLANK_PAGE_URL, }, async browser => { let {win, frame} = await setupPaymentDialog(browser, { methodData: [PTU.MethodData.basicCard], details: PTU.Details.twoShippingOptions, merchantTaskFn: PTU.ContentTasks.createAndShowRequest, + options: PTU.Options.requestShippingOption, } ); let addressOptions = await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.getShippingAddresses); info("initial addressOptions: " + JSON.stringify(addressOptions)); let selectedIndex = addressOptions.selectedOptionIndex; let selectedAddressGuid = addressOptions.options[selectedIndex].guid;
--- a/toolkit/components/payments/test/mochitest/mochitest.ini +++ b/toolkit/components/payments/test/mochitest/mochitest.ini @@ -1,12 +1,13 @@ [DEFAULT] prefs = dom.webcomponents.customelements.enabled=false support-files = + !/browser/extensions/formautofill/content/editCreditCard.xhtml ../../../../../browser/extensions/formautofill/content/autofillEditForms.js ../../../../../testing/modules/sinon-2.3.2.js ../../res/** payments_common.js skip-if = !e10s [test_address_picker.html] [test_basic_card_form.html]
--- a/toolkit/components/payments/test/mochitest/test_basic_card_form.html +++ b/toolkit/components/payments/test/mochitest/test_basic_card_form.html @@ -34,16 +34,17 @@ Test the basic-card-form element /* import-globals-from payments_common.js */ import BasicCardForm from "../../res/containers/basic-card-form.js"; let display = document.getElementById("display"); function checkCCForm(customEl, expectedCard) { const CC_PROPERTY_NAMES = [ + "billingAddressGUID", "cc-number", "cc-name", "cc-exp-month", "cc-exp-year", ]; for (let propName of CC_PROPERTY_NAMES) { let expectedVal = expectedCard[propName] || ""; is(document.getElementById(propName).value, @@ -148,17 +149,92 @@ add_task(async function test_genericErro display.appendChild(form); await asyncElementRendered(); 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_record() { +add_task(async function test_add_selectedShippingAddress() { + let form = new BasicCardForm(); + await form.promiseReady; + display.appendChild(form); + await asyncElementRendered(); + + info("have an existing card in storage"); + let card1 = deepClone(PTU.BasicCards.JohnDoe); + card1.guid = "9864798564"; + card1["cc-exp-year"] = 2011; + + let address1 = deepClone(PTU.Addresses.TimBL); + address1.guid = "TimBLGUID"; + + await form.requestStore.setState({ + page: { + id: "basic-card-page", + }, + savedAddresses: { + [address1.guid]: deepClone(address1), + }, + savedBasicCards: { + [card1.guid]: deepClone(card1), + }, + selectedShippingAddress: address1.guid, + }); + await asyncElementRendered(); + checkCCForm(form, { + billingAddressGUID: address1.guid, + }); + + form.remove(); + await form.requestStore.reset(); +}); + +add_task(async function test_add_noSelectedShippingAddress() { + let form = new BasicCardForm(); + await form.promiseReady; + display.appendChild(form); + await asyncElementRendered(); + + info("have an existing card in storage but unused"); + let card1 = deepClone(PTU.BasicCards.JohnDoe); + card1.guid = "9864798564"; + card1["cc-exp-year"] = 2011; + + let address1 = deepClone(PTU.Addresses.TimBL); + address1.guid = "TimBLGUID"; + + await form.requestStore.setState({ + page: { + id: "basic-card-page", + }, + savedAddresses: { + [address1.guid]: deepClone(address1), + }, + savedBasicCards: { + [card1.guid]: deepClone(card1), + }, + selectedShippingAddress: null, + }); + await asyncElementRendered(); + checkCCForm(form, {}); + + info("now test with a missing selectedShippingAddress"); + await form.requestStore.setState({ + selectedShippingAddress: "some-missing-guid", + }); + await asyncElementRendered(); + checkCCForm(form, {}); + + form.remove(); + await form.requestStore.reset(); +}); + +add_task(async function test_edit() { let form = new BasicCardForm(); await form.promiseReady; display.appendChild(form); await asyncElementRendered(); info("test year before current"); let card1 = deepClone(PTU.BasicCards.JohnDoe); card1.guid = "9864798564";