diff --git a/app/components/payments/funds-recipient/personal-id-number.js b/app/components/payments/funds-recipient/personal-id-number.js
new file mode 100644
index 000000000..34428636f
--- /dev/null
+++ b/app/components/payments/funds-recipient/personal-id-number.js
@@ -0,0 +1,11 @@
+import Ember from 'ember';
+
+const {
+ Component,
+ computed: { alias }
+} = Ember;
+
+export default Component.extend({
+ classNames: ['personal-id-number'],
+ status: alias('stripeConnectAccount.personalIdNumberStatus')
+});
diff --git a/app/components/payments/funds-recipient/verification-document.js b/app/components/payments/funds-recipient/verification-document.js
index b8b0d19e8..8cb27480b 100644
--- a/app/components/payments/funds-recipient/verification-document.js
+++ b/app/components/payments/funds-recipient/verification-document.js
@@ -5,6 +5,7 @@ const {
computed,
get,
set
+
} = Ember;
const VALIDATION_ERROR = 'The file you selected is invalid. Only .jpg and .png images of up to 8mb in size are supported.';
diff --git a/app/controllers/project/settings/donations/payments.js b/app/controllers/project/settings/donations/payments.js
index 7afb5e1e9..2f62863c5 100644
--- a/app/controllers/project/settings/donations/payments.js
+++ b/app/controllers/project/settings/donations/payments.js
@@ -10,11 +10,11 @@ const {
setProperties
} = Ember;
-const ACCOUNT_ADDING_ERROR = 'There was a problem submitting your bank account information.';
-const ACCOUNT_TOKEN_CREATION_ERROR = 'There was a problem in using your bank account information. Please check your input and try again.';
-const STRIPE_ACCOUNT_CREATION_ERROR = 'There was a problem with creating your account. Please check your input and try again.';
-const STRIPE_RECIPIENT_DETAILS_UPDATE_ERROR = 'There was a problem with your account information. Please check your input and try again.';
-const VERIFICATION_DOCUMENT_ERROR = 'There was a problem in attaching the verification document to your stripe account';
+const ACCOUNT_CREATION_ERROR = 'There was a problem with creating your account. Please check your input and try again.';
+const ACCOUNT_UPDATE_ERROR = 'There was a problem with your account information. Please check your input and try again.';
+const BANK_ACCOUNT_TOKEN_CREATION_ERROR = 'There was a problem in using your bank account information. Please check your input and try again.';
+const BANK_ACCOUNT_ADDING_ERROR = 'There was a problem submitting your bank account information.';
+const VERIFICATION_DOCUMENT_ERROR = 'There was a problem with attaching your document. Please try again.';
export default Controller.extend({
currentUser: service(),
@@ -63,8 +63,13 @@ export default Controller.extend({
.finally(() => set(this, 'isBusy', false));
},
- onPersonalIdNumberSubmitted() {
- console.log(arguments);
+ onPersonalIdNumberSubmitted(personalIdNumber) {
+ set(this, 'isBusy', true);
+
+ get(this, 'stripeConnectAccount')
+ .then((account) => this._assignPersonalIdNumber(account, personalIdNumber))
+ .catch((response) => this._handleError(response))
+ .finally(() => set(this, 'isBusy', false));
}
},
@@ -72,15 +77,10 @@ export default Controller.extend({
_createStripeAccount(organization, country) {
return get(this, 'store')
- .createRecord('stripe-connect-account', { organization, country })
- .save()
- .then((account) => RSVP.resolve(account))
- .catch((reason) => this._handleAccountCreationError(reason));
- },
-
- _handleAccountCreationError() {
- let friendlyError = new FriendlyError(STRIPE_ACCOUNT_CREATION_ERROR);
- return RSVP.reject(friendlyError);
+ .createRecord('stripe-connect-account', { organization, country })
+ .save()
+ .then(RSVP.resolve)
+ .catch(() => this._wrapError(ACCOUNT_CREATION_ERROR));
},
// udating recipient info
@@ -89,29 +89,31 @@ export default Controller.extend({
setProperties(stripeConnectAccount, recipientDetails);
return stripeConnectAccount
- .save()
- .then((account) => RSVP.resolve(account))
- .catch((reason) => this._handleRecipientDetailsUpdateError(reason));
- },
-
- _handleRecipientDetailsUpdateError() {
- let friendlyError = new FriendlyError(STRIPE_RECIPIENT_DETAILS_UPDATE_ERROR);
- return RSVP.reject(friendlyError);
+ .save()
+ .then(RSVP.resolve)
+ .catch(() => this._handleRecipientDetailsUpdateError(ACCOUNT_UPDATE_ERROR));
},
// uploading and assigning an id verification document
- _assignIdentityVerificationDocument(account, stripeFileUploadId) {
- set(account, 'identityDocumentId', stripeFileUploadId);
+ _assignIdentityVerificationDocument(stripeConnectAccount, stripeFileUploadId) {
+ set(stripeConnectAccount, 'identityDocumentId', stripeFileUploadId);
- return account.save()
- .then((account) => RSVP.resolve(account))
- .catch((reason) => this._handleIdentityVerificationDocumentError(reason));
+ return stripeConnectAccount
+ .save()
+ .then(RSVP.resolve)
+ .catch(() => this._wrapError(VERIFICATION_DOCUMENT_ERROR));
},
- _handleIdentityVerificationDocumentError() {
- let friendlyError = new FriendlyError(VERIFICATION_DOCUMENT_ERROR);
- return RSVP.reject(friendlyError);
+ // assigning a personal id number
+
+ _assignPersonalIdNumber(stripeConnectAccount, personalIdNumber) {
+ set(stripeConnectAccount, 'personalIdNumber', personalIdNumber);
+
+ return stripeConnectAccount
+ .save()
+ .then(RSVP.resolve)
+ .catch(() => this._wrapError(ACCOUNT_UPDATE_ERROR));
},
// bank account - token step
@@ -122,7 +124,7 @@ export default Controller.extend({
return stripe.bankAccount.createToken(params)
.then((stripeResponse) => RSVP.resolve(stripeResponse))
- .catch((reason) => this._handleBankAccountTokenError(reason));
+ .catch(() => this._wrapError(BANK_ACCOUNT_TOKEN_CREATION_ERROR));
},
_bankAccountTokenParams(accountNumber, routingNumber) {
@@ -135,23 +137,21 @@ export default Controller.extend({
};
},
- _handleBankAccountTokenError() {
- let friendlyError = new FriendlyError(ACCOUNT_TOKEN_CREATION_ERROR);
- return RSVP.reject(friendlyError);
- },
-
// bank account - updating connect account record step
_addBankAccount(tokenData, stripeConnectAccount) {
set(stripeConnectAccount, 'externalAccount', tokenData.id);
- return stripeConnectAccount.save()
- .then((stripeConnectAccount) => RSVP.resolve(stripeConnectAccount))
- .catch((reason) => this._handleAddBankAccountError(reason));
+ return stripeConnectAccount
+ .save()
+ .then(RSVP.resolve)
+ .catch(() => this._wrapError(BANK_ACCOUNT_ADDING_ERROR));
},
- _handleAddBankAccountError() {
- let friendlyError = new FriendlyError(ACCOUNT_ADDING_ERROR);
+ // friendly error wrapping
+
+ _wrapError(message) {
+ let friendlyError = new FriendlyError(message);
return RSVP.reject(friendlyError);
},
diff --git a/app/templates/components/payments/funds-recipient.hbs b/app/templates/components/payments/funds-recipient.hbs
index 06c8b915a..bae3a1017 100644
--- a/app/templates/components/payments/funds-recipient.hbs
+++ b/app/templates/components/payments/funds-recipient.hbs
@@ -14,9 +14,10 @@
isBusy=isBusy
onVerificationDocumentSubmitted=(action onVerificationDocumentSubmitted)
stripeConnectAccount=stripeConnectAccount}}
-
- TODO: personal-id-number component goes here
-
+ {{payments/funds-recipient/personal-id-number
+ isBusy=isBusy
+ stripeConnectAccount=stripeConnectAccount
+ submit=(action onPersonalIdNumberSubmitted)}}
{{/if}}
{{#if (eq status 'verified')}}
diff --git a/app/templates/components/payments/funds-recipient/personal-id-number.hbs b/app/templates/components/payments/funds-recipient/personal-id-number.hbs
new file mode 100644
index 000000000..1be8b4546
--- /dev/null
+++ b/app/templates/components/payments/funds-recipient/personal-id-number.hbs
@@ -0,0 +1,16 @@
+{{#if (eq status 'required')}}
+
+
+{{/if}}
+
+{{#if (eq status 'verifying')}}
+ We're verifying your ID number
+{{/if}}
\ No newline at end of file
diff --git a/app/templates/components/payments/funds-recipient/verification-document.hbs b/app/templates/components/payments/funds-recipient/verification-document.hbs
index 0f1ae7389..81c1db4f3 100644
--- a/app/templates/components/payments/funds-recipient/verification-document.hbs
+++ b/app/templates/components/payments/funds-recipient/verification-document.hbs
@@ -1,4 +1,3 @@
-
{{#if (eq status 'required')}}
{{#if isBusy}}
Processing...
@@ -23,4 +22,4 @@
{{/if}}
{{#if (eq status 'verifying')}}
Please be patient while we review the document you provided.
-{{/if}}
\ No newline at end of file
+{{/if}}
diff --git a/tests/integration/components/payments/funds-recipient-test.js b/tests/integration/components/payments/funds-recipient-test.js
index b58484585..b9a644470 100644
--- a/tests/integration/components/payments/funds-recipient-test.js
+++ b/tests/integration/components/payments/funds-recipient-test.js
@@ -7,10 +7,7 @@ import fundsRecipientComponent from '../../../pages/components/payments/funds-re
let page = PageObject.create(fundsRecipientComponent);
-const {
- setProperties,
- K
-} = Ember;
+const { setProperties, K } = Ember;
function setHandlers(context, { detailsHandler = K, documentHandler = K, idHandler = K }) {
setProperties(context, { detailsHandler, documentHandler, idHandler });
@@ -61,7 +58,7 @@ test('it renders correctly when "required"', function(assert) {
assert.ok(page.rendersDetailsForm, 'Component renders the details form subcomponent.');
});
-test('it renders correctly when "verifying"', function(assert) {
+test('it renders correctly when "verifying" and document status "required"', function(assert) {
assert.expect(3);
let stripeConnectAccount = { recipientStatus: 'verifying' };
@@ -107,30 +104,52 @@ test('it renders correctly when "verified" for business', function(assert) {
assert.ok(page.businessNameText, 'Company Inc.', 'Component renders the name of the registered business.');
});
-// TODO: These need to be implemented once subcomponents are done and pass out actions
-// test('it passes out submit action from details subcomponent', function(assert) {
-// assert.expect(1);
+test('it passes out submit action from details subcomponent', function(assert) {
+ assert.expect(1);
-// let stripeConnectAccount = { recipientStatus: 'required' };
-// this.set('stripeConnectAccount', stripeConnectAccount);
+ let stripeConnectAccount = { recipientStatus: 'required' };
+ this.set('stripeConnectAccount', stripeConnectAccount);
-// renderPage();
-// });
+ function detailsHandler() {
+ assert.ok(true, 'Action got called');
+ }
+ setHandlers(this, { detailsHandler });
+
+ renderPage();
+
+ page.detailsForm.clickSubmit();
+});
+
+// TODO: Get this working
// test('it passes out submit action from document upload subcomponent', function(assert) {
// assert.expect(1);
-// let stripeConnectAccount = { recipientStatus: 'verifying' };
+// let stripeConnectAccount = { recipientStatus: 'verifying', verificationDocumentStatus: 'required' };
// this.set('stripeConnectAccount', stripeConnectAccount);
+// function documentHandler() {
+// assert.ok(true, 'Action got called');
+// };
+// setHandlers(this, { documentHandler });
+
// renderPage();
+
+// page.verificationDocument.pickFile(this);
// });
-// test('it passes out submit action from personal id number subcomponent', function(assert) {
-// assert.expect(1);
+test('it passes out submit action from personal id number subcomponent', function(assert) {
+ assert.expect(1);
-// let stripeConnectAccount = { recipientStatus: 'verifying' };
-// this.set('stripeConnectAccount', stripeConnectAccount);
+ let stripeConnectAccount = { recipientStatus: 'verifying', personalIdNumberStatus: 'required' };
+ this.set('stripeConnectAccount', stripeConnectAccount);
-// renderPage();
-// });
+ function idHandler() {
+ assert.ok(true, 'Action got called');
+ }
+ setHandlers(this, { idHandler });
+
+ renderPage();
+
+ page.personalIdNumber.clickSubmit();
+});
diff --git a/tests/integration/components/payments/funds-recipient/personal-id-number-test.js b/tests/integration/components/payments/funds-recipient/personal-id-number-test.js
new file mode 100644
index 000000000..970960e76
--- /dev/null
+++ b/tests/integration/components/payments/funds-recipient/personal-id-number-test.js
@@ -0,0 +1,111 @@
+import Ember from 'ember';
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+import PageObject from 'ember-cli-page-object';
+
+import personalIdNumberComponent from 'code-corps-ember/tests/pages/components/payments/funds-recipient/personal-id-number';
+
+let page = PageObject.create(personalIdNumberComponent);
+
+const {
+ set,
+ K
+} = Ember;
+
+function setHandler(context, submitHandler = K) {
+ set(context, 'submitHandler', submitHandler);
+}
+
+function renderPage() {
+ page.render(hbs`
+ {{payments/funds-recipient/personal-id-number
+ isBusy=isBusy
+ stripeConnectAccount=stripeConnectAccount
+ submit=submitHandler}}
+ `);
+}
+
+moduleForComponent('payments/funds-recipient/personal-id-number', 'Integration | Component | payments/funds recipient/personal id number', {
+ integration: true,
+ beforeEach() {
+ setHandler(this);
+ page.setContext(this);
+ },
+ afterEach() {
+ page.removeContext();
+ }
+});
+
+test('it renders correctly for "pending" status', function(assert) {
+ assert.expect(1);
+
+ let stripeConnectAccount = { personalIdNumberStatus: 'pending_requirement' };
+ set(this, 'stripeConnectAccount', stripeConnectAccount);
+
+ renderPage();
+
+ assert.equal(page.text, '', 'Component renders nothing at all.');
+});
+
+test('it renders correctly for "required" status', function(assert) {
+ assert.expect(2);
+
+ let stripeConnectAccount = { personalIdNumberStatus: 'required' };
+ set(this, 'stripeConnectAccount', stripeConnectAccount);
+
+ renderPage();
+
+ assert.ok(page.rendersPersonalIdNumberField, 'Component renders the account number field.');
+ assert.ok(page.rendersSubmitButton, 'Component renders the submit button.');
+});
+
+test('it renders correctly for "verifying" status', function(assert) {
+ assert.expect(1);
+
+ let stripeConnectAccount = { personalIdNumberStatus: 'verifying' };
+ set(this, 'stripeConnectAccount', stripeConnectAccount);
+
+ renderPage();
+
+ assert.equal(page.text, "We're verifying your ID number");
+});
+
+test('it renders correctly for "verified" status', function(assert) {
+ assert.expect(1);
+
+ let stripeConnectAccount = { personalIdNumberStatus: 'verified' };
+ set(this, 'stripeConnectAccount', stripeConnectAccount);
+
+ renderPage();
+
+ assert.equal(page.text, '', 'Component renders nothing at all.');
+});
+
+test('it sends properties with submit action', function(assert) {
+ assert.expect(1);
+
+ let stripeConnectAccount = { personalIdNumberStatus: 'required' };
+ set(this, 'stripeConnectAccount', stripeConnectAccount);
+
+ let personalIdNumber = '123456';
+
+ setHandler(this, (number) => {
+ assert.equal(personalIdNumber, number, 'Correct parameter was sent out with action.');
+ });
+
+ renderPage();
+ page.personalIdNumber(personalIdNumber).clickSubmit();
+});
+
+test('it disables controls when busy', function(assert) {
+ assert.expect(2);
+
+ let stripeConnectAccount = { personalIdNumberStatus: 'required' };
+ set(this, 'isBusy', true);
+ set(this, 'stripeConnectAccount', stripeConnectAccount);
+
+ renderPage();
+
+ assert.ok(page.personalIdNumberFieldIsDisabled, 'Personal ID number field is disabled when busy.');
+ assert.ok(page.submitButtonIsDisabled, 'Submit button is disabled when busy.');
+});
diff --git a/tests/integration/components/payments/funds-recipient/verification-document-test.js b/tests/integration/components/payments/funds-recipient/verification-document-test.js
index 75558209c..105c5f248 100644
--- a/tests/integration/components/payments/funds-recipient/verification-document-test.js
+++ b/tests/integration/components/payments/funds-recipient/verification-document-test.js
@@ -41,7 +41,6 @@ test('it renders file upload subcomponent if status is "required"', function(ass
assert.expect(1);
this.set('stripeConnectAccount', { verificationDocumentStatus: 'required' });
-
renderPage();
assert.ok(page.rendersFileUpload, 'File upload subcomponent is rendered');
diff --git a/tests/pages/components/payments/funds-recipient.js b/tests/pages/components/payments/funds-recipient.js
index 25e2e25c7..cd3dcb8ef 100644
--- a/tests/pages/components/payments/funds-recipient.js
+++ b/tests/pages/components/payments/funds-recipient.js
@@ -1,5 +1,9 @@
import { hasClass, isVisible, text } from 'ember-cli-page-object';
+import detailsForm from './funds-recipient/details-form';
+import verificationDocument from './funds-recipient/verification-document';
+import personalIdNumber from './funds-recipient/personal-id-number';
+
export default {
scope: '.funds-recipient',
@@ -13,5 +17,9 @@ export default {
rendersPersonalIdNumber: isVisible('.personal-id-number'),
individualNameText: text('.funds-recipient__individual-name p'),
- businessNameText: text('.funds-recipient__business-name p')
+ businessNameText: text('.funds-recipient__business-name p'),
+
+ detailsForm,
+ verificationDocument,
+ personalIdNumber
};
diff --git a/tests/pages/components/payments/funds-recipient/personal-id-number.js b/tests/pages/components/payments/funds-recipient/personal-id-number.js
new file mode 100644
index 000000000..cd6745fa7
--- /dev/null
+++ b/tests/pages/components/payments/funds-recipient/personal-id-number.js
@@ -0,0 +1,15 @@
+import { clickable, fillable, is, isVisible } from 'ember-cli-page-object';
+
+export default {
+ scope: '.personal-id-number',
+
+ clickSubmit: clickable('button'),
+
+ personalIdNumber: fillable('input[type=text]'),
+ personalIdNumberFieldIsDisabled: is(':disabled', 'input[type=text]'),
+
+ rendersPersonalIdNumberField: isVisible('input[type=text]'),
+ rendersSubmitButton: isVisible('button'),
+
+ submitButtonIsDisabled: is(':disabled', 'button')
+};
diff --git a/tests/pages/components/payments/funds-recipient/verification-document.js b/tests/pages/components/payments/funds-recipient/verification-document.js
index c80020e78..ae9eeb830 100644
--- a/tests/pages/components/payments/funds-recipient/verification-document.js
+++ b/tests/pages/components/payments/funds-recipient/verification-document.js
@@ -1,7 +1,9 @@
-import { isVisible, text } from 'ember-cli-page-object';
+import { clickable, isVisible, text } from 'ember-cli-page-object';
export default {
+ scope: '.verification-document',
errorText: text('.error'),
- rendersFileUpload: isVisible('input[type=file]')
-
+ rendersFileUpload: isVisible('input[type=file]'),
+ clickSubmit: clickable('button')
};
+