basecomm_sdk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +94 -0
  5. data/CHANGELOG +3 -0
  6. data/Gemfile +4 -0
  7. data/Guardfile +26 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +102 -0
  10. data/Rakefile +14 -0
  11. data/basecomm_sdk.gemspec +40 -0
  12. data/lib/basecomm_sdk/address.rb +25 -0
  13. data/lib/basecomm_sdk/bank_account.rb +29 -0
  14. data/lib/basecomm_sdk/bank_account_transaction.rb +48 -0
  15. data/lib/basecomm_sdk/bank_card.rb +26 -0
  16. data/lib/basecomm_sdk/bank_card_transaction.rb +52 -0
  17. data/lib/basecomm_sdk/base.rb +91 -0
  18. data/lib/basecomm_sdk/client.rb +151 -0
  19. data/lib/basecomm_sdk/push_notification.rb +22 -0
  20. data/lib/basecomm_sdk/settlement_batch.rb +18 -0
  21. data/lib/basecomm_sdk/triple_des_service.rb +36 -0
  22. data/lib/basecomm_sdk/version.rb +3 -0
  23. data/lib/basecomm_sdk.rb +31 -0
  24. data/spec/cassettes/BasecommSdk_Client/_add_bank_account/fails_when_passing_an_invalid_bank_account.yml +34 -0
  25. data/spec/cassettes/BasecommSdk_Client/_add_bank_account/returns_the_new_bank_account_instance.yml +34 -0
  26. data/spec/cassettes/BasecommSdk_Client/_add_bank_card/fails_when_passing_an_invalid_bank_card.yml +34 -0
  27. data/spec/cassettes/BasecommSdk_Client/_add_bank_card/returns_a_valid_new_bank_card_instance.yml +34 -0
  28. data/spec/cassettes/BasecommSdk_Client/_get_bank_account_transaction/fails_when_passing_invalid_bat_transaction.yml +34 -0
  29. data/spec/cassettes/BasecommSdk_Client/_get_bank_account_transaction/fails_when_passing_invalid_transaction.yml +34 -0
  30. data/spec/cassettes/BasecommSdk_Client/_get_bank_account_transaction/returns_the_specified_bank_account_transaction.yml +34 -0
  31. data/spec/cassettes/BasecommSdk_Client/_get_bank_card_transaction/collects_proper_responses_for_missing_transactions.yml +34 -0
  32. data/spec/cassettes/BasecommSdk_Client/_get_bank_card_transaction/returns_the_specified_bank_card_transaction.yml +34 -0
  33. data/spec/cassettes/BasecommSdk_Client/_process_bank_account_transaction/fails_when_passing_invalid_transaction.yml +34 -0
  34. data/spec/cassettes/BasecommSdk_Client/_process_bank_account_transaction/populates_messages_with_failure_reasons.yml +34 -0
  35. data/spec/cassettes/BasecommSdk_Client/_process_bank_account_transaction/returns_the_processed_bank_account_transaction.yml +34 -0
  36. data/spec/cassettes/BasecommSdk_Client/_process_bank_card_transaction/returns_the_processed_bank_account_transaction_for_auth.yml +34 -0
  37. data/spec/factories.rb +95 -0
  38. data/spec/lib/basecomm_sdk/address_spec.rb +53 -0
  39. data/spec/lib/basecomm_sdk/bank_account_spec.rb +53 -0
  40. data/spec/lib/basecomm_sdk/bank_account_transaction_spec.rb +60 -0
  41. data/spec/lib/basecomm_sdk/bank_card_spec.rb +55 -0
  42. data/spec/lib/basecomm_sdk/bank_card_transaction_spec.rb +55 -0
  43. data/spec/lib/basecomm_sdk/base_spec.rb +7 -0
  44. data/spec/lib/basecomm_sdk/client_spec.rb +204 -0
  45. data/spec/lib/basecomm_sdk/push_notification_spec.rb +14 -0
  46. data/spec/lib/basecomm_sdk/settlement_batch_spec.rb +14 -0
  47. data/spec/lib/basecomm_sdk/triple_des_service_spec.rb +39 -0
  48. data/spec/lib/basecomm_sdk_spec.rb +17 -0
  49. data/spec/spec_helper.rb +56 -0
  50. data/spec/support/shared_class_with_messages.rb +7 -0
  51. metadata +374 -0
@@ -0,0 +1,204 @@
1
+ require 'spec_helper'
2
+
3
+ module BasecommSdk
4
+ describe Client, type: :lib do
5
+
6
+ let(:config) do
7
+ {
8
+ gateway_username: ENV['BASECOMM_UID'],
9
+ gateway_password: ENV['BASECOMM_PWD'],
10
+ key: ENV['BASECOMM_KEY'],
11
+ sandbox: true
12
+ }
13
+ end
14
+ let(:instance) { Client.new(config) }
15
+
16
+ context '.initialize' do
17
+ let(:config) do
18
+ {
19
+ gateway_username: 'GATEWAY_USERNAME',
20
+ gateway_password: 'GATEWAY_PASSWORD',
21
+ key: 'GATEWAY_KEY',
22
+ sandbox: true
23
+ }
24
+ end
25
+ it 'accepts config settings from options' do
26
+ expect(instance.gateway_username).to eq('GATEWAY_USERNAME')
27
+ expect(instance.gateway_password).to eq('GATEWAY_PASSWORD')
28
+ expect(instance.key).to eq('GATEWAY_KEY')
29
+ expect(instance.sandbox).to eq(true)
30
+ end
31
+
32
+ it 'defaults the base url' do
33
+ config.merge!(sandbox: false)
34
+ expect(instance.url).to eq('https://gateway.basecommerce.com')
35
+ end
36
+
37
+ it 'defaults the sandbox url' do
38
+ expect(instance.url).to eq('https://gateway.basecommercesandbox.com')
39
+ end
40
+
41
+ it 'accepts a url from options' do
42
+ url = 'http://example.com'
43
+ config.merge!(url: url)
44
+ expect(instance.url).to eq(url)
45
+ end
46
+ end
47
+
48
+ # We normally don't test private methods but this is an exception
49
+ context '.api_endpoint' do
50
+ it 'returns the proper endpoint based on the method name given' do
51
+ endpoint = instance.send(:api_endpoint, :add_bank_account)
52
+ expect(endpoint).to match(/API_addBankAccount/)
53
+ end
54
+ end
55
+
56
+ context '.add_bank_account', :vcr do
57
+ it 'returns the new bank account instance' do
58
+ bank_account = create(:bank_account)
59
+ returned_bank_account = instance.add_bank_account(bank_account)
60
+ expect(returned_bank_account).to be_a(BankAccount)
61
+ expect(returned_bank_account.name).to eq(bank_account.name)
62
+ expect(
63
+ returned_bank_account.routing_number
64
+ ).to eq(bank_account.routing_number)
65
+ end
66
+
67
+ it 'fails when passing an invalid bank account' do
68
+ bank_account = create(:bank_account, account_number: nil)
69
+ returned_bank_account = instance.add_bank_account(bank_account)
70
+ expect(
71
+ returned_bank_account.status[:bank_account_status_name]
72
+ ).to eq('FAILED')
73
+ end
74
+ end
75
+
76
+ context '.add_bank_card', :vcr do
77
+ it 'returns a valid new bank card instance' do
78
+ bank_card = create(:bank_card)
79
+ last_4 = bank_card.number.split(//).last(4).join
80
+ returned_bank_card = instance.add_bank_card(bank_card)
81
+ expect(returned_bank_card).to be_a(BankCard)
82
+ expect(returned_bank_card.alias).to match(/ending in #{last_4}/)
83
+ expect(returned_bank_card.name).to eq(bank_card.name)
84
+ expect(returned_bank_card.token.nil?).to eq(false)
85
+ expect(returned_bank_card.creation_date.nil?).to eq(false)
86
+ expect(returned_bank_card.last_used_date.nil?).to eq(false)
87
+ expect(
88
+ returned_bank_card.status[:bank_card_status_name]
89
+ ).to eq('ACTIVE')
90
+ expect(
91
+ returned_bank_card.expiration_year
92
+ ).to eq(bank_card.expiration_year)
93
+ expect(
94
+ returned_bank_card.expiration_month
95
+ ).to eq(bank_card.expiration_month)
96
+ end
97
+
98
+ it 'fails when passing an invalid bank card' do
99
+ bank_card = create(:bank_card, number: nil)
100
+ returned_bank_card = instance.add_bank_card(bank_card)
101
+ expect(
102
+ returned_bank_card.status[:bank_card_status_name]
103
+ ).to eq('FAILED')
104
+ end
105
+ end
106
+
107
+ context '.get_bank_account_transaction', :vcr do
108
+ it 'returns the specified bank account transaction' do
109
+ bat = instance.get_bank_account_transaction(24_571)
110
+ expect(bat.id).to eq(24_571)
111
+ expect(bat.trace).to eq('11100002566271')
112
+ expect(bat.account_name).to eq('test account')
113
+ expect(
114
+ bat.status[:bank_account_transaction_status_name]
115
+ ).to eq('SETTLED')
116
+ end
117
+
118
+ it 'fails when passing invalid bat transaction' do
119
+ bat = instance.get_bank_account_transaction(99_999)
120
+ expect(bat.status_name).to eq('FAILED')
121
+ expect(
122
+ bat.status[:bank_account_transaction_status_name]
123
+ ).to eq('FAILED')
124
+ end
125
+ end
126
+
127
+ context '.get_bank_card_transaction' do
128
+ it 'returns the specified bank card transaction', :vcr do
129
+ bct = instance.get_bank_card_transaction(65_473)
130
+ expect(bct).to be_a(BankCardTransaction)
131
+ expect(bct.amount).to eq(60)
132
+ expect(bct.authorization_code).to eq('159721')
133
+ expect(bct.card_number).to eq('4***********1111')
134
+ end
135
+
136
+ it 'collects proper responses for missing transactions', :vcr do
137
+ bct = instance.get_bank_card_transaction(99_999)
138
+ expect(bct.card_number).to eq('NO CARD NUMBER')
139
+ expect(bct.response_code).to eq('9000')
140
+ expect(bct.response_message).to eq('Validation Error')
141
+ expect(bct.status_name).to eq('FAILED')
142
+ expect(
143
+ bct.status[:bank_card_transaction_status_name]
144
+ ).to eq('FAILED')
145
+ end
146
+ end
147
+
148
+ context '.process_bank_account_transaction' do
149
+ it 'returns the processed bank account transaction', :vcr do
150
+ bat = create(:bank_account_transaction, :checking, :debit, :ccd)
151
+ returned_bat = instance.process_bank_account_transaction(bat)
152
+ expect(returned_bat.status_name).to eq('CREATED')
153
+ expect(
154
+ returned_bat.status[:bank_account_transaction_status_name]
155
+ ).to eq('CREATED')
156
+ end
157
+
158
+ it 'fails when passing invalid transaction', :vcr do
159
+ bat = create(:bank_account_transaction, :checking, :debit)
160
+ returned_bat = instance.process_bank_account_transaction(bat)
161
+ expect(returned_bat.status_name).to eq('FAILED')
162
+ expect(
163
+ returned_bat.status[:bank_account_transaction_status_name]
164
+ ).to eq('FAILED')
165
+ end
166
+
167
+ it 'populates @messages with failure reasons', :vcr do
168
+ bat = create(:bank_account_transaction, :checking, account_number: nil)
169
+ returned_bat = instance.process_bank_account_transaction(bat)
170
+ expect(returned_bat.messages.empty?).to eq(false)
171
+ expect(returned_bat.messages.count).to eq(3)
172
+ binding.pry
173
+ end
174
+ end
175
+
176
+ context '.process_bank_card_transaction' do
177
+ it 'returns the processed bank account transaction for auth', :vcr do
178
+ bct = create(:bank_card_transaction, :auth)
179
+ returned_bct = instance.process_bank_card_transaction(bct)
180
+ expect(returned_bct.status_name).to eq('AUTHORIZED')
181
+ expect(
182
+ returned_bct.status[:bank_card_transaction_status_name]
183
+ ).to eq('AUTHORIZED')
184
+ end
185
+
186
+ # it 'returns the processed bank account transaction for capture', focus:true do
187
+ # bct = create(:bank_card_transaction, :capture)
188
+ # returned_bct = instance.process_bank_card_transaction(bct)
189
+ # expect(
190
+ # returned_bct.status[:bank_card_transaction_status_name]
191
+ # ).to eq('FAILED')
192
+ # end
193
+
194
+ # it 'fails when passing invalid transaction' do
195
+ # bct = create(:bank_card_transaction)
196
+ # returned_bct = instance.process_bank_card_transaction(bct)
197
+ # expect(
198
+ # returned_bct.status[:bank_card_transaction_status_name]
199
+ # ).to eq('FAILED')
200
+ # end
201
+ end
202
+
203
+ end
204
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ module BasecommSdk
4
+ RSpec.describe PushNotification, type: :lib do
5
+
6
+ context '.json_prefix' do
7
+ it 'returns snake-cased class name as a symbol' do
8
+ instance = PushNotification.new
9
+ expect(instance.json_prefix).to eq(:push_notification)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ module BasecommSdk
4
+ RSpec.describe SettlementBatch, type: :lib do
5
+
6
+ context '.json_prefix' do
7
+ it 'returns snake-cased class name as a symbol' do
8
+ instance = SettlementBatch.new
9
+ expect(instance.json_prefix).to eq(:settlement_batch)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ # rubocop:disable Metrics/LineLength
4
+ module BasecommSdk
5
+ describe TripleDesService, type: :lib do
6
+
7
+ let(:instance) { TripleDesService.new(ENV['BASECOMM_KEY']) }
8
+ let(:decrypted_data) { '{"name":"We are great!","type":"the_best"}' }
9
+ let(:encrypted_data) do
10
+ '5ebd0e6d9053db8a4b073c42994015a947623672ad014885b8dcba1c92400a064e30aa86ff1b4bed184cc25396c7f69e'
11
+ end
12
+ let(:encrypted_response) do
13
+ 'dcd2610ecb6336d5f7f8842ebf6ce01b2d54b8865ecd0b34a87ad4a963370b1f8ba8a0e3f6b9cfad6cae6602d7a6fb20ba1176219862c5258bef0b21fb550a02938c5b42d5e9073393334a83eb415fc5d8a7c35127b2add4b3b8b78c95cc7c955e42cefc90140b8e32738f12c9aeb8eb8236fb3f134a8032408c2b5df973b6a788fb1409340d7ab9a249eaa2fa0100cb2bf07a76743e9eeba2c8d2f67855c4ce6e62abc0e152bed3e2839b4b09861e41faf90fff70ab702703aa68bf5714efcdbc041c007f3ca9d7f7f8842ebf6ce01b2d54b8865ecd0b3422a7de029ddbb81cdd06ebe87b6d27e448e16bc585b5056116daeeaf89c9ead5997b8362aa473fff1f72a5209e2fc2db9c6a69e9509ff7780741949de029e33c0144d126cdca682f21d5aa796463734dc7113673c42fb0cb8ba8a0e3f6b9cfad6cae6602d7a6fb2028b24f1673a5a5baa8badd095a00f38b58d3a9b4155b308dbcee41ca8ec8807a50c00d49eafa3e318167688c7267654d62c480fe18d94f89694a6f5c44aab09e2d3f8fc47ee08eba7c6ee8935ea67db47716e11cbbb9c1ec0f7151b028c5bcbff0afd44a6b2104a70470dd38e26f4d419c6a69e9509ff7785e4d15bfb391a30f2d3f8fc47ee08eba7c6ee8935ea67db47716e11cbbb9c1ec7754678df828b54fb0edfbc72739e2adbc041c007f3ca9d7f7f8842ebf6ce01b2d54b8865ecd0b34fcf749ebadd3f2b223d95300c4fb76dc9fcc8a57955f201427d9ebcfec50045e2d3f8fc47ee08eba7c6ee8935ea67db4ae2dd9f8c9a8be995e5e91be2f9ea2680ebed60cf428491db3b8b78c95cc7c955e42cefc90140b8e4ab4452d22bdd713f51173e6e3cdb7f64ef6167467f14023f388522ac185b89d28fce4d01c9773a447de6b52cf885b6468417f14a69df07f2d3f8fc47ee08eba7c6ee8935ea67db4ae2dd9f8c9a8be995e5e91be2f9ea2687754678df828b54fe44fc1deb7236dd2594cdb0f9e0a8a39b3b8b78c95cc7c955e42cefc90140b8e37b2e4b8d621f497ddd6473698e69e5700c2fe8d01e3d5ef3c3e0715177e0c364a923c76e2fc1f5f961d4cc1175fe0e3c0e9c858acc5a9e8daa22a8f708fa2d791d27c3d53734a969c6a69e9509ff7785e4d15bfb391a30f2d3f8fc47ee08eba7c6ee8935ea67db44c63f27bfd73cba0cebdcb1fdff27e20ed988ef219558eaab2cfd0aeeea9102f8ba8a0e3f6b9cfad6cae6602d7a6fb202ccd1e32e63a2df97f09ec6a5949a6e158d3a9b4155b308de2693e7edafca9202db4d1a0843e106a2d3f8fc47ee08eba7c6ee8935ea67db4e897d931bfef5d725974a7113cbfe868938c5b42d5e9073393334a83eb415fc5d8a7c35127b2add4b3b8b78c95cc7c955e42cefc90140b8edb8c66cd64e69dd90bd2395739e667c31b7eadf715e7e6b2bad9bcdc1a4497e8997b8362aa473fff1f72a5209e2fc2db9c6a69e9509ff778f96429ab428b1342694a6f5c44aab09e2d3f8fc47ee08eba7c6ee8935ea67db48791fc124a7ca2571e2c1baa493a31fe64a8c294f95dcb060bdb7aa9d66bb9ec594c5f7c6705e94788fb1409340d7ab9a249eaa2fa0100cb2bf07a76743e9eebfe97fbd611055583c68921a5a57383b7a54d96b45937e84bb3b8b78c95cc7c955e42cefc90140b8e0adc60f15d504f5d9731cdd0318e57f52d54b8865ecd0b342cff0e3117b8a08fbcee41ca8ec8807a50c00d49eafa3e318167688c7267654d870126b3670a3cc3d0107f33c7a2f5a9c58a3eac2c0c27c22d5f696a4a43d4bf8a446f91145e3fff'
14
+ end
15
+ let(:decrypted_response) do
16
+ '{"bank_account_transaction":{"bank_account_transaction_creation_date":1417621559000,"bank_account_transaction_return_code":"","bank_account_transaction_id":24571,"merchant_organization_id":351,"bank_account_transaction_account_name":"test account","bank_account_transaction_amount":10,"device_id":232,"bank_account_transaction_account_number":"","bank_account_transaction_type":{"bank_account_transaction_type_description":"Debit Transaction","bank_account_transaction_type_name":"DEBIT"},"bank_account_transaction_trace":"11100002566271","bank_account_transaction_account_type":{"bank_account_transaction_account_type_description":"Checking Account","bank_account_transaction_account_type_name":"CHECKING"},"bank_account_transaction_status":{"bank_account_transaction_status_description":"Settled Transaction","bank_account_transaction_status_name":"SETTLED"},"bank_account_transaction_routing_number":"111000025","bank_account_transaction_settlement_date":1417621559000,"bank_account_transaction_settlement_batch_id":6627,"bank_account_transaction_method":{"bank_account_transaction_method_description":"ccd method","bank_account_transaction_method_name":"CCD"},"bank_account_transaction_merchant_transaction_id":"","bank_account_transaction_effective_date":1417621559000}}'
17
+ end
18
+
19
+ context '.initialize' do
20
+ it 'accepts and exposes encoded key' do
21
+ expect(instance.key).to eq(ENV['BASECOMM_KEY'])
22
+ end
23
+ end
24
+
25
+ context '.encrypt' do
26
+ it 'returns the encrypted plaintext' do
27
+ expect(instance.encrypt(decrypted_data)).to eq(encrypted_data)
28
+ end
29
+ end
30
+
31
+ context '.decrypt' do
32
+ it 'decrypts the real response' do
33
+ expect(instance.decrypt(encrypted_response)).to eq(decrypted_response)
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ # rubocop:enable Metrics/LineLength
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe BasecommSdk, type: :lib do
4
+
5
+ context '#root' do
6
+ it 'returns a Pathname instance' do
7
+ expect(BasecommSdk.root).to be_a(Pathname)
8
+ end
9
+
10
+ it 'returns the root directory' do
11
+ dir = BasecommSdk.root
12
+ expect(dir.to_s).to match(/basecomm_sdk$/)
13
+ expect(File.exist?(BasecommSdk.root)).to eq(true)
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,56 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ if ENV['COVERAGE']
4
+ require 'simplecov'
5
+ unless SimpleCov.adapters.include? :virtual_bank
6
+ SimpleCov.adapters.define 'basecomm_sdk' do
7
+ add_filter 'stubs'
8
+ add_filter 'tmp'
9
+ add_filter 'vendor'
10
+ add_filter 'spec/factories.rb'
11
+ end
12
+ end
13
+ SimpleCov.start 'basecomm_sdk'
14
+ end
15
+
16
+ require 'dotenv'
17
+ Dotenv.load
18
+
19
+ require 'pry'
20
+ require 'basecomm_sdk'
21
+
22
+ # load rspec support
23
+ root = File.expand_path('../', File.dirname(__FILE__))
24
+ Dir[File.join(root, 'spec/support/**/*.rb')].each { |f| require f }
25
+
26
+ require 'vcr'
27
+ VCR.configure do |c|
28
+ c.cassette_library_dir = 'spec/cassettes'
29
+ c.hook_into :webmock
30
+ c.configure_rspec_metadata!
31
+ c.allow_http_connections_when_no_cassette = true
32
+ end
33
+
34
+ require 'factory_girl'
35
+ FactoryGirl.define do
36
+ skip_create
37
+ end
38
+ require_relative 'factories'
39
+
40
+ RSpec.configure do |config|
41
+ config.include FactoryGirl::Syntax::Methods
42
+
43
+ config.filter_run :focus
44
+ config.run_all_when_everything_filtered = true
45
+
46
+ config.before(:suite) do
47
+ FactoryGirl.lint
48
+ end
49
+
50
+ def is_json?(str)
51
+ JSON.parse(str)
52
+ true
53
+ rescue
54
+ false
55
+ end
56
+ end
@@ -0,0 +1,7 @@
1
+ shared_context 'class_with_messages' do
2
+ context '.initialize' do
3
+ it 'initializes the messages instance variable' do
4
+ expect(subject.messages).to eq([])
5
+ end
6
+ end
7
+ end