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')
};