From 1b24f25def5bfa258c57dca472aa2e7116610379 Mon Sep 17 00:00:00 2001 From: Marine Boudeau Date: Sun, 18 Dec 2016 01:12:36 -0500 Subject: [PATCH] Update funds recipients form --- app/components/payments/account-setup.js | 30 +---- app/components/payments/bank-account.js | 2 +- app/components/payments/funds-recipient.js | 5 +- .../payments/funds-recipient/details-form.js | 54 +++++++++ .../project/settings/donations/payments.js | 90 +++++++++----- app/controllers/project/tasks/index.js | 11 +- app/models/stripe-connect-account.js | 35 +++--- app/styles/_forms.scss | 2 +- app/styles/app.scss | 1 + .../components/payments/account-setup.scss | 1 + .../funds-recipient/details-form.scss | 70 +++++++++++ .../components/payments/account-setup.hbs | 13 +- .../components/payments/bank-account.hbs | 4 +- .../components/payments/funds-recipient.hbs | 20 ++-- .../payments/funds-recipient/details-form.hbs | 94 +++++++++++++++ .../components/select/birth-date.hbs | 3 - .../project/settings/donations/payments.hbs | 3 +- mirage/scenarios/default.js | 7 +- package.json | 1 + .../components/payments/bank-account-test.js | 48 +++++--- .../payments/funds-recipient-test.js | 47 ++++---- .../funds-recipient/details-form-test.js | 113 ++++++++++++++++++ .../payments/funds-recipient/details-form.js | 30 +++++ .../models/stripe-connect-account-test.js | 31 ++++- 24 files changed, 554 insertions(+), 161 deletions(-) create mode 100644 app/components/payments/funds-recipient/details-form.js create mode 100644 app/styles/components/payments/funds-recipient/details-form.scss create mode 100644 app/templates/components/payments/funds-recipient/details-form.hbs create mode 100644 tests/integration/components/payments/funds-recipient/details-form-test.js create mode 100644 tests/pages/components/payments/funds-recipient/details-form.js diff --git a/app/components/payments/account-setup.js b/app/components/payments/account-setup.js index 93e390459..33a5ad350 100644 --- a/app/components/payments/account-setup.js +++ b/app/components/payments/account-setup.js @@ -5,33 +5,5 @@ const { } = Ember; export default Component.extend({ - classNames: ['account-setup'], - - // set by binding - email: null, - - // Preset values for testing - fundsRecipient: { - recipientType: 'company', - firstName: 'John', - lastName: 'Doe', - - businessType: 'sole_prop', - businessName: 'Managed LLC', - businessEin: '1234-managed', - - dob: '06-12-1986', - - dobDay: '06', - dobMonth: '12', - dobYear: '1986', - - address1: 'Some street 22', - address2: 'PO 23', - city: 'Los Angeles', - state: 'CA', - country: 'US', - zip: '10000', - ssnLast4: '1234' - } + classNames: ['account-setup'] }); diff --git a/app/components/payments/bank-account.js b/app/components/payments/bank-account.js index 3c19424f1..76d93a3cc 100644 --- a/app/components/payments/bank-account.js +++ b/app/components/payments/bank-account.js @@ -13,7 +13,7 @@ export default Component.extend({ accountNumber: '000123456789', routingNumber: '110000000', - status: computed.alias('account.bankAccountStatus'), + status: computed.alias('stripeConnectAccount.bankAccountStatus'), statusClass: computed('status', function() { return `account-setup__section--${get(this, 'status')}`; diff --git a/app/components/payments/funds-recipient.js b/app/components/payments/funds-recipient.js index d6eb79f7d..22ad8aa66 100644 --- a/app/components/payments/funds-recipient.js +++ b/app/components/payments/funds-recipient.js @@ -3,14 +3,15 @@ import Ember from 'ember'; const { Component, computed, + computed: { alias }, get } = Ember; export default Component.extend({ classNameBindings: ['statusClass'], - classNames: ['funds-recipient'], + classNames: ['funds-recipient', 'account-setup__section'], - status: computed.alias('account.recipientStatus'), + status: alias('stripeConnectAccount.recipientStatus'), statusClass: computed('status', function() { return `account-setup__section--${get(this, 'status')}`; diff --git a/app/components/payments/funds-recipient/details-form.js b/app/components/payments/funds-recipient/details-form.js new file mode 100644 index 000000000..a2e135e09 --- /dev/null +++ b/app/components/payments/funds-recipient/details-form.js @@ -0,0 +1,54 @@ +import Ember from 'ember'; + +const { + assign, + Component, + computed: { equal }, + get, + getProperties, + set +} = Ember; + +const BUSINESS_PROPERTIES = ['businessName', 'businessEin']; + +const INDIVIDUAL_PROPERTIES = [ + 'recipientType', + 'firstName', 'lastName', + 'dobDay', 'dobMonth', 'dobYear', + 'address1', 'address2', 'city', 'state', 'zip', 'country', + 'ssnLast4' +]; + +export default Component.extend({ + classNames: ['details-form'], + + isBusiness: equal('recipientType', 'business'), + isIndividual: equal('recipientType', 'individual'), + + init() { + let recipientType = get(this, 'account.recipientType') || 'individual'; + set(this, 'recipientType', recipientType); + this._super(...arguments); + }, + + actions: { + submit() { + let details = this._collectIndividualProperties(); + + if (get(this, 'isBusiness')) { + assign(details, this._collectBusinessProperties()); + } + + let onSubmit = get(this, 'onSubmit'); + onSubmit(details); + } + }, + + _collectBusinessProperties() { + return getProperties(this, ...BUSINESS_PROPERTIES); + }, + + _collectIndividualProperties() { + return getProperties(this, ...INDIVIDUAL_PROPERTIES); + } +}); diff --git a/app/controllers/project/settings/donations/payments.js b/app/controllers/project/settings/donations/payments.js index ee8fc1fae..e076d13e2 100644 --- a/app/controllers/project/settings/donations/payments.js +++ b/app/controllers/project/settings/donations/payments.js @@ -2,7 +2,6 @@ import Ember from 'ember'; import FriendlyError from 'code-corps-ember/utils/friendly-error'; const { - computed: { alias }, Controller, get, inject: { service }, @@ -11,24 +10,16 @@ const { set } = Ember; -const ACCOUNT_TOKEN_CREATION_ERROR = 'There was a problem in using your bank account information. Please check your input and try again.'; -const ACCOUNT_ADDING_ERROR = 'There was a problem in attaching the provided bank account information to your Stripe account.'; +const ACCOUNT_ADDING_ERROR = 'There was a problem submitting your bank account information.'; +const ACCOUNT_TOKEN_CREATION_ERROR = 'There was a problem with your bank account information. Please check your input and try again.'; +const STRIPE_ACCOUNT_CREATION_ERROR = 'There was a problem with your account information. Please check your input and try again.'; export default Controller.extend({ currentUser: service(), store: service(), stripe: service(), - user: alias('currentUser.user'), - stripeConnectAccount: alias('project.organization.stripeConnectAccount'), - actions: { - onRecipientInformationSubmitted(organization, email, recipientInformation) { - let accountParams = merge(recipientInformation, { organization, email }); - get(this, 'store').createRecord('stripe-connect-account', accountParams) - .save(); - }, - onBankAccountInformationSubmitted({ accountNumber, routingNumber }) { set(this, 'isBusy', true); @@ -41,23 +32,31 @@ export default Controller.extend({ .then(({ tokenData, stripeConnectAccount }) => this._addBankAccount(tokenData, stripeConnectAccount)) .catch((response) => this._handleError(response)) .finally(() => set(this, 'isBusy', false)); - } - }, + }, - // adding bank account information + onPersonalIdNumberSubmitted() { + // TODO: FIX THIS + return; + }, - _createAccountToken(accountNumber, routingNumber) { - let stripe = get(this, 'stripe'); - let params = this._bankAccountTokenParams(accountNumber, routingNumber); + onRecipientDetailsSubmitted(recipientInformation) { + set(this, 'isBusy', true); - return stripe.bankAccount.createToken(params) - .then((stripeResponse) => RSVP.resolve(stripeResponse)) - .catch((reason) => this._handleBankAccountTokenError(reason)); - }, + let promises = { + organization: get(this, 'project.organization'), + email: get(this, 'currentUser.user.email') + }; - _handleBankAccountTokenError() { - let friendlyError = new FriendlyError(ACCOUNT_TOKEN_CREATION_ERROR); - return RSVP.reject(friendlyError); + RSVP.hash(promises) + .then(({ organization, email }) => this._createStripeAccount(recipientInformation, organization, email)) + .catch((reason) => this._handleError(reason)) + .finally(() => set(this, 'isBusy', false)); + }, + + onVerificationDocumentSubmitted() { + // TODO: FIX THIS + return; + } }, _addBankAccount(tokenData, stripeConnectAccount) { @@ -68,11 +67,6 @@ export default Controller.extend({ .catch((reason) => this._handleAddBankAccountError(reason)); }, - _handleAddBankAccountError() { - let friendlyError = new FriendlyError(ACCOUNT_ADDING_ERROR); - return RSVP.reject(friendlyError); - }, - _bankAccountTokenParams(accountNumber, routingNumber) { return { account_number: accountNumber, @@ -83,9 +77,41 @@ export default Controller.extend({ }; }, - // setting error property + _createAccountToken(accountNumber, routingNumber) { + let stripe = get(this, 'stripe'); + let params = this._bankAccountTokenParams(accountNumber, routingNumber); + + return stripe.bankAccount.createToken(params) + .then((stripeResponse) => RSVP.resolve(stripeResponse)) + .catch((reason) => this._handleBankAccountTokenError(reason)); + }, + + _createStripeAccount(recipientInformation, organization, email) { + let accountParams = merge(recipientInformation, { organization, email }); + + return get(this, 'store') + .createRecord('stripe-connect-account', accountParams) + .save() + .then((account) => RSVP.resolve(account)) + .catch((reason) => this._handleStripeAccountCreationError(reason)); + }, + + _handleAddBankAccountError() { + let friendlyError = new FriendlyError(ACCOUNT_ADDING_ERROR); + return RSVP.reject(friendlyError); + }, + + _handleBankAccountTokenError() { + let friendlyError = new FriendlyError(ACCOUNT_TOKEN_CREATION_ERROR); + return RSVP.reject(friendlyError); + }, _handleError(error) { - this.set('error', error); + set(this, 'error', error); + }, + + _handleStripeAccountCreationError() { + let friendlyError = new FriendlyError(STRIPE_ACCOUNT_CREATION_ERROR); + return RSVP.reject(friendlyError); } }); diff --git a/app/controllers/project/tasks/index.js b/app/controllers/project/tasks/index.js index 247a9ca74..9c3289149 100644 --- a/app/controllers/project/tasks/index.js +++ b/app/controllers/project/tasks/index.js @@ -16,11 +16,10 @@ export default Controller.extend({ }, actions: { - onDrop(el, target) { - let listId = target.dataset.modelId; - let position = $(el).index(); - let taskId = el.dataset.modelId; - console.log(taskId, position, listId); - } + // onDrop(el, target) { + // let listId = target.dataset.modelId; + // let position = $(el).index(); + // let taskId = el.dataset.modelId; + // } } }); diff --git a/app/models/stripe-connect-account.js b/app/models/stripe-connect-account.js index 3b1951cd0..b25c9ec5f 100644 --- a/app/models/stripe-connect-account.js +++ b/app/models/stripe-connect-account.js @@ -3,38 +3,31 @@ import attr from 'ember-data/attr'; import { belongsTo } from 'ember-data/relationships'; export default Model.extend({ - email: attr(), - - recipientType: attr(), - - firstName: attr(), - lastName: attr(), - - dobDay: attr(), - dobMonth: attr(), - dobYear: attr(), - address1: attr(), address2: attr(), - city: attr(), - country: attr(), - state: attr(), - zip: attr(), - - ssnLast4: attr(), - businessEin: attr(), businessName: attr(), businessType: attr(), - canAcceptDonations: attr(), chargesEnabled: attr(), - + city: attr(), + country: attr(), displayName: attr(), + dobDay: attr(), + dobMonth: attr(), + dobYear: attr(), + email: attr(), + firstName: attr(), idFromStripe: attr(), - insertedAt: attr(), + lastName: attr(), + recipientStatus: attr(), + recipientType: attr(), + ssnLast4: attr(), + state: attr(), updatedAt: attr(), + verificationFieldsNeeded: attr(), + zip: attr(), organization: belongsTo('organization', { async: true }) }); diff --git a/app/styles/_forms.scss b/app/styles/_forms.scss index 2c1222aea..5b4bfd16e 100644 --- a/app/styles/_forms.scss +++ b/app/styles/_forms.scss @@ -11,7 +11,7 @@ $outer-border-radius: 4px; width: 100%; #{$all-text-inputs} { - border-radius: $inner-border-radius; + border-radius: $outer-border-radius; float: left; max-width: 100%; width: 100%; diff --git a/app/styles/app.scss b/app/styles/app.scss index 1a377fdab..c97590665 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -51,6 +51,7 @@ @import "components/organization-header"; @import "components/organization-members"; @import "components/payments/account-setup"; +@import "components/payments/funds-recipient/details-form"; @import "components/payments/bank-account"; @import "components/pager-control"; @import "components/task-card"; diff --git a/app/styles/components/payments/account-setup.scss b/app/styles/components/payments/account-setup.scss index 1ce0db356..7e6155747 100644 --- a/app/styles/components/payments/account-setup.scss +++ b/app/styles/components/payments/account-setup.scss @@ -9,6 +9,7 @@ display: flex; min-height: 4em; padding: 1.5em; + margin-bottom: 15px; aside { @include span-columns(3); diff --git a/app/styles/components/payments/funds-recipient/details-form.scss b/app/styles/components/payments/funds-recipient/details-form.scss new file mode 100644 index 000000000..fafe5898a --- /dev/null +++ b/app/styles/components/payments/funds-recipient/details-form.scss @@ -0,0 +1,70 @@ +.details-form { + &__recipient-type { + input { + margin-right: 1em; + } + + label { + background-color: #FCFCFC; + border: 1px solid #DDD; + border-radius: 4px; + cursor: pointer; + min-height: 2em; + padding: 1em; + + &.checked { + background: $light-blue-background; + border-color: $dark-blue; + } + } + } + + p:first-child { + margin-top: 0; + } + + input[type="text"] { + background: white; + } + + input[type="submit"] { + margin-left: 140px; + } + + .input-section { + display: flex; + flex-direction: row; + margin: 20px 0; + + &__label { + width: 140px; + } + + &__content { + flex-grow: 1; + } + + .select-country select { + width: 100%; + } + } + + .input-line { + display: flex; + flex-direction: row; + justify-content: space-between; + + .input--state { + width: 48%; + + .select-state select { + width: 100%; + } + } + + .input--state, + .input--zipcode { + width: 48%; + } + } +} diff --git a/app/templates/components/payments/account-setup.hbs b/app/templates/components/payments/account-setup.hbs index 58c5126bc..fe7b74b51 100644 --- a/app/templates/components/payments/account-setup.hbs +++ b/app/templates/components/payments/account-setup.hbs @@ -1,12 +1,15 @@

Create a Stripe account for {{organizationName}}

-{{payments/contact-info email=email}} - {{payments/funds-recipient - account=account isBusy=isBusy onRecipientDetailsSubmitted=(action onRecipientDetailsSubmitted) onVerificationDocumentSubmitted=(action onVerificationDocumentSubmitted) - onPersonalIdNumberSubmitted=(action onPersonalIdNumberSubmitted)}} + onPersonalIdNumberSubmitted=(action onPersonalIdNumberSubmitted) + stripeConnectAccount=stripeConnectAccount +}} -{{payments/bank-account account=account isBusy=isBusy submit=(action onBankAccountInformationSubmitted)}} +{{payments/bank-account + isBusy=isBusy + stripeConnectAccount=stripeConnectAccount + submit=(action onBankAccountInformationSubmitted) +}} diff --git a/app/templates/components/payments/bank-account.hbs b/app/templates/components/payments/bank-account.hbs index 9816599e6..2bbebc2f9 100644 --- a/app/templates/components/payments/bank-account.hbs +++ b/app/templates/components/payments/bank-account.hbs @@ -20,11 +20,11 @@
{{/if}} diff --git a/app/templates/components/payments/funds-recipient.hbs b/app/templates/components/payments/funds-recipient.hbs index 1e7f2d00e..85eab9d73 100644 --- a/app/templates/components/payments/funds-recipient.hbs +++ b/app/templates/components/payments/funds-recipient.hbs @@ -1,14 +1,12 @@ -{{#if (eq status 'required')}} -
- TODO: details-form-component goes here -
+{{#if (or (eq status 'required') (eq status 'errored'))}} + {{payments/funds-recipient/details-form + onSubmit=(action onRecipientDetailsSubmitted) + stripeConnectAccount=stripeConnectAccount + }} {{/if}} {{#if (eq status 'verifying')}} @@ -24,14 +22,14 @@
-

{{account.individualName}}

+

{{stripeConnectAccount.individualName}}

- {{#if (eq account.recipientType 'business')}} + {{#if (eq stripeConnectAccount.recipientType 'business')}}
-

{{account.businessName}}

+

{{stripeConnectAccount.businessName}}

{{/if}}
-{{/if}} \ No newline at end of file +{{/if}} diff --git a/app/templates/components/payments/funds-recipient/details-form.hbs b/app/templates/components/payments/funds-recipient/details-form.hbs new file mode 100644 index 000000000..9cb345b62 --- /dev/null +++ b/app/templates/components/payments/funds-recipient/details-form.hbs @@ -0,0 +1,94 @@ +
+

Tell us whether a person or an organization will be running this project. Once your turn on donations, you cannot change your information.

+ {{#radio-button class="details-form__recipient-type" value="individual" groupValue=recipientType}} + Individual + {{/radio-button}} + {{#radio-button class="details-form__recipient-type" value="business" groupValue=recipientType}} + Legal entity (company or organization) + {{/radio-button}} +
+ +{{#if (eq recipientType 'business')}} +
+ +
+
+ + {{input type="text" name="business-name" value=businessName}} +
+
+ + {{input type="text" name="business-ein" value=businessEin}} +
+
+
+{{/if}} + + +

Please verify your identity with your legal first and last name. If you're running your project as an organization, only a legal representative of the organization should complete this verification.

+ +
+ +
+
+ + {{input type="text" name="first-name" value=firstName}} +
+
+ + {{input type="text" name="last-name" value=lastName}} +
+
+
+ +
+ +
+
+ {{select/birth-date day=dobDay month=dobMonth year=dobYear}} +
+
+
+ +
+ +
+
+ + {{input type="text" name="address-1" value=address1}} +
+
+ + {{input type="text" name="address-2" value=address2}} +
+
+ + {{input type="text" name="city" value=city}} +
+
+
+ + {{select/state-select state=state}} +
+
+ + {{input type="text" name="zip" value=zip}} +
+
+
+ + {{select/country-select country=country}} +
+
+
+ +
+ +
+
+ {{input type="text" name="ssn-last4" value=ssnLast4}} +
+
+
+ + diff --git a/app/templates/components/select/birth-date.hbs b/app/templates/components/select/birth-date.hbs index 0d7ec12f7..33d8b6fd3 100644 --- a/app/templates/components/select/birth-date.hbs +++ b/app/templates/components/select/birth-date.hbs @@ -1,6 +1,3 @@ -
{{#x-select value=month as |xs|}} {{#each monthOptions as |monthOption|}} diff --git a/app/templates/project/settings/donations/payments.hbs b/app/templates/project/settings/donations/payments.hbs index 68e6c7ee8..fc4b0d186 100644 --- a/app/templates/project/settings/donations/payments.hbs +++ b/app/templates/project/settings/donations/payments.hbs @@ -1,5 +1,4 @@ {{payments/account-setup - account=stripeConnectAccount email=user.email isBusy=isBusy onBankAccountInformationSubmitted=(action 'onBankAccountInformationSubmitted') @@ -7,7 +6,9 @@ onRecipientDetailsSubmitted=(action 'onRecipientDetailsSubmitted') onVerificationDocumentSubmitted=(action 'onVerificationDocumentSubmitted') organizationName=project.organization.name + stripeConnectAccount=project.organization.stripeConnectAccount }} + {{#if error}} {{error-formatter error=error}} {{/if}} diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js index 5fbc5927d..ea73e3f4e 100644 --- a/mirage/scenarios/default.js +++ b/mirage/scenarios/default.js @@ -289,7 +289,12 @@ export default function(server) { server.create('project-category', { category, project }); }); - organization.createStripeConnectAccount(); + let stripeConnectAccount = server.create('stripe-connect-account', { + organization, + recipientStatus: 'required' + }); + organization.stripeConnectAccount = stripeConnectAccount; + organization.save(); project.createStripeConnectPlan(); diff --git a/package.json b/package.json index 6e6d384c8..a06c5dc0c 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "ember-modal-dialog": "0.8.8", "ember-moment": "7.1.0", "ember-page-title": "^3.0.10", + "ember-radio-button": "^1.0.7", "ember-resolver": "^2.0.3", "ember-route-action-helper": "^2.0.0", "ember-simple-auth": "1.1.0", diff --git a/tests/integration/components/payments/bank-account-test.js b/tests/integration/components/payments/bank-account-test.js index 5e868b30a..102282954 100644 --- a/tests/integration/components/payments/bank-account-test.js +++ b/tests/integration/components/payments/bank-account-test.js @@ -5,7 +5,7 @@ import PageObject from 'ember-cli-page-object'; import bankAccountComponent from '../../../pages/components/payments/bank-account'; -const { K } = Ember; +const { K, set } = Ember; let page = PageObject.create(bankAccountComponent); @@ -13,6 +13,16 @@ function setHandler(context, submitHandler = K) { context.set('submitHandler', submitHandler); } +function renderPage() { + page.render(hbs` + {{payments/bank-account + isBusy=isBusy + stripeConnectAccount=stripeConnectAccount + submit=submitHandler + }} + `); +} + moduleForComponent('payments/bank-account', 'Integration | Component | payments/bank account', { integration: true, beforeEach() { @@ -27,20 +37,22 @@ moduleForComponent('payments/bank-account', 'Integration | Component | payments/ test('it renders correctly for "pending" status', function(assert) { assert.expect(1); - let account = { bankAccountStatus: 'pending_requirement' }; - this.set('account', account); + let stripeConnectAccount = { bankAccountStatus: 'pending_requirement' }; + set(this, 'stripeConnectAccount', stripeConnectAccount); + + renderPage(); - page.render(hbs`{{payments/bank-account account=account submit=submitHandler}}`); assert.ok(page.rendersPending, 'Component is rendered in pending status.'); }); test('it renders correctly for "required" status', function(assert) { assert.expect(4); - let account = { bankAccountStatus: 'required' }; - this.set('account', account); + let stripeConnectAccount = { bankAccountStatus: 'required' }; + set(this, 'stripeConnectAccount', stripeConnectAccount); + + renderPage(); - page.render(hbs`{{payments/bank-account account=account submit=submitHandler}}`); assert.ok(page.rendersRequired, 'Component is rendered in required mode.'); assert.ok(page.rendersAccountNumberField, 'Component renders the account number field.'); assert.ok(page.rendersRoutingNumberField, 'Component renders the routing number field.'); @@ -50,10 +62,11 @@ test('it renders correctly for "required" status', function(assert) { test('it renders correctly for "verified" status', function(assert) { assert.expect(3); - let account = { bankAccountLast4: 4321, bankAccountRoutingNumber: 123456, bankAccountStatus: 'verified' }; - this.set('account', account); + let stripeConnectAccount = { bankAccountLast4: 4321, bankAccountRoutingNumber: 123456, bankAccountStatus: 'verified' }; + set(this, 'stripeConnectAccount', stripeConnectAccount); + + renderPage(); - page.render(hbs`{{payments/bank-account account=account submit=submitHandler}}`); assert.ok(page.rendersVerified, 'Component is rendered in verified mode.'); assert.equal(page.accountLast4Text, 4321, 'Component renders last 4 digits of account number.'); assert.equal(page.routingNumberText, 123456, 'Component renders routing number.'); @@ -62,8 +75,8 @@ test('it renders correctly for "verified" status', function(assert) { test('it sends properties with submit action', function(assert) { assert.expect(1); - let account = { bankAccountStatus: 'required' }; - this.set('account', account); + let stripeConnectAccount = { bankAccountStatus: 'required' }; + set(this, 'stripeConnectAccount', stripeConnectAccount); let input = { routingNumber: '123456', @@ -74,8 +87,8 @@ test('it sends properties with submit action', function(assert) { assert.deepEqual(output, input, 'Correct parameters were sent out with action.'); }); - page.render(hbs`{{payments/bank-account account=account submit=submitHandler}}`) - .accountNumber(input.accountNumber) + renderPage(); + page.accountNumber(input.accountNumber) .routingNumber(input.routingNumber) .clickSubmit(); }); @@ -83,10 +96,11 @@ test('it sends properties with submit action', function(assert) { test('it disables controls when busy', function(assert) { assert.expect(3); - let account = { bankAccountStatus: 'required' }; - this.set('account', account); + let stripeConnectAccount = { bankAccountStatus: 'required' }; + set(this, 'isBusy', true); + set(this, 'stripeConnectAccount', stripeConnectAccount); - page.render(hbs`{{payments/bank-account account=account isBusy=true submit=submitHandler}}`); + renderPage(); assert.ok(page.accountNumberFieldIsDisabled, 'Account number field is disabled when busy.'); assert.ok(page.routingNumberFieldIsDisabled, 'Routing number field is disabled when buys.'); diff --git a/tests/integration/components/payments/funds-recipient-test.js b/tests/integration/components/payments/funds-recipient-test.js index 32b1adcb2..b58484585 100644 --- a/tests/integration/components/payments/funds-recipient-test.js +++ b/tests/integration/components/payments/funds-recipient-test.js @@ -17,13 +17,14 @@ function setHandlers(context, { detailsHandler = K, documentHandler = K, idHandl } function renderPage() { - page.render( - hbs`{{payments/funds-recipient - account=account - onRecipientDetailsSubmitted=detailsHandler - onVerificationDocumentSubmitted=documentHandler - onPersonalIdNumberSubmitted=idHandler}}` - ); + page.render(hbs` + {{payments/funds-recipient + stripeConnectAccount=stripeConnectAccount + onRecipientDetailsSubmitted=detailsHandler + onVerificationDocumentSubmitted=documentHandler + onPersonalIdNumberSubmitted=idHandler + }} + `); } moduleForComponent('payments/funds-recipient', 'Integration | Component | payments/funds recipient', { @@ -40,8 +41,8 @@ moduleForComponent('payments/funds-recipient', 'Integration | Component | paymen test('it renders correctly when "pending"', function(assert) { assert.expect(1); - let account = { recipientStatus: 'pending_requirement' }; - this.set('account', account); + let stripeConnectAccount = { recipientStatus: 'pending_requirement' }; + this.set('stripeConnectAccount', stripeConnectAccount); renderPage(); @@ -51,8 +52,8 @@ test('it renders correctly when "pending"', function(assert) { test('it renders correctly when "required"', function(assert) { assert.expect(2); - let account = { recipientStatus: 'required' }; - this.set('account', account); + let stripeConnectAccount = { recipientStatus: 'required' }; + this.set('stripeConnectAccount', stripeConnectAccount); renderPage(); @@ -63,8 +64,8 @@ test('it renders correctly when "required"', function(assert) { test('it renders correctly when "verifying"', function(assert) { assert.expect(3); - let account = { recipientStatus: 'verifying' }; - this.set('account', account); + let stripeConnectAccount = { recipientStatus: 'verifying' }; + this.set('stripeConnectAccount', stripeConnectAccount); renderPage(); @@ -76,11 +77,11 @@ test('it renders correctly when "verifying"', function(assert) { test('it renders correctly when "verified"', function(assert) { assert.expect(2); - let account = { + let stripeConnectAccount = { recipientStatus: 'verified', individualName: 'Joe Individual' }; - this.set('account', account); + this.set('stripeConnectAccount', stripeConnectAccount); renderPage(); @@ -91,13 +92,13 @@ test('it renders correctly when "verified"', function(assert) { test('it renders correctly when "verified" for business', function(assert) { assert.expect(3); - let account = { + let stripeConnectAccount = { recipientStatus: 'verified', individualName: 'Joe Individual', businessName: 'Company Inc.', recipientType: 'business' }; - this.set('account', account); + this.set('stripeConnectAccount', stripeConnectAccount); renderPage(); @@ -110,8 +111,8 @@ test('it renders correctly when "verified" for business', function(assert) { // test('it passes out submit action from details subcomponent', function(assert) { // assert.expect(1); -// let account = { recipientStatus: 'required' }; -// this.set('account', account); +// let stripeConnectAccount = { recipientStatus: 'required' }; +// this.set('stripeConnectAccount', stripeConnectAccount); // renderPage(); // }); @@ -119,8 +120,8 @@ test('it renders correctly when "verified" for business', function(assert) { // test('it passes out submit action from document upload subcomponent', function(assert) { // assert.expect(1); -// let account = { recipientStatus: 'verifying' }; -// this.set('account', account); +// let stripeConnectAccount = { recipientStatus: 'verifying' }; +// this.set('stripeConnectAccount', stripeConnectAccount); // renderPage(); // }); @@ -128,8 +129,8 @@ test('it renders correctly when "verified" for business', function(assert) { // test('it passes out submit action from personal id number subcomponent', function(assert) { // assert.expect(1); -// let account = { recipientStatus: 'verifying' }; -// this.set('account', account); +// let stripeConnectAccount = { recipientStatus: 'verifying' }; +// this.set('stripeConnectAccount', stripeConnectAccount); // renderPage(); // }); diff --git a/tests/integration/components/payments/funds-recipient/details-form-test.js b/tests/integration/components/payments/funds-recipient/details-form-test.js new file mode 100644 index 000000000..c68957f49 --- /dev/null +++ b/tests/integration/components/payments/funds-recipient/details-form-test.js @@ -0,0 +1,113 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; +import PageObject from 'ember-cli-page-object'; + +import detailsFormComponent from 'code-corps-ember/tests/pages/components/payments/funds-recipient/details-form'; + +let page = PageObject.create(detailsFormComponent); + +function renderPage() { + page.render( + hbs`{{payments/funds-recipient/details-form account=account onSubmit=onSubmit}}` + ); +} + +moduleForComponent('payments/funds-recipient/details-form', 'Integration | Component | payments/funds recipient/details form', { + integration: true, + beforeEach() { + page.setContext(this); + }, + afterEach() { + page.removeContext(); + } +}); + +test('it sends out correct properties when submitting in business mode', function(assert) { + assert.expect(1); + + let expectedProperties = { + businessName: 'Test Business', + businessEin: '1234', + recipientType: 'business', + firstName: 'Joe', + lastName: 'Regular', + dobDay: 6, + dobMonth: 12, + dobYear: 1986, + address1: 'Some street 42', + address2: 'PO 21', + city: 'Town', + state: 'AL', + zip: '11111', + country: 'US', + ssnLast4: '5555' + }; + + this.set('onSubmit', (properties) => { + assert.deepEqual(properties, expectedProperties, 'Correct properties were submitted'); + }); + + renderPage(); + + page.selectBusiness() + .businessName(expectedProperties.businessName) + .businessEin(expectedProperties.businessEin) + .firstName(expectedProperties.firstName) + .lastName(expectedProperties.lastName) + .address1(expectedProperties.address1) + .address2(expectedProperties.address2) + .city(expectedProperties.city) + .zip(expectedProperties.zip) + .ssnLast4(expectedProperties.ssnLast4); + + page.state.fillIn(expectedProperties.state); + page.country.fillIn(expectedProperties.country); + page.birthDate.day.fillIn(expectedProperties.dobDay); + page.birthDate.month.fillIn(expectedProperties.dobMonth); + page.birthDate.year.fillIn(expectedProperties.dobYear); + + page.clickSubmit(); +}); + +test('it sends out correct properties when submitting in individual mode', function(assert) { + assert.expect(1); + + let expectedProperties = { + recipientType: 'individual', + firstName: 'Joe', + lastName: 'Regular', + dobDay: 6, + dobMonth: 12, + dobYear: 1986, + address1: 'Some street 42', + address2: 'PO 21', + city: 'Town', + state: 'AL', + zip: '11111', + country: 'US', + ssnLast4: '5555' + }; + + this.set('onSubmit', (properties) => { + assert.deepEqual(properties, expectedProperties, 'Correct properties were submitted'); + }); + + renderPage(); + + page.selectIndividual() + .firstName(expectedProperties.firstName) + .lastName(expectedProperties.lastName) + .address1(expectedProperties.address1) + .address2(expectedProperties.address2) + .city(expectedProperties.city) + .zip(expectedProperties.zip) + .ssnLast4(expectedProperties.ssnLast4); + + page.state.fillIn(expectedProperties.state); + page.country.fillIn(expectedProperties.country); + page.birthDate.day.fillIn(expectedProperties.dobDay); + page.birthDate.month.fillIn(expectedProperties.dobMonth); + page.birthDate.year.fillIn(expectedProperties.dobYear); + + page.clickSubmit(); +}); diff --git a/tests/pages/components/payments/funds-recipient/details-form.js b/tests/pages/components/payments/funds-recipient/details-form.js new file mode 100644 index 000000000..8fde6f795 --- /dev/null +++ b/tests/pages/components/payments/funds-recipient/details-form.js @@ -0,0 +1,30 @@ +import { fillable, clickable } from 'ember-cli-page-object'; +import birthDate from 'code-corps-ember/tests/pages/components/select/birth-date'; +import country from 'code-corps-ember/tests/pages/components/select/country-select'; +import state from 'code-corps-ember/tests/pages/components/select/state-select'; + +export default { + scope: '.details-form', + + selectIndividual: clickable('input[value="individual"]'), + selectBusiness: clickable('input[value="business"]'), + + businessName: fillable('input[name=business-name]'), + businessEin: fillable('input[name=business-ein]'), + + firstName: fillable('input[name=first-name]'), + lastName: fillable('input[name=last-name]'), + + birthDate, + + address1: fillable('input[name=address-1]'), + address2: fillable('input[name=address-2]'), + city: fillable('input[name=city]'), + state, + zip: fillable('input[name=zip]'), + country, + + ssnLast4: fillable('input[name=ssn-last4]'), + + clickSubmit: clickable('input[type=submit]') +}; diff --git a/tests/unit/models/stripe-connect-account-test.js b/tests/unit/models/stripe-connect-account-test.js index a183948b7..33afc722a 100644 --- a/tests/unit/models/stripe-connect-account-test.js +++ b/tests/unit/models/stripe-connect-account-test.js @@ -12,11 +12,30 @@ test('it exists', function(assert) { }); testForAttributes('stripe-connect-account', [ - 'email', 'recipientType', 'firstName', 'lastName', 'dobDay', 'dobMonth', 'dobYear', - 'address1', 'address2', 'city', 'country', 'state', 'zip', 'ssnLast4', - 'businessEin', 'businessName', 'businessType', - 'canAcceptDonations', 'chargesEnabled', - 'displayName', 'idFromStripe', - 'insertedAt', 'updatedAt' + 'address1', + 'address2', + 'businessEin', + 'businessName', + 'businessType', + 'canAcceptDonations', + 'chargesEnabled', + 'city', + 'country', + 'displayName', + 'dobDay', + 'dobMonth', + 'dobYear', + 'email', + 'firstName', + 'idFromStripe', + 'insertedAt', + 'lastName', + 'recipientStatus', + 'recipientType', + 'ssnLast4', + 'state', + 'updatedAt', + 'verificationFieldsNeeded', + 'zip' ]); testForBelongsTo('stripe-connect-account', 'organization');