dune-balanced-bankaccount 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +6 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +17 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +59 -0
  10. data/Rakefile +34 -0
  11. data/app/assets/images/dune/balanced/bankaccount/.gitkip +0 -0
  12. data/app/assets/javascripts/dune-balanced-bankaccount.js +1 -0
  13. data/app/assets/javascripts/dune/balanced/bankaccount/.gitkip +0 -0
  14. data/app/assets/javascripts/dune/balanced/bankaccount/accounts.js.coffee.erb +24 -0
  15. data/app/assets/javascripts/dune/balanced/bankaccount/flash.js.coffee +16 -0
  16. data/app/assets/javascripts/dune/balanced/bankaccount/form.js.coffee.erb +90 -0
  17. data/app/assets/javascripts/dune/balanced/bankaccount/payments.js.coffee.erb +25 -0
  18. data/app/assets/stylesheets/dune/balanced/bankaccount/.gitkip +0 -0
  19. data/app/controllers/dune/balanced/bankaccount/accounts_controller.rb +67 -0
  20. data/app/controllers/dune/balanced/bankaccount/application_controller.rb +4 -0
  21. data/app/controllers/dune/balanced/bankaccount/confirmations_controller.rb +66 -0
  22. data/app/controllers/dune/balanced/bankaccount/payments_controller.rb +65 -0
  23. data/app/controllers/dune/balanced/bankaccount/routing_numbers_controller.rb +10 -0
  24. data/app/helpers/application_helper.rb +8 -0
  25. data/app/models/dune/balanced/bankaccount/delayed_payment.rb +18 -0
  26. data/app/models/dune/balanced/bankaccount/delayed_payment_processing.rb +22 -0
  27. data/app/models/dune/balanced/bankaccount/payment.rb +69 -0
  28. data/app/models/dune/balanced/bankaccount/payment_base.rb +44 -0
  29. data/app/models/dune/balanced/bankaccount/payment_generator.rb +38 -0
  30. data/app/models/dune/balanced/bankaccount/routing_number.rb +6 -0
  31. data/app/models/dune/balanced/bankaccount/transaction_additional_fee_calculator.rb +12 -0
  32. data/app/models/dune/balanced/bankaccount/transaction_fee_calculator_base.rb +34 -0
  33. data/app/models/dune/balanced/bankaccount/transaction_inclusive_fee_calculator.rb +16 -0
  34. data/app/models/dune/balanced/bankaccount/verification.rb +34 -0
  35. data/app/models/dune/balanced/event_registered.rb +13 -0
  36. data/app/views/dune/balanced/bankaccount/accounts/new.html.slim +96 -0
  37. data/app/views/dune/balanced/bankaccount/confirmations/new.html.slim +53 -0
  38. data/app/views/dune/balanced/bankaccount/payments/new.html.slim +97 -0
  39. data/app/views/notifications_mailer/balanced/bankaccount/bank_account_replaced.en.html.slim +12 -0
  40. data/app/views/notifications_mailer/balanced/bankaccount/confirm_bank_account.en.html.slim +16 -0
  41. data/app/views/notifications_mailer/balanced/bankaccount/new_verification_started.en.html.slim +14 -0
  42. data/app/views/notifications_mailer/subjects/balanced/bankaccount/bank_account_replaced.en.text.slim +1 -0
  43. data/app/views/notifications_mailer/subjects/balanced/bankaccount/confirm_bank_account.en.text.slim +1 -0
  44. data/app/views/notifications_mailer/subjects/balanced/bankaccount/new_verification_started.en.text.slim +1 -0
  45. data/app/workers/dune/balanced/bankaccount/debit_authorized_contributions_worker.rb +26 -0
  46. data/bin/rails +8 -0
  47. data/bin/test_suite +19 -0
  48. data/config/environment.rb +0 -0
  49. data/config/initializers/event_observers.rb +2 -0
  50. data/config/initializers/registration.rb +5 -0
  51. data/config/locales/en.yml +59 -0
  52. data/config/locales/simple_form.en.yml +21 -0
  53. data/config/routes.rb +6 -0
  54. data/db/migrate/20140224220426_create_routing_number.rb +10 -0
  55. data/db/migrate/20140813180429_use_hrefs_for_balanced_resources.rb +41 -0
  56. data/dune-balanced-bankaccount.gemspec +29 -0
  57. data/lib/dune/balanced/bankaccount.rb +11 -0
  58. data/lib/dune/balanced/bankaccount/engine.rb +14 -0
  59. data/lib/dune/balanced/bankaccount/interface.rb +28 -0
  60. data/lib/dune/balanced/bankaccount/version.rb +7 -0
  61. data/lib/float_extensions.rb +11 -0
  62. data/lib/tasks/dune/balanced/bankaccount/update_routing_numbers.rake +27 -0
  63. data/spec/controllers/dune/balanced/bankaccount/accounts_controller_spec.rb +183 -0
  64. data/spec/controllers/dune/balanced/bankaccount/confirmations_controller_spec.rb +190 -0
  65. data/spec/controllers/dune/balanced/bankaccount/payments_controller_spec.rb +158 -0
  66. data/spec/controllers/dune/balanced/bankaccount/routing_numbers_controller_spec.rb +22 -0
  67. data/spec/factories.rb +47 -0
  68. data/spec/lib/dune/balanced/bankaccount/interface_spec.rb +37 -0
  69. data/spec/models/dune/balanced/bankaccount/delayed_payment_processing_spec.rb +38 -0
  70. data/spec/models/dune/balanced/bankaccount/delayed_payment_spec.rb +66 -0
  71. data/spec/models/dune/balanced/bankaccount/payment_generator_spec.rb +65 -0
  72. data/spec/models/dune/balanced/bankaccount/payment_spec.rb +252 -0
  73. data/spec/models/dune/balanced/bankaccount/routing_number_spec.rb +6 -0
  74. data/spec/models/dune/balanced/bankaccount/transaction_additional_fee_calculator_spec.rb +53 -0
  75. data/spec/models/dune/balanced/bankaccount/transaction_inclusive_fee_calculator_spec.rb +34 -0
  76. data/spec/models/dune/balanced/bankaccount/verification_spec.rb +34 -0
  77. data/spec/models/dune/balanced/event_registered_spec.rb +51 -0
  78. data/spec/spec_helper.rb +44 -0
  79. data/spec/workers/dune/balanced/bankaccount/debit_authorized_contributions_worker_spec.rb +71 -0
  80. metadata +241 -0
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Balanced::Bankaccount::PaymentsController do
4
+ routes { Dune::Balanced::Bankaccount::Engine.routes }
5
+
6
+ let(:current_user) { double('User').as_null_object }
7
+
8
+ let(:bank_account) do
9
+ double('::Balanced::BankAccount', href: '/ABANK').as_null_object
10
+ end
11
+
12
+ let(:customer) do
13
+ double('::Balanced::Customer',
14
+ bank_accounts: [bank_account],
15
+ href: '/qwertyuiop').as_null_object
16
+ end
17
+
18
+ before do
19
+ ::Balanced::Customer.stub(:find).and_return(customer)
20
+ ::Balanced::Customer.stub(:new).and_return(customer)
21
+ ::Balanced::BankAccount.stub(:find).and_return(bank_account)
22
+ Dune::Balanced::Bankaccount::PaymentGenerator.any_instance.stub(:complete)
23
+ end
24
+
25
+ context 'authenticated' do
26
+ before { sign_in FactoryGirl.create(:user) }
27
+
28
+ describe 'get new' do
29
+ it 'should use accounts controller new action' do
30
+ expect_any_instance_of(
31
+ Dune::Balanced::Bankaccount::AccountsController
32
+ ).to receive(:new)
33
+ get :new, contribution_id: 42
34
+ end
35
+ end
36
+
37
+ describe 'POST create' do
38
+ shared_examples_for '#create' do
39
+ let(:payment) do
40
+ double('Payment', status: :succeeded).as_null_object
41
+ end
42
+ let(:params) do
43
+ {
44
+ 'payment' => {
45
+ resource_id_name => resource.id.to_s,
46
+ 'use_bank' => '/ABANK',
47
+ 'user' => {}
48
+ },
49
+ }
50
+ end
51
+ let(:resource) { FactoryGirl.create(resource_class.to_s.underscore) }
52
+
53
+ it 'should receive authenticate_user!' do
54
+ expect(controller).to receive(:authenticate_user!)
55
+ post :create, params
56
+ end
57
+
58
+ before do
59
+ Dune::Balanced::Bankaccount::PaymentGenerator.
60
+ any_instance.
61
+ stub(:status).
62
+ and_return(:succeeded)
63
+ end
64
+
65
+ it 'generates new payment with given params' do
66
+ Dune::Balanced::Bankaccount::PaymentGenerator.should_receive(:new).
67
+ with(customer, an_instance_of(resource_class), params['payment']).
68
+ and_return(payment)
69
+ post :create, params
70
+ end
71
+
72
+ it 'completes a payment of the resource' do
73
+ Dune::Balanced::Bankaccount::PaymentGenerator.any_instance.should_receive(:complete)
74
+ post :create, params
75
+ end
76
+
77
+ context 'with successul checkout' do
78
+ it 'redirects to contribute page' do
79
+ post :create, params
80
+ expect(response).to redirect_to(resource_path)
81
+ end
82
+ end
83
+
84
+ context 'with pending checkout status' do
85
+ before do
86
+ Dune::Balanced::Bankaccount::PaymentGenerator.
87
+ any_instance.
88
+ stub(:status).
89
+ and_return(:pending)
90
+ end
91
+
92
+ it 'redirects to contribute page' do
93
+ post :create, params
94
+ expect(response).to redirect_to(resource_path)
95
+ end
96
+ end
97
+
98
+ context 'with unsuccessul checkout' do
99
+ before do
100
+ Dune::Balanced::Bankaccount::PaymentGenerator.
101
+ any_instance.
102
+ stub(:status).
103
+ and_return(:failed)
104
+ end
105
+
106
+ it 'redirects to resource edit page' do
107
+ post :create, params
108
+ expect(response).to redirect_to(edit_resource_path)
109
+ end
110
+ end
111
+
112
+ describe 'insertion of bank account to a customer' do
113
+ it 'should use accounts controller attach_bank_to_customer method' do
114
+ expect_any_instance_of(
115
+ Dune::Balanced::Bankaccount::AccountsController
116
+ ).to receive(:attach_bank_to_customer)
117
+ post :create, params
118
+ end
119
+ end
120
+
121
+ describe 'update customer' do
122
+ it 'update user attributes and balanced customer' do
123
+ expect_any_instance_of(
124
+ Dune::Balanced::Customer
125
+ ).to receive(:update!)
126
+ post :create, params
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'when resource is Contribution' do
132
+ let(:resource_class) { Contribution }
133
+ let(:resource_id_name) { 'contribution_id' }
134
+ let(:resource_path) do
135
+ project_contribution_path(resource.project, resource)
136
+ end
137
+ let(:edit_resource_path) do
138
+ edit_project_contribution_path(resource.project, resource)
139
+ end
140
+
141
+ it_should_behave_like '#create'
142
+ end
143
+
144
+ context 'when resource is Match' do
145
+ let(:resource_class) { Match }
146
+ let(:resource_id_name) { 'match_id' }
147
+ let(:resource_path) do
148
+ project_match_path(resource.project, resource)
149
+ end
150
+ let(:edit_resource_path) do
151
+ edit_project_match_path(resource.project, resource)
152
+ end
153
+
154
+ it_should_behave_like '#create'
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ module Dune::Balanced::Bankaccount
4
+ describe RoutingNumbersController do
5
+ routes { Dune::Balanced::Bankaccount::Engine.routes }
6
+
7
+ describe '#show' do
8
+ context 'when routing number is incorrect' do
9
+ before { get :show, id: 123 }
10
+ it { expect(response.status).to eq 200 }
11
+ it { expect(response.body).to eq({ ok: false, bank_name: nil }.to_json) }
12
+ end
13
+
14
+ context 'when routing number is correct' do
15
+ let(:routing_number) { RoutingNumber.create! number: 123456, bank_name: 'Bank of America' }
16
+ before { get :show, id: routing_number.number }
17
+ it { expect(response.status).to eq 200 }
18
+ it { expect(response.body).to eq({ ok: true, bank_name: 'Bank of America' }.to_json) }
19
+ end
20
+ end
21
+ end
22
+ end
data/spec/factories.rb ADDED
@@ -0,0 +1,47 @@
1
+ FactoryGirl.define do
2
+ factory :category do
3
+ name_pt { "category-#{rand}" }
4
+ end
5
+
6
+ factory :contribution do
7
+ confirmed_at { Time.now }
8
+ credits false
9
+ value 10
10
+ state :confirmed
11
+ association :project, factory: :online_project
12
+ user
13
+ end
14
+
15
+ factory :match do |f|
16
+ finishes_at { project.expires_at }
17
+ starts_at { Time.now.utc.to_date }
18
+ state :confirmed
19
+ value 1_500
20
+ value_unit 2
21
+ association :project, factory: :online_project
22
+ user
23
+ end
24
+
25
+ factory :project do
26
+ about 'a-big-text-about-the-project'
27
+ goal 10_000
28
+ headline 'attractive-headline'
29
+ location 'New York, NY'
30
+ name 'a-project'
31
+ user
32
+ category
33
+
34
+ factory :online_project do
35
+ online_date { Time.now }
36
+ online_days 30
37
+ state 'online'
38
+ end
39
+ end
40
+
41
+ factory :user do
42
+ name 'Joãozinho'
43
+ password 'right-password'
44
+ email { "person#{rand}@example.com" }
45
+ confirmed_at { Time.now }
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Balanced::Bankaccount::Interface do
4
+
5
+ it 'should return the engine name' do
6
+ expect(subject.name).to eq 'balanced-bankaccount'
7
+ end
8
+
9
+ it 'should return account path' do
10
+ expect(subject.account_path).to eq Dune::Balanced::Bankaccount::Engine.
11
+ routes.url_helpers.new_account_path
12
+ end
13
+
14
+ it 'should return an instance of TransactionAdditionalFeeCalculator' do
15
+ expect(subject.fee_calculator(10)).to be_an_instance_of(Dune::Balanced::Bankaccount::TransactionAdditionalFeeCalculator)
16
+ end
17
+
18
+ describe '#payment_path' do
19
+ context 'when resource is a Contribution' do
20
+ let(:resource) { Contribution.new(id: 42) }
21
+
22
+ it 'should return payment path' do
23
+ expect(subject.payment_path(resource)).to eq Dune::Balanced::Bankaccount::Engine.
24
+ routes.url_helpers.new_payment_path(contribution_id: resource)
25
+ end
26
+ end
27
+
28
+ context 'when resource is a Match' do
29
+ let(:resource) { Match.new(id: 42) }
30
+
31
+ it 'should return payment path' do
32
+ expect(subject.payment_path(resource)).to eq Dune::Balanced::Bankaccount::Engine.
33
+ routes.url_helpers.new_payment_path(match_id: resource)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Balanced::Bankaccount::DelayedPaymentProcessing do
4
+ let(:contributor) { double('Contributor', href: '/MYID') }
5
+ let(:customer) { double('Customer') }
6
+ subject { described_class.new(contributor, contributions) }
7
+ before do
8
+ ::Balanced::Customer.stub(:find).and_return(customer)
9
+ end
10
+
11
+ describe 'completion' do
12
+ let(:contribution_1) { double('Contribution') }
13
+ let(:contribution_2) { contribution_1.dup }
14
+ let(:contributions) { [contribution_1, contribution_2] }
15
+
16
+ it 'generates a Payment for each contribution' do
17
+ expect(
18
+ Dune::Balanced::Bankaccount::Payment
19
+ ).to receive(:new).with(anything, anything, contribution_1, anything).
20
+ and_return(double.as_null_object)
21
+ expect(
22
+ Dune::Balanced::Bankaccount::Payment
23
+ ).to receive(:new).with(anything, anything, contribution_2, anything).
24
+ and_return(double.as_null_object)
25
+ subject.complete
26
+ end
27
+
28
+ it 'checkouts a Payment for each contribution' do
29
+ payment = double('Dune::Balanced::Bankaccount::Payment').as_null_object
30
+ Dune::Balanced::Bankaccount::Payment.
31
+ stub(:new).
32
+ and_return(payment)
33
+
34
+ expect(payment).to receive(:checkout!).twice
35
+ subject.complete
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Balanced::Bankaccount::DelayedPayment do
4
+ let(:customer) { double('::Balanced::Customer') }
5
+ let(:contribution) { double('Contribution', value: 1234).as_null_object }
6
+ let(:bank_account) { double('::Balanced::BankAccount', href: '/ABANK') }
7
+ let(:attributes) { { pay_fee: '1', use_bank: bank_account.href } }
8
+ subject do
9
+ described_class.new('balanced-bankaccount',
10
+ customer,
11
+ contribution,
12
+ attributes)
13
+ end
14
+
15
+ describe 'checkout' do
16
+ it 'authorizes payment of contribution' do
17
+ expect(contribution).to receive(:wait_confirmation!)
18
+ subject.checkout!
19
+ end
20
+
21
+ it 'defines given engine\'s name as payment method of the contribution' do
22
+ contribution.should_receive(:update_attributes).
23
+ with(hash_including(payment_method: 'balanced-bankaccount'))
24
+ subject.checkout!
25
+ end
26
+
27
+ it 'saves paid fees on contribution object' do
28
+ calculator = double('FeeCalculator', fees: 0.42).as_null_object
29
+ subject.stub(:fee_calculator).and_return(calculator)
30
+ contribution.should_receive(:update_attributes).
31
+ with(hash_including(payment_service_fee: 0.42))
32
+ subject.checkout!
33
+ end
34
+
35
+ it 'saves who paid the fees' do
36
+ calculator = double('FeeCalculator', fees: 0.42).as_null_object
37
+ subject.stub(:fee_calculator).and_return(calculator)
38
+ contribution.should_receive(:update_attributes).
39
+ with(hash_including(payment_service_fee_paid_by_user: '1'))
40
+ subject.checkout!
41
+ end
42
+ end
43
+
44
+ describe 'status' do
45
+ context 'after checkout' do
46
+ before do
47
+ subject.checkout!
48
+ end
49
+
50
+ it 'is succeeded' do
51
+ expect(subject.status).to eql(:succeeded)
52
+ expect(subject).to be_successful
53
+ end
54
+ end
55
+
56
+ context 'before checkout' do
57
+ it 'is nil' do
58
+ expect(subject.status).to be_nil
59
+ end
60
+
61
+ it 'is not succeeded' do
62
+ expect(subject).to_not be_successful
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Balanced::Bankaccount::PaymentGenerator do
4
+ let(:customer) { double('::Balanced::Customer') }
5
+ let(:contribution) { double('Contribution', value: 1234).as_null_object }
6
+ let(:attrs) { { use_bank: '/ABANK' } }
7
+ let(:bank_account) { double('::Balanced::BankAccount', bank_account_verifications: []) }
8
+ subject { described_class.new(customer, contribution, attrs) }
9
+
10
+ before do
11
+ ::Balanced::BankAccount.stub(:find).and_return(bank_account)
12
+ end
13
+
14
+ describe 'ability to debit resource' do
15
+ before do
16
+ bank_account.stub(:bank_account_verifications).and_return(verifications)
17
+ end
18
+
19
+ context 'with confirmed verification' do
20
+ let(:verifications) do
21
+ [double('::Balanced::BankAccountVerification', verification_status: 'succeeded')]
22
+ end
23
+
24
+ it 'is able to debit resource' do
25
+ expect(subject.can_debit_resource?).to be_truthy
26
+ end
27
+ end
28
+
29
+ context 'with verification started' do
30
+ let(:verifications) do
31
+ [double('::Balanced::BankAccountVerification', state: 'deposit_succeeded')]
32
+ end
33
+
34
+ it 'isn\'t able to debit resource' do
35
+ expect(subject.can_debit_resource?).to be_falsey
36
+ end
37
+ end
38
+
39
+ context 'without verifications' do
40
+ let(:verifications) { [] }
41
+
42
+ it 'isn\'t able to debit resource' do
43
+ expect(subject.can_debit_resource?).to be_falsey
44
+ end
45
+ end
46
+ end
47
+
48
+ describe 'completion' do
49
+ it 'checkouts using Payment class when is able to debit resource' do
50
+ subject.stub(:can_debit_resource?).and_return(true)
51
+ expect_any_instance_of(
52
+ Dune::Balanced::Bankaccount::Payment
53
+ ).to receive(:checkout!)
54
+ subject.complete
55
+ end
56
+
57
+ it 'checkouts using DelayedPayment when is not able to debit resource' do
58
+ subject.stub(:can_debit_resource?).and_return(false)
59
+ expect_any_instance_of(
60
+ Dune::Balanced::Bankaccount::DelayedPayment
61
+ ).to receive(:checkout!)
62
+ subject.complete
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,252 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Balanced::Bankaccount::Payment do
4
+ shared_examples_for 'payable' do
5
+ let(:customer) { double('::Balanced::Customer', href: '/CUSTOMER-ID') }
6
+ let(:debit) { double('::Balanced::Debit').as_null_object }
7
+ let(:bank_account) { double('::Balanced::BankAccount', href: '/ABANK') }
8
+ let(:attributes) { { use_bank: bank_account.href } }
9
+ subject do
10
+ described_class.new('balanced-bankaccount',
11
+ customer,
12
+ resource,
13
+ attributes)
14
+ end
15
+ before do
16
+ Balanced::BankAccount.stub(:find).with(bank_account.href).
17
+ and_return(bank_account)
18
+ subject.stub_chain(:contributor, :projects).and_return([])
19
+
20
+ User.any_instance.stub(:balanced_contributor).and_return(
21
+ double('BalancedContributor', href: 'project-owner-href')
22
+ )
23
+
24
+ allow_any_instance_of(Dune::Balanced::OrderProxy).to receive(:debit_from).and_return(debit)
25
+ resource.stub(:value).and_return(1234)
26
+ described_class.any_instance.stub(:meta).and_return({})
27
+ end
28
+
29
+ describe '#amount_in_cents' do
30
+ context 'when customer is paying fees' do
31
+ let(:attributes) { { pay_fee: '1', use_bank: bank_account.href } }
32
+
33
+ it 'returns gross amount from TransactionAdditionalFeeCalculator' do
34
+ Dune::Balanced::Bankaccount::TransactionAdditionalFeeCalculator.
35
+ any_instance.stub(:gross_amount).and_return(15)
36
+ expect(subject.amount_in_cents).to eql(1500)
37
+ end
38
+ end
39
+
40
+ context 'when customer is not paying fees' do
41
+ let(:attributes) { { pay_fee: '0', use_bank: bank_account.href } }
42
+
43
+ it 'returns gross amount from TransactionInclusiveFeeCalculator' do
44
+ Dune::Balanced::Bankaccount::TransactionInclusiveFeeCalculator.
45
+ any_instance.stub(:gross_amount).and_return(10)
46
+ expect(subject.amount_in_cents).to eql(1000)
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'checkout' do
52
+ shared_examples 'updates resource object' do
53
+ let(:attributes) { { pay_fee: '1', use_bank: bank_account.href } }
54
+
55
+ context 'when a use_bank is provided' do
56
+ before do
57
+ allow(Balanced::BankAccount).to receive(:find).
58
+ with(bank_account.href).and_return(bank_account)
59
+ end
60
+
61
+ it 'debits customer on selected funding instrument' do
62
+ expect_any_instance_of(
63
+ Dune::Balanced::OrderProxy
64
+ ).to receive(:debit_from).with(hash_including(source: bank_account)).
65
+ and_return(debit)
66
+ subject.checkout!
67
+ end
68
+ end
69
+
70
+ context 'when no use_bank is provided' do
71
+ let(:contributor) do
72
+ double('Dune::Balanced::Contributor',
73
+ bank_account_href: '/MY-DEFAULT-BANK',
74
+ projects: []
75
+ )
76
+ end
77
+ let(:attributes) { { pay_fee: '1' } }
78
+ before do
79
+ subject.stub(:contributor).and_return(contributor)
80
+ allow(Balanced::BankAccount).to receive(:find).
81
+ with(contributor.bank_account_href).and_return(bank_account)
82
+ end
83
+
84
+ it 'debits customer on default funding instrument' do
85
+ expect_any_instance_of(
86
+ Dune::Balanced::OrderProxy
87
+ ).to receive(:debit_from).with(hash_including(source: bank_account)).
88
+ and_return(debit)
89
+ subject.checkout!
90
+ end
91
+ end
92
+
93
+ it 'defines given engine\'s name as payment method of the resource' do
94
+ resource.should_receive(:update_attributes).
95
+ with(hash_including(payment_method: 'balanced-bankaccount'))
96
+ subject.checkout!
97
+ end
98
+
99
+ it 'saves paid fees on resource object' do
100
+ calculator = double('FeeCalculator', fees: 0.42).as_null_object
101
+ subject.stub(:fee_calculator).and_return(calculator)
102
+ resource.should_receive(:update_attributes).
103
+ with(hash_including(payment_service_fee: 0.42))
104
+ subject.checkout!
105
+ end
106
+
107
+ it 'saves who paid the fees' do
108
+ calculator = double('FeeCalculator', fees: 0.42).as_null_object
109
+ subject.stub(:fee_calculator).and_return(calculator)
110
+ resource.should_receive(:update_attributes).
111
+ with(hash_including(payment_service_fee_paid_by_user: '1'))
112
+ subject.checkout!
113
+ end
114
+ end
115
+
116
+ context 'with successful debit' do
117
+ before do
118
+ allow_any_instance_of(
119
+ Dune::Balanced::OrderProxy
120
+ ).to receive(:debit_from).and_return(debit)
121
+ end
122
+
123
+ include_examples 'updates resource object'
124
+
125
+ it 'confirms the resource' do
126
+ expect(resource).to receive(:confirm)
127
+ subject.checkout!
128
+ end
129
+
130
+ it 'defines appears_on_statement_as on debit' do
131
+ ::Configuration.stub(:[]).with(:balanced_appears_on_statement_as).
132
+ and_return('www.dune-investissement.fr')
133
+
134
+ expect_any_instance_of(
135
+ Dune::Balanced::OrderProxy
136
+ ).to receive(:debit_from).with(hash_including(appears_on_statement_as: 'dune-investissement')).
137
+ and_return(debit)
138
+ subject.checkout!
139
+ end
140
+
141
+ it 'defines id as payment id of the resource' do
142
+ debit.stub(:id).and_return('i-am-an-id!')
143
+ resource.should_receive(:update_attributes).
144
+ with(hash_including(payment_id: 'i-am-an-id!'))
145
+ subject.checkout!
146
+ end
147
+
148
+ it 'defines meta on debit' do
149
+ described_class.any_instance.stub(:meta).and_return({ payment_service_fee: 5.0 })
150
+ expect_any_instance_of(
151
+ Dune::Balanced::OrderProxy
152
+ ).to receive(:debit_from).with(hash_including(meta: { payment_service_fee: 5.0 })).
153
+ and_return(debit)
154
+ subject.checkout!
155
+ end
156
+ end
157
+
158
+ context 'when raising Balanced::BadRequest exception' do
159
+ before do
160
+ allow_any_instance_of(
161
+ Dune::Balanced::OrderProxy
162
+ ).to receive(:debit_from).
163
+ and_raise(Balanced::BadRequest.new({}))
164
+ end
165
+
166
+ include_examples 'updates resource object'
167
+
168
+ it 'cancels the resource' do
169
+ expect(resource).to receive(:cancel)
170
+ subject.checkout!
171
+ end
172
+ end
173
+
174
+ context 'when a description is provided to debit' do
175
+ it 'defines description on debit' do
176
+ Project.any_instance.stub(:name).and_return('Awesome Project')
177
+ expect_any_instance_of(
178
+ Dune::Balanced::OrderProxy
179
+ ).to receive(:debit_from).with(hash_including(description: debit_description)).
180
+ and_return(debit)
181
+ subject.checkout!
182
+ end
183
+ end
184
+ end
185
+
186
+ describe 'status' do
187
+ context 'after checkout' do
188
+ before do
189
+ subject.checkout!
190
+ end
191
+
192
+ it 'returns the debit status symbolized' do
193
+ debit.stub(:status).and_return('my_status')
194
+ expect(subject.status).to eql(:my_status)
195
+ end
196
+ end
197
+
198
+ context 'before checkout' do
199
+ it 'is nil' do
200
+ expect(subject.status).to be_nil
201
+ end
202
+ end
203
+ end
204
+
205
+ describe 'successful state' do
206
+ before do
207
+ allow_any_instance_of(
208
+ Dune::Balanced::OrderProxy
209
+ ).to receive(:debit_from).and_return(debit)
210
+ end
211
+
212
+ context 'after checkout' do
213
+ before { subject.checkout! }
214
+
215
+ it 'is successfull when the debit has \'succeeded\' status' do
216
+ debit.stub(:status).and_return('succeeded')
217
+ expect(subject).to be_successful
218
+ end
219
+
220
+ it 'is successfull when the debit has \'pending\' status' do
221
+ debit.stub(:status).and_return('pending')
222
+ expect(subject).to be_successful
223
+ end
224
+
225
+ it 'is not successfull when the debit has others statuses' do
226
+ debit.stub(:status).and_return('failed')
227
+ expect(subject).to_not be_successful
228
+ end
229
+ end
230
+
231
+ context 'before checkout' do
232
+ it 'is not successfull' do
233
+ expect(subject).to_not be_successful
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ context 'when resource is Contribution' do
240
+ let(:resource) { FactoryGirl.create(:contribution) }
241
+ let(:debit_description) { 'Contribution to Awesome Project' }
242
+
243
+ it_should_behave_like 'payable'
244
+ end
245
+
246
+ context 'when resource is Match' do
247
+ let(:resource) { FactoryGirl.create(:match) }
248
+ let(:debit_description) { 'Match for Awesome Project' }
249
+
250
+ it_should_behave_like 'payable'
251
+ end
252
+ end