money_mover 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +17 -0
  5. data/Gemfile.lock +80 -0
  6. data/lib/money_mover/dwolla/account_client.rb +9 -0
  7. data/lib/money_mover/dwolla/account_token.rb +24 -0
  8. data/lib/money_mover/dwolla/api_connection.rb +18 -0
  9. data/lib/money_mover/dwolla/api_server_response.rb +31 -0
  10. data/lib/money_mover/dwolla/application_client.rb +9 -0
  11. data/lib/money_mover/dwolla/application_token.rb +25 -0
  12. data/lib/money_mover/dwolla/client.rb +24 -0
  13. data/lib/money_mover/dwolla/config.rb +33 -0
  14. data/lib/money_mover/dwolla/environment_urls.rb +35 -0
  15. data/lib/money_mover/dwolla/error_handler.rb +30 -0
  16. data/lib/money_mover/dwolla/models/account_funding_source.rb +28 -0
  17. data/lib/money_mover/dwolla/models/api_resource.rb +70 -0
  18. data/lib/money_mover/dwolla/models/customer.rb +53 -0
  19. data/lib/money_mover/dwolla/models/document.rb +22 -0
  20. data/lib/money_mover/dwolla/models/funding_source.rb +30 -0
  21. data/lib/money_mover/dwolla/models/micro_deposit_initiation.rb +19 -0
  22. data/lib/money_mover/dwolla/models/micro_deposit_verification.rb +31 -0
  23. data/lib/money_mover/dwolla/models/receive_only_business_customer.rb +27 -0
  24. data/lib/money_mover/dwolla/models/receive_only_customer.rb +19 -0
  25. data/lib/money_mover/dwolla/models/root_account.rb +27 -0
  26. data/lib/money_mover/dwolla/models/transfer.rb +33 -0
  27. data/lib/money_mover/dwolla/models/unverified_business_customer.rb +43 -0
  28. data/lib/money_mover/dwolla/models/unverified_customer.rb +27 -0
  29. data/lib/money_mover/dwolla/models/verified_business_customer.rb +53 -0
  30. data/lib/money_mover/dwolla/models/webhook_subscription.rb +36 -0
  31. data/lib/money_mover/dwolla/token.rb +26 -0
  32. data/lib/money_mover/dwolla.rb +44 -0
  33. data/lib/money_mover/standalone_errors.rb +12 -0
  34. data/lib/money_mover/version.rb +3 -0
  35. data/lib/money_mover.rb +15 -0
  36. data/money_mover.gemspec +27 -0
  37. data/spec/integration/money_mover/dwolla/customers/create_spec.rb +75 -0
  38. data/spec/integration/money_mover/dwolla/customers/find_spec.rb +71 -0
  39. data/spec/integration/money_mover/dwolla/customers/funding-sources/create_spec.rb +40 -0
  40. data/spec/integration/money_mover/dwolla/documents/create_spec.rb +62 -0
  41. data/spec/integration/money_mover/dwolla/funding-sources/micro-deposits/initiation_spec.rb +52 -0
  42. data/spec/integration/money_mover/dwolla/funding-sources/micro-deposits/verification_spec.rb +77 -0
  43. data/spec/integration/money_mover/dwolla/transfers/create_spec.rb +80 -0
  44. data/spec/lib/money_mover/dwolla/client_spec.rb +101 -0
  45. data/spec/lib/money_mover/dwolla/config_spec.rb +20 -0
  46. data/spec/lib/money_mover/dwolla/error_handler_spec.rb +78 -0
  47. data/spec/lib/money_mover/dwolla/funding_source_spec.rb +94 -0
  48. data/spec/lib/money_mover/dwolla/microdeposits_initiation_spec.rb +36 -0
  49. data/spec/lib/money_mover/dwolla/root_account_spec.rb +86 -0
  50. data/spec/lib/money_mover/dwolla/token_spec.rb +101 -0
  51. data/spec/lib/money_mover/dwolla/transfer_spec.rb +94 -0
  52. data/spec/lib/money_mover/dwolla/webhook_subscription_spec.rb +199 -0
  53. data/spec/spec_helper.rb +121 -0
  54. data/spec/support/dwolla_helper.rb +330 -0
  55. data/spec/support/fixtures/sample.jpg +0 -0
  56. metadata +196 -0
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::MicroDepositVerification do
4
+ let(:funding_source_token) { '9481924a-6795-4e7a-b436-a7a48a4141ca' }
5
+
6
+ describe '#save' do
7
+ context 'valid attributes' do
8
+ let(:amount1) { 0.01 }
9
+ let(:amount2) { 0.02 }
10
+
11
+ let(:attrs) {{
12
+ funding_source_id: funding_source_token,
13
+ amount1: amount1,
14
+ amount2: amount2
15
+ }}
16
+
17
+ subject { described_class.new(attrs) }
18
+
19
+ let(:create_params) {{
20
+ amount1: {
21
+ value: amount1,
22
+ currency: "USD"
23
+ },
24
+ amount2: {
25
+ value: amount2,
26
+ currency: "USD"
27
+ }
28
+ }}
29
+
30
+ before do
31
+ dwolla_helper.stub_funding_source_microdeposits_request funding_source_token, create_params, create_response
32
+ end
33
+
34
+ context 'success' do
35
+ let(:create_response) {{
36
+ status: 200,
37
+ body: ""
38
+ }}
39
+
40
+ it 'creates new resource in dwolla' do
41
+ expect(subject.save).to eq(true)
42
+ end
43
+ end
44
+
45
+ context 'fail' do
46
+ let(:create_response) { dwolla_helper.resource_create_error_response error_response }
47
+
48
+ let(:error_response) {{
49
+ code: "ValidationError",
50
+ message: "Validation error(s) present. See embedded errors list for more details.",
51
+ _embedded: {
52
+ errors: [
53
+ { code: "Invalid", message: "Invalid amount.", path: "/amount1/value" },
54
+ { code: "Invalid", message: "Invalid amount.", path: "/amount2/value" }
55
+ ]
56
+ }
57
+ }}
58
+
59
+ it 'returns errors' do
60
+ expect(subject.save).to eq(false)
61
+ expect(subject.errors[:amount1]).to eq(['Invalid amount.'])
62
+ expect(subject.errors[:amount2]).to eq(['Invalid amount.'])
63
+ end
64
+ end
65
+ end
66
+
67
+ context 'invalid attributes' do
68
+ let(:attrs) {{}}
69
+
70
+ it 'returns errors' do
71
+ expect(subject.save).to eq(false)
72
+ expect(subject.errors[:amount1]).to eq(["can't be blank", "is not a number"])
73
+ expect(subject.errors[:amount2]).to eq(["can't be blank", "is not a number"])
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::Transfer do
4
+ let(:funding_source_resource_location) { 'some-resource-location' }
5
+ let(:funding_destination_resource_location) { 'some-resource-location' }
6
+ let(:amount) { 10.0 }
7
+ let(:metadata) {{}}
8
+
9
+ #let(:attrs) {{
10
+ #funding_source_resource_location: funding_source_resource_location,
11
+ #funding_destination_resource_location: funding_destination_resource_location,
12
+ #amount: amount,
13
+ #metadata: metadata
14
+ #}}
15
+
16
+ let(:attrs) {{
17
+ sender_funding_source_token: funding_source_resource_location,
18
+ destination_funding_source_token: funding_destination_resource_location,
19
+ transfer_amount: amount,
20
+ metadata: metadata
21
+ }}
22
+
23
+ subject { described_class.new(attrs) }
24
+
25
+ let(:create_params) {{
26
+ _links: {
27
+ destination: {
28
+ href: dwolla_helper.build_dwolla_url("funding-sources/#{funding_source_resource_location}")
29
+ },
30
+ source: {
31
+ href: dwolla_helper.build_dwolla_url("funding-sources/#{funding_destination_resource_location}")
32
+ }
33
+ },
34
+ amount: {
35
+ value: amount.to_s,
36
+ currency: "USD"
37
+ },
38
+ metadata: metadata
39
+ }}
40
+
41
+ let(:resource_token) { 'some-token' }
42
+
43
+ before do
44
+ dwolla_helper.stub_create_transfer_request create_params, create_response
45
+ end
46
+
47
+ describe '#save' do
48
+ context 'success' do
49
+ let(:create_response) { dwolla_helper.transfer_created_response resource_token }
50
+
51
+ it 'creates new resource in dwolla' do
52
+ expect(subject.save).to eq(true)
53
+ expect(subject.id).to eq(resource_token)
54
+ expect(subject.resource_location).to eq(dwolla_helper.transfer_endpoint(resource_token))
55
+ end
56
+ end
57
+
58
+ context 'fail' do
59
+ let(:create_response) { dwolla_helper.resource_create_error_response error_response }
60
+
61
+ let(:error_response) {{
62
+ code: "ValidationError",
63
+ message: "Validation error(s) present. See embedded errors list for more details.",
64
+ _embedded: {
65
+ errors: [
66
+ { code: "Duplicate", message: "Invalid destination", path: "/_links/destination/href"
67
+ }
68
+ ]
69
+ }
70
+ }}
71
+
72
+ it 'returns errors' do
73
+ expect(subject.save).to eq(false)
74
+ expect(subject.errors[:_links]).to eq(['Invalid destination'])
75
+ expect(subject.id).to be_nil
76
+ expect(subject.resource_location).to be_nil
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::AccountClient do
4
+ let(:expected_response) { double 'expected response' }
5
+ let(:server_request) { double 'server request' }
6
+
7
+ let(:url_provider) { double 'url provider', api_url: api_url }
8
+ let(:api_url) { double' api url' }
9
+
10
+ subject { described_class.new }
11
+
12
+ let(:token) { double 'account token' }
13
+ let(:dwolla_token_provider) { double 'token provider', access_token: token }
14
+
15
+ let(:api_connection) { double 'api connection', connection: faraday_connection }
16
+ let(:faraday_connection) { double 'faraday connection' }
17
+
18
+ before do
19
+ allow(MoneyMover::Dwolla::ApiConnection).to receive(:new).with(token) { api_connection }
20
+ allow(MoneyMover::Dwolla::AccountToken).to receive(:new) { dwolla_token_provider }
21
+ end
22
+
23
+ let(:url) { double 'url' }
24
+ let(:params) { double 'params' }
25
+
26
+ describe '#post' do
27
+ let(:expected_response) { double 'expected response' }
28
+ let(:server_request) { double 'server request', response: expected_response }
29
+
30
+ before do
31
+ allow(faraday_connection).to receive(:post).with(url, params) { server_request }
32
+ allow(MoneyMover::Dwolla::ApiServerResponse).to receive(:new).with(server_request) { expected_response }
33
+ end
34
+
35
+ it 'returns success response' do
36
+ expect(subject.post(url, params)).to eq(expected_response)
37
+ end
38
+ end
39
+
40
+ describe '#delete' do
41
+ before do
42
+ allow(faraday_connection).to receive(:delete).with(url, params) { server_request }
43
+ allow(MoneyMover::Dwolla::ApiServerResponse).to receive(:new).with(server_request) { expected_response }
44
+ end
45
+
46
+ it 'returns SuccessResponse' do
47
+ expect(subject.delete(url, params)).to eq(expected_response)
48
+ end
49
+ end
50
+
51
+ describe '#get' do
52
+ before do
53
+ allow(faraday_connection).to receive(:get).with(url, params) { server_request }
54
+ allow(MoneyMover::Dwolla::ApiServerResponse).to receive(:new).with(server_request) { expected_response }
55
+ end
56
+
57
+ it 'returns response from token#get' do
58
+ expect(subject.get(url, params)).to eq(expected_response)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe MoneyMover::Dwolla::AccountClient do
64
+ describe '#post' do
65
+ let(:url) { '/customers' }
66
+
67
+ let(:params) {{
68
+ firstName: 'someone first name',
69
+ lastName: 'someone last name',
70
+ email: 'email@example.com',
71
+ businessName: 'some company name',
72
+ type: 'receive-only'
73
+ }}
74
+
75
+ before do
76
+ dwolla_helper.stub_create_customer_request(params, create_response)
77
+ end
78
+
79
+ context 'success' do
80
+ let(:create_response) { dwolla_helper.create_customer_success_response(customer_token) }
81
+ let(:customer_token) { 'some-customer-token' }
82
+
83
+ it 'returns success response' do
84
+ response = subject.post(url, params)
85
+ expect(response.resource_id).to eq(customer_token)
86
+ expect(response.resource_location).to eq(dwolla_helper.customer_url(customer_token))
87
+ end
88
+ end
89
+
90
+ context 'error' do
91
+ let(:create_response) {
92
+ dwolla_helper.error_response :code=>"ValidationError", :message=>"Validation error(s) present. See embedded errors list for more details.", :_embedded=>{:errors=>[{:code=>"Duplicate", :message=>"A customer with the specified email already exists.", :path=>"/email"}]}
93
+ }
94
+
95
+ it 'returns error response' do
96
+ response = subject.post(url, params)
97
+ expect(response.errors[:email]).to eq(['A customer with the specified email already exists.'])
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::Config do
4
+ let(:webhook_secret_key) { double 'webhook secret key' }
5
+ let(:webhook_callback_url) { double 'webhook callback url' }
6
+ let(:api_key) { double 'api key' }
7
+ let(:api_secret_key) { double 'api secret key' }
8
+ let(:environment) { double 'environment' }
9
+ let(:ach_provider_config) { double 'configatron ach provider store', webhook_secret_key: webhook_secret_key, webhook_callback_url: webhook_callback_url, api_key: api_key, api_secret_key: api_secret_key, environment: environment }
10
+
11
+ subject { described_class.new(ach_provider_config) }
12
+
13
+ it 'returns expected values' do
14
+ expect(subject.webhook_secret_key).to eq(webhook_secret_key)
15
+ expect(subject.webhook_callback_url).to eq(webhook_callback_url)
16
+ expect(subject.api_key).to eq(api_key)
17
+ expect(subject.api_secret_key).to eq(api_secret_key)
18
+ expect(subject.environment).to eq(environment)
19
+ end
20
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::ErrorHandler do
4
+ subject { described_class.new(server_error) }
5
+
6
+ describe '#errors' do
7
+ context 'no embedded errors' do
8
+ let(:server_error) {{
9
+ code: "DuplicateResource",
10
+ message: "Bank already exists: id=442efd3e-3f70-4cb1-a393-593dca3464b4",
11
+ _embedded: nil
12
+ }}
13
+
14
+ it 'sets error correctly' do
15
+ expect(subject.errors[:base]).to eq(["Bank already exists: id=442efd3e-3f70-4cb1-a393-593dca3464b4"])
16
+ end
17
+ end
18
+
19
+ context 'json pointer path is /routingNumber' do
20
+ let(:server_error) {{
21
+ code: "ValidationError",
22
+ message: "Validation error(s) present. See embedded errors list for more details.",
23
+ _embedded: {
24
+ errors: [
25
+ {
26
+ :code=>"Invalid",
27
+ :message=>"Invalid parameter.",
28
+ :path=>"/routingNumber"
29
+ }
30
+ ]
31
+ }
32
+ }}
33
+
34
+ it 'sets error correctly' do
35
+ expect(subject.errors[:routingNumber]).to eq(["Invalid parameter."])
36
+ end
37
+ end
38
+
39
+ context 'json pointer path is /amount2/value' do
40
+ let(:server_error) {{
41
+ code: "ValidationError",
42
+ message: "Validation error(s) present. See embedded errors list for more details.",
43
+ _embedded: {
44
+ errors: [
45
+ {
46
+ code: "Invalid",
47
+ message: "Invalid amount.",
48
+ path: "/amount2/value"
49
+ }
50
+ ]
51
+ }
52
+ }}
53
+
54
+ it 'sets error correctly' do
55
+ expect(subject.errors[:amount2]).to eq(["Invalid amount."])
56
+ end
57
+ end
58
+
59
+ context 'json pointer path is empty' do
60
+ let(:server_error) {{
61
+ code: "ValidationError",
62
+ message: "Validation error(s) present. See embedded errors list for more details.",
63
+ _embedded: {
64
+ errors: [
65
+ {
66
+ code: "Invalid",
67
+ message: "Invalid amount."
68
+ }
69
+ ]
70
+ }
71
+ }}
72
+
73
+ it 'sets error correctly' do
74
+ expect(subject.errors[:base]).to eq(["Invalid amount."])
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::FundingSource do
4
+ let(:customer_id) { double 'customer id' }
5
+
6
+ let(:name) { 'some name' }
7
+ let(:type) { 'checking' }
8
+ let(:routingNumber) { 'routing number' }
9
+ let(:accountNumber) { 'account number' }
10
+
11
+ let(:attrs) {{
12
+ name: name,
13
+ type: type,
14
+ routingNumber: routingNumber,
15
+ accountNumber: accountNumber
16
+ }}
17
+
18
+ subject { described_class.new customer_id, attrs }
19
+
20
+ let(:dwolla_client) { double 'dwolla client' }
21
+
22
+ let(:dwolla_response) { double 'dwolla response', success?: save_success?, resource_location: resource_location, resource_id: resource_id, errors: dwolla_errors }
23
+ let(:dwolla_errors) { [ ['key1', 'error1'], ['key2', 'error2'] ] }
24
+
25
+ let(:resource_location) { double 'resource location' }
26
+ let(:resource_id) { double 'resource id' }
27
+
28
+ before do
29
+ allow(MoneyMover::Dwolla::AccountClient).to receive(:new) { dwolla_client }
30
+ end
31
+
32
+ it { should validate_presence_of(:name) }
33
+ it { should validate_presence_of(:type) }
34
+ it { should validate_presence_of(:routingNumber) }
35
+ it { should validate_presence_of(:accountNumber) }
36
+
37
+ describe '#save' do
38
+ let(:save_success?) { true }
39
+
40
+ let(:create_params) {{
41
+ name: name,
42
+ type: type,
43
+ routingNumber: routingNumber,
44
+ accountNumber: accountNumber
45
+ }}
46
+
47
+ let(:create_endpoint) { "/customers/#{customer_id}/funding-sources" }
48
+
49
+ context 'success' do
50
+ let(:save_success?) { true }
51
+
52
+ it 'returns true and sets resource_location and id' do
53
+ expect(dwolla_client).to receive(:post).with(create_endpoint, create_params) { dwolla_response }
54
+
55
+ expect(subject.save).to eq(true)
56
+
57
+ expect(subject.errors).to be_empty
58
+ expect(subject.resource_location).to eq(resource_location)
59
+ expect(subject.id).to eq(resource_id)
60
+ end
61
+ end
62
+
63
+ context 'validations fail' do
64
+ let(:name) { nil }
65
+ let(:type) { nil }
66
+ let(:routingNumber) { nil }
67
+ let(:accountNumber) { nil }
68
+
69
+ it 'does not attempt to create transfer and returns false with errors' do
70
+ expect(dwolla_client).to_not receive(:post)
71
+
72
+ expect(subject.save).to eq(false)
73
+
74
+ expect(subject.errors[:name]).to eq(["can't be blank"])
75
+ expect(subject.errors[:type]).to eq(["can't be blank", "is not included in the list"])
76
+ expect(subject.errors[:routingNumber]).to eq(["can't be blank"])
77
+ expect(subject.errors[:accountNumber]).to eq(["can't be blank"])
78
+ end
79
+ end
80
+
81
+ context 'dwolla error' do
82
+ let(:save_success?) { false }
83
+
84
+ it 'returns false and has errors' do
85
+ expect(dwolla_client).to receive(:post).with(create_endpoint, create_params) { dwolla_response }
86
+
87
+ expect(subject.save).to eq(false)
88
+
89
+ expect(subject.errors[:key1]).to eq(['error1'])
90
+ expect(subject.errors[:key2]).to eq(['error2'])
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::MicroDepositInitiation do
4
+ let(:response_errors) { { key1: 'Error1', key2: 'Error2' } }
5
+ let(:ach_response) { double 'ach response', success?: response_success?, resource_location: resource_location, resource_id: resource_id, errors: response_errors}
6
+ let(:resource_location) { double 'resource location' }
7
+ let(:resource_id) { double 'resource id' }
8
+ let(:ach_client) { double 'Dwolla Client', post: ach_response }
9
+
10
+ let(:funding_source_id) { 'some_funding_source_id_token' }
11
+
12
+ subject { described_class.new(funding_source_id: funding_source_id) }
13
+
14
+ before do
15
+ allow(MoneyMover::Dwolla::AccountClient).to receive(:new) { ach_client }
16
+ end
17
+
18
+ context 'success' do
19
+ let(:response_success?) { true }
20
+
21
+ it 'posts to ach provider and returns true' do
22
+ expect(ach_client).to receive(:post).with("/funding-sources/#{funding_source_id}/micro-deposits", {})
23
+ expect(subject.save).to eq(true)
24
+ end
25
+ end
26
+
27
+ context 'ach failure' do
28
+ let(:response_success?) { false }
29
+
30
+ it 'posts to ach provider and returns false and has errors' do
31
+ expect(ach_client).to receive(:post).with("/funding-sources/#{funding_source_id}/micro-deposits", {})
32
+ expect(subject.save).to eq(false)
33
+ expect(subject.errors.to_a).to eq(["Key1 Error1", "Key2 Error2"])
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::RootAccount do
4
+ let(:client) { double 'dwolla account client' }
5
+ let(:account_token) { "account_token_value" }
6
+ let(:bank_funding_source_token) { "bank_funding_source_token_value" }
7
+
8
+ let(:account_response) { double 'account response', success?: account_success?, body: account_response_body }
9
+ let(:account_success?) { true }
10
+
11
+ let(:account_response_body) do
12
+ {
13
+ :_links=>{
14
+ :account=>{
15
+ :href=>"https://api-uat.dwolla.com/accounts/#{account_token}"
16
+ },
17
+ :customers=>{:href=>"https://api-uat.dwolla.com/customers"}
18
+ }
19
+ }
20
+ end
21
+
22
+ let(:funding_response) { double 'funding response', body: funding_response_body }
23
+
24
+ let(:funding_response_body) do
25
+ {
26
+ :_links=>{
27
+ :self=>{
28
+ :href=>"https://api-uat.dwolla.com/accounts/#{account_token}/funding-sources"
29
+ }
30
+ },
31
+ :_embedded=>{
32
+ :"funding-sources"=>[
33
+ {
34
+ :_links=>{
35
+ :self=>{
36
+ :href=>"https://api-uat.dwolla.com/funding-sources/#{bank_funding_source_token}"
37
+ },
38
+ :account=>{
39
+ :href=>"https://api-uat.dwolla.com/accounts/#{account_token}"
40
+ }
41
+ },
42
+ :id=>bank_funding_source_token,
43
+ :status=>"verified",
44
+ :type=>"bank",
45
+ :name=>"Superhero Savings Bank",
46
+ :created=>'2016-03-08 17:43:43 UTC'
47
+ },
48
+ {
49
+ :_links=>{
50
+ :self=>{
51
+ :href=>"https://api-uat.dwolla.com/funding-sources/90fa0eff-8ea0-4cab-89eb-72a1f5d93c13"
52
+ },
53
+ :account=>{
54
+ :href=>"https://api-uat.dwolla.com/accounts/#{account_token}"
55
+ },
56
+ :"with-available-balance"=>{
57
+ :href=>"https://api-uat.dwolla.com/funding-sources/90fa0eff-8ea0-4cab-89eb-72a1f5d93c13"
58
+ }
59
+ },
60
+ :id=>"90fa0eff-8ea0-4cab-89eb-72a1f5d93c13",
61
+ :status=>"verified",
62
+ :type=>"balance",
63
+ :name=>"Balance",
64
+ :created=>'2016-03-08 17:43:42 UTC'
65
+ }
66
+ ]
67
+ }
68
+ }
69
+ end
70
+
71
+ before do
72
+ allow(MoneyMover::Dwolla::AccountClient).to receive(:new) { client }
73
+ allow(client).to receive(:get).with('/') { account_response }
74
+ allow(client).to receive(:get).with("/accounts/#{account_token}/funding-sources") { funding_response }
75
+ end
76
+
77
+ describe '.fetch' do
78
+ subject { described_class }
79
+
80
+ it 'returns expected token hash' do
81
+ account = subject.fetch
82
+ expect(account.account_resource_id).to eq(account_token)
83
+ expect(account.bank_account_funding_source.id).to eq(bank_funding_source_token)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::AccountToken do
4
+ let(:ach_config) { double 'ach config', api_key: ach_config_api_key, api_secret_key: ach_config_api_secret_key, environment: ach_config_environment, account_token_provider: account_token_provider }
5
+ let(:ach_config_api_key) { double 'ach config api key' }
6
+ let(:ach_config_api_secret_key) { double 'ach config api secret' }
7
+ let(:ach_config_environment) { double 'ach config environment' }
8
+ let(:account_token_provider) { double 'account token provider', access_token: account_access_token, refresh_token: account_refresh_token }
9
+ let(:account_access_token) { double 'account access token' }
10
+ let(:account_refresh_token) { double 'account refresh token' }
11
+
12
+ let(:attrs) {{}}
13
+
14
+ subject { described_class.new attrs, ach_config }
15
+
16
+ describe '#access_token' do
17
+ it 'returns account token from account token provider' do
18
+ expect(subject.access_token).to eq(account_access_token)
19
+ end
20
+ end
21
+
22
+ describe '#refresh_token' do
23
+ it 'returns account token from account token provider' do
24
+ expect(subject.refresh_token).to eq(account_refresh_token)
25
+ end
26
+ end
27
+ end
28
+
29
+ # INTEGRATION TEST
30
+ describe MoneyMover::Dwolla::AccountToken do
31
+ let(:invalid_refresh_token_response) {{
32
+ "error": "access_denied",
33
+ "error_description": "Invalid refresh token."
34
+ }}
35
+
36
+ let(:expired_refresh_token_error) {{
37
+ "error": "access_denied",
38
+ "error_description": "Expired refresh token."
39
+ }}
40
+
41
+ let(:refresh_token_request_params) {{
42
+ "client_id": "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
43
+ "client_secret": "g7QLwvO37aN2HoKx1amekWi8a2g7AIuPbD5C/JSLqXIcDOxfTr",
44
+ "refresh_token": "Pgk+l9okjwTCfsvIvEDPrsomE1er1txeyoaAkTIBAuXza8WvZY",
45
+ "grant_type": "refresh_token"
46
+ }}
47
+
48
+ #let(:refresh_token_success_response) {{
49
+ #"_links": {
50
+ #"account": {
51
+ #"href": "https://api-uat.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
52
+ #}
53
+ #},
54
+ #"access_token": "F3jK4rg7FGlq4yRQ7vWECoXVD4zQq9Xg26VnxzMbHGusZqr7dF",
55
+ #"expires_in": 3600,
56
+ #"refresh_token": "DRlqGJ0IFsRK8xzjkKhjTOgz3meet6E91T2oacGCefHGU4h1hj",
57
+ #"refresh_expires_in": 5184000,
58
+ #"token_type": "bearer",
59
+ #"scope": "send|transactions|funding|managecustomers",
60
+ #"account_id": "ca32853c-48fa-40be-ae75-77b37504581b"
61
+ #}}
62
+
63
+
64
+ let(:account_id) { "7da912eb-5976-4e5c-b5ab-a5df35ac661b" }
65
+ let(:new_access_token) { "oNGSeXqucdVxTLAwSRNc1WjG5BTHWNS5z7hccJGUTGvCXusmbC" }
66
+ let(:new_refresh_token) { "Et380Ps1y9tyiW3A8yf0ws1lbfGUVXl5DLIHfDDELXC0ls7hie" }
67
+
68
+ let(:refresh_token_success_response) {{
69
+ "_links": {
70
+ "account": {
71
+ "href":"https://api-uat.dwolla.com/accounts/#{account_id}"
72
+ }
73
+ },
74
+ "access_token": new_access_token,
75
+ "expires_in":3600,
76
+ "refresh_token": new_refresh_token,
77
+ "refresh_expires_in":5184000,
78
+ "token_type":"bearer",
79
+ "scope":"accountinfofull|contacts|transactions|balance|send|request|funding|manageaccount|scheduled|email|managecustomers",
80
+ "account_id": account_id
81
+ }}
82
+
83
+ describe '#request_new_token!' do
84
+ let(:token_response) { refresh_token_success_response }
85
+
86
+ before do
87
+ dwolla_helper.stub_refresh_token_request(token_response)
88
+ end
89
+
90
+ context 'success' do
91
+ it 'updates tokens in db' do
92
+ new_token = subject.request_new_token!
93
+
94
+ expect(new_token.account_id).to eq(account_id)
95
+ expect(new_token.expires_in).to eq(3600)
96
+ expect(new_token.access_token).to eq(new_access_token)
97
+ expect(new_token.refresh_token).to eq(new_refresh_token)
98
+ end
99
+ end
100
+ end
101
+ end