From 7fd5da0bd924282d11c38c32bfdc4871801630ca Mon Sep 17 00:00:00 2001 From: Josh Smith Date: Thu, 1 Dec 2016 15:46:35 -0800 Subject: [PATCH] Fix card loading --- app/components/donation/credit-card.js | 3 +- app/components/donation/donation-container.js | 24 +++++++- app/controllers/project/donate.js | 15 +++-- .../components/donation/credit-card.hbs | 15 +++-- .../donation/donation-container.hbs | 23 +++++--- app/templates/project/donate.hbs | 2 +- mirage/scenarios/default.js | 6 ++ .../components/donation/credit-card-test.js | 4 +- .../donation/donation-container-test.js | 56 +++++++++++++++++-- .../pages/components/donation/credit-card.js | 3 +- 10 files changed, 116 insertions(+), 35 deletions(-) diff --git a/app/components/donation/credit-card.js b/app/components/donation/credit-card.js index 6e63db185..5bc04a520 100644 --- a/app/components/donation/credit-card.js +++ b/app/components/donation/credit-card.js @@ -23,7 +23,7 @@ export default Component.extend({ cardInvalid: not('cardValid'), cardValid: and('isCardNumberValid', 'isCVCValid', 'isExpiryValid'), - isBusyOrInvalid: or('isBusy', 'cardInvalid'), + isProcessingOrInvalid: or('isProcessing', 'cardInvalid'), date: computed('month', 'year', function() { let month = this.get('month'); @@ -81,7 +81,6 @@ export default Component.extend({ actions: { submit() { - this.set('isSubmitting', true); let cardAttrs = this.getProperties('cvc', 'cardNumber', 'year', 'month'); let onSubmit = this.get('submit'); diff --git a/app/components/donation/donation-container.js b/app/components/donation/donation-container.js index 025e2b9fc..a1861ac13 100644 --- a/app/components/donation/donation-container.js +++ b/app/components/donation/donation-container.js @@ -1,11 +1,31 @@ import Ember from 'ember'; const { - Component + Component, + computed: { + and, empty, or + } } = Ember; export default Component.extend({ classNames: ['donation-container'], donationAmount: 0, - projectTitle: null + projectTitle: null, + wasNewCard: true, + + /** + * If there is no card for the user, this might be an ObjectProxy + * that has `null` content. This `card.id` approach was the least + * hacky way we could think to deal with this late one night. + * + * TODO: Find a better approach! + */ + isNewCard: empty('card.id'), + shouldShowNewForm: or('isNewCard', 'subscribingWithNewCard'), + subscribingWithNewCard: and('isProcessing', 'wasNewCard'), + + init() { + this._super(...arguments); + this.set('wasNewCard', this.get('isNewCard')); + } }); diff --git a/app/controllers/project/donate.js b/app/controllers/project/donate.js index a55c9edd0..1b8774bae 100644 --- a/app/controllers/project/donate.js +++ b/app/controllers/project/donate.js @@ -18,7 +18,6 @@ const SUBSCRIPTION_VALIDATION_ERROR = "The amount you've set for your monthly do export default Controller.extend({ amount: null, - isAddingCard: false, queryParams: ['amount'], currentUser: service(), @@ -28,29 +27,29 @@ export default Controller.extend({ project: alias('model'), user: alias('currentUser.user'), - stripeCustomerCreated: bool('currentUser.user.stripePlatformCustomer.id'), + stripeCustomerCreated: bool('user.stripePlatformCustomer.id'), shouldCreateCustomer: not('stripeCustomerCreated'), actions: { saveAndDonate(amount, cardParams) { this._clearErrors(); - this._updateIsLoading(true); + this._updateisProcessing(true); return this._createCreditCardToken(cardParams) .then((stripeResponse) => this._createCardForPlatformCustomer(stripeResponse)) .then((stripeCard) => this._createSubscription(amount, stripeCard)) .then(() => this._transitionToThankYou()) .catch((response) => this._handleError(response)) - .finally(() => this._updateIsLoading(false)); + .finally(() => this._updateisProcessing(false)); }, donate(amount, stripeCard) { this._clearErrors(); - this._updateIsLoading(true); + this._updateisProcessing(true); return this._createSubscription(amount, stripeCard) .then(() => this._transitionToThankYou()) - .finally(() => this._updateIsLoading(false)); + .finally(() => this._updateisProcessing(false)); } }, @@ -163,8 +162,8 @@ export default Controller.extend({ }; }, - _updateIsLoading(value) { - set(this, 'isLoading', value); + _updateisProcessing(value) { + set(this, 'isProcessing', value); }, _clearErrors() { diff --git a/app/templates/components/donation/credit-card.hbs b/app/templates/components/donation/credit-card.hbs index 9f781a467..e3281163f 100644 --- a/app/templates/components/donation/credit-card.hbs +++ b/app/templates/components/donation/credit-card.hbs @@ -41,13 +41,18 @@ -{{#unless isBusy}} +{{#unless isProcessing}} {{!validation errors can be passed in from parent, using a block}} {{yield}} {{/unless}} diff --git a/app/templates/components/donation/donation-container.hbs b/app/templates/components/donation/donation-container.hbs index 458dd032a..625183207 100644 --- a/app/templates/components/donation/donation-container.hbs +++ b/app/templates/components/donation/donation-container.hbs @@ -11,17 +11,26 @@

-{{#if card}} - {{donation/card-item card=card}} -{{else}} - {{#donation/credit-card isBusy=isBusy submit=(action saveAndDonate)}} +{{#if shouldShowNewForm}} + {{#donation/credit-card isProcessing=isProcessing submit=(action saveAndDonate)}} {{!show errors}} {{yield}} {{/donation/credit-card}} -{{/if}} +{{else}} + {{donation/card-item card=card}} + -{{#if card}} - {{!show errors}} {{yield}} {{/if}} diff --git a/app/templates/project/donate.hbs b/app/templates/project/donate.hbs index a54085144..f973ae925 100644 --- a/app/templates/project/donate.hbs +++ b/app/templates/project/donate.hbs @@ -3,7 +3,7 @@ card=user.stripePlatformCard donate=(action 'donate' amount user.stripePlatformCard) donationAmount=amount - isBusy=isLoading + isProcessing=isProcessing projectTitle=project.title saveAndDonate=(action 'saveAndDonate' amount) }} diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js index ea946f6cb..c3a120028 100644 --- a/mirage/scenarios/default.js +++ b/mirage/scenarios/default.js @@ -253,6 +253,12 @@ export default function(server) { server.create('project-category', { category, project }); }); + organization.createStripeConnectAccount(); + + project.createStripeConnectPlan(); + + server.create('stripe-platform-customer', { user: owner }); + server.create('stripe-platform-card', { user: owner }); server.create('donation-goal', { diff --git a/tests/integration/components/donation/credit-card-test.js b/tests/integration/components/donation/credit-card-test.js index c9b1cd899..23d6b641a 100644 --- a/tests/integration/components/donation/credit-card-test.js +++ b/tests/integration/components/donation/credit-card-test.js @@ -57,7 +57,7 @@ test('it sends submit with credit card fields when button is clicked', function( page.clickSubmit(); }); -test('it renders button as disabled and "Processing" when busy', function(assert) { +test('it renders button as disabled and "Processing" when processing', function(assert) { assert.expect(2); stubService(this, 'stripe', { @@ -68,7 +68,7 @@ test('it renders button as disabled and "Processing" when busy', function(assert } }); - page.render(hbs`{{donation/credit-card isBusy=true submit=submitHandler}}`); + page.render(hbs`{{donation/credit-card isProcessing=true submit=submitHandler}}`); assert.ok(page.submitDisabled, 'Submit button is disabled'); assert.equal(page.submitButtonText, 'Processing...', 'Submit button changed text'); diff --git a/tests/integration/components/donation/donation-container-test.js b/tests/integration/components/donation/donation-container-test.js index b1935294b..209b17a3b 100644 --- a/tests/integration/components/donation/donation-container-test.js +++ b/tests/integration/components/donation/donation-container-test.js @@ -34,18 +34,65 @@ test('it renders new card form when there is no card to begin with', function(as assert.expect(2); this.set('amount', 100); + this.set('isProcessing', false); this.set('projectTitle', 'CodeCorps'); - this.set('card', null); + this.set('card', Object.create({ content: null, isFulfilled: true })); page.render(hbs` {{donation/donation-container - card=card donate=donateHandler donationAmount=amount projectTitle=projectTitle saveAndDonate=saveAndDonateHandler }} + card=card donate=donateHandler donationAmount=amount + isProcessing=isProcessing projectTitle=projectTitle saveAndDonate=saveAndDonateHandler }} `); assert.ok(page.cardFormIsVisible, 'The new card form is rendered automatically.'); assert.notOk(page.cards(0).isVisible, 'The card item is not visible.'); }); +test('it renders new card form when the card is added and is processing', function(assert) { + assert.expect(2); + + this.set('amount', 100); + this.set('isProcessing', false); + this.set('projectTitle', 'CodeCorps'); + this.set('card', Object.create({ content: null, isFulfilled: true })); + + page.render(hbs` + {{donation/donation-container + card=card + donate=donateHandler + isProcessing=isProcessing + saveAndDonate=saveAndDonateHandler + }} + `); + + this.set('card', visa); + this.set('isProcessing', true); + + assert.ok(page.cardFormIsVisible, 'The new card form is rendered.'); + assert.notOk(page.cards(0).isVisible, 'The card item is not visible.'); +}); + +test('it renders the card item if there is a card and the form is processing', function(assert) { + assert.expect(4); + + this.set('card', visa); + this.set('isProcessing', true); + + page.render(hbs` + {{donation/donation-container + card=card + donate=donateHandler + isProcessing=isProcessing + saveAndDonate=saveAndDonateHandler + }} + `); + + assert.notOk(page.cardFormIsVisible, 'The new card form is not rendered.'); + assert.ok(page.donationButtonIsVisible, 'Donation button is rendered.'); + assert.notOk(page.creditCard.submitButtonIsVisible, 'Card form button is not rendered.'); + assert.ok(page.cards(0).isVisible, 'The card item is visible.'); +}); + test('it renders the card item and the "donate" button when a card exists', function(assert) { assert.expect(3); @@ -103,10 +150,7 @@ test('it handles adding a card correctly', function(assert) { test('it handles donating correctly', function(assert) { assert.expect(1); - let amount = 100; - - this.set('amount', amount); - + this.set('amount', 100); this.set('card', visa); function donateHandler() { diff --git a/tests/pages/components/donation/credit-card.js b/tests/pages/components/donation/credit-card.js index 03a9fe463..4ce747f08 100644 --- a/tests/pages/components/donation/credit-card.js +++ b/tests/pages/components/donation/credit-card.js @@ -3,8 +3,6 @@ import { clickable, fillable, is, isVisible, selectable, text, value } from 'emb export default { scope: '.credit-card-form', - isCancelVisible: isVisible('.cancel-add-card a'), - cardCVC: { scope: '[name=card-cvc]', fillIn: fillable(), @@ -32,6 +30,7 @@ export default { clickSubmit: clickable('button.submit-card'), clickCancel: clickable('div.cancel-add-card a'), + submitButtonIsVisible: isVisible('button.submit-card'), submitButtonText: text('button.submit-card'), submitDisabled: is(':disabled', 'button') };