nmi_direct_post 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.simplecov +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +83 -0
- data/Rakefile +1 -0
- data/lib/nmi_direct_post.rb +7 -0
- data/lib/nmi_direct_post/base.rb +102 -0
- data/lib/nmi_direct_post/customer_vault.rb +245 -0
- data/lib/nmi_direct_post/logger.rb +17 -0
- data/lib/nmi_direct_post/transaction.rb +168 -0
- data/lib/nmi_direct_post/version.rb +3 -0
- data/nmi_direct_post.gemspec +30 -0
- data/spec/base_spec.rb +37 -0
- data/spec/customer_vault_spec.rb +243 -0
- data/spec/logger_spec.rb +77 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/credentials.rb.example +13 -0
- data/spec/support/test_credentials.rb +11 -0
- data/spec/transaction_spec.rb +303 -0
- metadata +217 -0
data/spec/logger_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class DebugLogger
|
4
|
+
def debug(_)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class InfoLogger
|
9
|
+
def info(_)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module NmiDirectPost
|
14
|
+
class << self
|
15
|
+
def reset_logger
|
16
|
+
@logger = nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module RailsWithLogger
|
22
|
+
class << self
|
23
|
+
def logger
|
24
|
+
@logger = Logger.new('/tmp/rails_logger')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module RailsWithoutLogger
|
30
|
+
end
|
31
|
+
|
32
|
+
describe NmiDirectPost do
|
33
|
+
describe "logger" do
|
34
|
+
before(:each) do
|
35
|
+
NmiDirectPost.reset_logger
|
36
|
+
end
|
37
|
+
after(:all) do
|
38
|
+
NmiDirectPost.reset_logger
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should default to a STDOUT logger if Rails is not defined" do
|
42
|
+
expect(NmiDirectPost.logger.instance_variable_get("@logdev").instance_variable_get("@dev")).to eq(STDOUT)
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "Rails.logger is defined" do
|
46
|
+
before(:each) do
|
47
|
+
stub_const("::Rails", RailsWithLogger)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should default to the Rails logger if Rails.logger is defined" do
|
51
|
+
expect(NmiDirectPost.logger.instance_variable_get("@logdev").instance_variable_get("@dev").inspect).to eq(File.new('/tmp/rails_logger').inspect)
|
52
|
+
end
|
53
|
+
|
54
|
+
after(:each) do
|
55
|
+
`rm /tmp/rails_logger`
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "Rails is defined but Rails.logger is not" do
|
60
|
+
before(:each) do
|
61
|
+
stub_const("::Rails", RailsWithoutLogger)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should default to a STDOUT logger" do
|
65
|
+
expect(NmiDirectPost.logger.instance_variable_get("@logdev").instance_variable_get("@dev")).to eq(STDOUT)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should fail to be set to an object that doesn't respond to info" do
|
70
|
+
expect { NmiDirectPost.logger = DebugLogger.new }.to raise_error(ArgumentError, "NmiDirectPost logger must respond to :info and :debug")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should fail to be set to an object that doesn't respond to debug" do
|
74
|
+
expect { NmiDirectPost.logger = InfoLogger.new }.to raise_error(ArgumentError, "NmiDirectPost logger must respond to :info and :debug")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'nmi_direct_post'
|
3
|
+
|
4
|
+
Dir[("#{File.expand_path("#{__FILE__}/../support")}/**/*.rb")].each { |f| require f }
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.order = "random"
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec::Matchers.define :have_same_attributes_as do |expected|
|
11
|
+
match do |actual|
|
12
|
+
actual.customer_vault_id == expected.customer_vault_id && [true] == (NmiDirectPost::CustomerVault::WHITELIST_ATTRIBUTES.collect { |a| actual.__send__(a) == expected.__send__(a) }).uniq
|
13
|
+
end
|
14
|
+
description do
|
15
|
+
"'#{expected.inspect}'"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path("#{__FILE__}/../test_credentials.rb")
|
2
|
+
|
3
|
+
class TestCredentials
|
4
|
+
INSTANCE = TestCredentials.new(
|
5
|
+
# Configure these values before running specs
|
6
|
+
# You can try using test credentials from https://secure.nmi.com/merchants/resources/integration/integration_portal.php#testing_information if you have a valid customer_vault_id from there, but if you do, the spec for CustomerVault#all will take a very, very, very long time
|
7
|
+
'MY_NMI_USERNAME',
|
8
|
+
'MY_NMI_PASSWORD',
|
9
|
+
'A_CUSTOMER_VAULT_ID_I_CAN_SAFELY_MAKE_CHANGES_TO'.to_i, # Specifically, one that uses a credit card
|
10
|
+
'ANOTHER_CUSTOMER_VAULT_ID_I_CAN_SAFELY_MAKE_CHANGES_TO'.to_i, # Specifically, one that uses a checking account
|
11
|
+
'A_CLEARED_CC_TRANSACTION'.to_i
|
12
|
+
)
|
13
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class TestCredentials
|
2
|
+
attr_reader :nmi_username, :nmi_password, :cc_customer, :ach_customer, :cc_transaction
|
3
|
+
def initialize nmi_username, nmi_password, cc_customer, ach_customer, cc_transaction
|
4
|
+
@nmi_username, @nmi_password, @cc_customer, @ach_customer, @cc_transaction = nmi_username, nmi_password, cc_customer, ach_customer, cc_transaction
|
5
|
+
end
|
6
|
+
credentials_file = File.expand_path("#{__FILE__}/../credentials.rb")
|
7
|
+
unless File.exists?(credentials_file)
|
8
|
+
puts "Please configure your NMI application credentials by copying #{credentials_file}.example to #{credentials_file} and configuring the required values there appropriately."
|
9
|
+
exit
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
#require 'rspec/rails/extensions/active_record/base'
|
3
|
+
|
4
|
+
describe NmiDirectPost::Transaction do
|
5
|
+
let(:a_cc_customer_vault_id) { TestCredentials::INSTANCE.cc_customer }
|
6
|
+
let(:a_checking_account_customer_vault_id) { TestCredentials::INSTANCE.ach_customer }
|
7
|
+
let(:amount) { lambda { @amount_generator.rand(50..500) } }
|
8
|
+
|
9
|
+
before :all do
|
10
|
+
credentials = TestCredentials::INSTANCE
|
11
|
+
NmiDirectPost::Base.establish_connection(credentials.nmi_username, credentials.nmi_password)
|
12
|
+
@amount_generator = Random.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def given_a_sale_for_customer_vault_id customer_vault_id
|
16
|
+
@transaction = NmiDirectPost::Transaction.new(:customer_vault_id => customer_vault_id, :amount => amount.call)
|
17
|
+
expect(@transaction.save).to eq(true), "Transaction failed to save for the following reasons: #{@transaction.errors.messages.inspect}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def expect_response_to_be response, response_code
|
21
|
+
expect(@transaction.response).to eq(response), @transaction.inspect
|
22
|
+
expect(@transaction.response_code).to eq(response_code), @transaction.inspect
|
23
|
+
end
|
24
|
+
|
25
|
+
def if_the_transaction_succeeds
|
26
|
+
expect(@transaction.response).to eq(1), @transaction.inspect
|
27
|
+
end
|
28
|
+
|
29
|
+
def it_should_find_the_transaction
|
30
|
+
@queried_transaction = NmiDirectPost::Transaction.find_by_transaction_id(@transaction.transaction_id)
|
31
|
+
expect(@queried_transaction).not_to be_nil
|
32
|
+
expect(@queried_transaction.amount).to eq @transaction.amount
|
33
|
+
expect(@queried_transaction.customer_vault_id).to eq @transaction.customer_vault_id
|
34
|
+
expect(@queried_transaction.customer_vault).not_to be_nil
|
35
|
+
expect(@queried_transaction.customer_vault.first_name).to eq(@transaction.customer_vault.first_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow saving with a bang" do
|
39
|
+
@transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
40
|
+
expect{@transaction.save!}.not_to raise_error
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should fail validation when no customer_vault_id and no transaction_id are given" do
|
44
|
+
@transaction = NmiDirectPost::Transaction.new(:amount => amount.call)
|
45
|
+
expect{@transaction.save!}.to raise_error(NmiDirectPost::TransactionNotSavedError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should respond with a success code when given a valid customer_vault_id" do
|
49
|
+
given_a_sale_for_customer_vault_id a_cc_customer_vault_id
|
50
|
+
expect_response_to_be 1, 100
|
51
|
+
expect(@transaction.response_text).to eq("SUCCESS"), @transaction.inspect
|
52
|
+
expect(@transaction).to be_success, @transaction.inspect
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should fail validation when given an invalid customer_vault_id" do
|
56
|
+
@transaction = NmiDirectPost::Transaction.new(:customer_vault_id => 1000, :amount => amount.call)
|
57
|
+
expect(@transaction.save).to eq(false)
|
58
|
+
expect(@transaction.errors.size).to eq(1)
|
59
|
+
expect(@transaction.errors[:customer_vault].size).to eq(1)
|
60
|
+
expect(@transaction.errors[:customer_vault]).to include("Customer vault with the given customer_vault could not be found")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should find a sale" do
|
64
|
+
given_a_sale_for_customer_vault_id a_cc_customer_vault_id
|
65
|
+
if_the_transaction_succeeds
|
66
|
+
it_should_find_the_transaction
|
67
|
+
expect(@queried_transaction.type).to eq "sale"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should find a validate" do
|
71
|
+
@transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0, :type => :validate)
|
72
|
+
@transaction.save
|
73
|
+
if_the_transaction_succeeds
|
74
|
+
it_should_find_the_transaction
|
75
|
+
expect(@queried_transaction.type).to eq @transaction.type
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should raise an error when transaction_id is blank" do
|
79
|
+
expect{ NmiDirectPost::Transaction.find_by_transaction_id("") }.to raise_error(StandardError, "TransactionID cannot be blank")
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should raise an error when transaction is not found using instance" do
|
83
|
+
expect{ NmiDirectPost::Transaction.new(:transaction_id => 12345) }.to raise_error(NmiDirectPost::TransactionNotFoundError, "No transaction found for TransactionID 12345")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should return nil when transaction is not found using class method" do
|
87
|
+
expect(NmiDirectPost::Transaction.find_by_transaction_id(12345)).to be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should add response, response_code and response to errors when charge cannot be saved" do
|
91
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0, :type => :validate)
|
92
|
+
transaction.instance_variable_set("@password", '12345')
|
93
|
+
expect(transaction.save).to eq(false)
|
94
|
+
expect(transaction.errors.size).to eq(3), transaction.errors.inspect
|
95
|
+
expect(transaction.errors[:response].size).to eq(1), transaction.errors[:response].inspect
|
96
|
+
expect(transaction.errors[:response]).to include('3'), transaction.errors.inspect
|
97
|
+
expect(transaction.errors[:response_code].size).to eq(1), transaction.errors[:response_code].inspect
|
98
|
+
expect(transaction.errors[:response_code]).to include('300'), transaction.errors.inspect
|
99
|
+
expect(transaction.errors[:response_text].size).to eq(1), transaction.errors[:response_text].inspect
|
100
|
+
expect(transaction.errors[:response_text]).to include('Authentication Failed'), transaction.errors.inspect
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "customer_vault" do
|
104
|
+
it "should find when it exists" do
|
105
|
+
@transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
106
|
+
expect(@transaction.customer_vault).to have_same_attributes_as(NmiDirectPost::CustomerVault.find_by_customer_vault_id(a_cc_customer_vault_id))
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should be nil when it doesn't exist" do
|
110
|
+
@transaction = NmiDirectPost::Transaction.new(:customer_vault_id => '123456', :amount => amount.call)
|
111
|
+
expect(@transaction.customer_vault).to be_nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "type" do
|
116
|
+
describe "sale" do
|
117
|
+
it "should allow non-zero amounts for credit card customer vaults" do
|
118
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :sale)
|
119
|
+
expect(transaction.save).to eq(true), transaction.errors.inspect
|
120
|
+
end
|
121
|
+
it "should not allow amount to be 0 for credit card customer vaults" do
|
122
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0, :type => :sale)
|
123
|
+
expect(transaction.save).to eq(false)
|
124
|
+
expect(transaction.errors.size).to eq(1)
|
125
|
+
expect(transaction.errors[:amount].size).to eq(1)
|
126
|
+
expect(transaction.errors[:amount]).to include('Amount cannot be 0 for a sale')
|
127
|
+
end
|
128
|
+
it "should allow non-zero amounts for checking account customer vaults" do
|
129
|
+
expect(NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => amount.call, :type => :sale).save).to eq(true)
|
130
|
+
end
|
131
|
+
it "should not allow amount to be 0 for checking account customer vaults" do
|
132
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => 0, :type => :sale)
|
133
|
+
expect(transaction.save).to eq(false)
|
134
|
+
expect(transaction.errors.size).to eq(1)
|
135
|
+
expect(transaction.errors[:amount].size).to eq(1)
|
136
|
+
expect(transaction.errors[:amount]).to include('Amount cannot be 0 for a sale')
|
137
|
+
end
|
138
|
+
it "should allow non-zero amounts for credit card customer vaults when sale is implied" do
|
139
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
140
|
+
expect(transaction.save).to eq(true), transaction.errors.inspect
|
141
|
+
end
|
142
|
+
it "should not allow amount to be 0 for credit card customer vaults when sale is implied" do
|
143
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0)
|
144
|
+
expect(transaction.save).to eq(false)
|
145
|
+
expect(transaction.errors.size).to eq(1)
|
146
|
+
expect(transaction.errors[:amount].size).to eq(1)
|
147
|
+
expect(transaction.errors[:amount]).to include('Amount cannot be 0 for a sale')
|
148
|
+
end
|
149
|
+
it "should allow non-zero amounts for checking account customer vaults when sale is implied" do
|
150
|
+
expect(NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => amount.call).save).to eq(true)
|
151
|
+
end
|
152
|
+
it "should not allow amount to be 0 for checking account customer vaults when sale is implied" do
|
153
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => 0)
|
154
|
+
expect(transaction.save).to eq(false)
|
155
|
+
expect(transaction.errors.size).to eq(1)
|
156
|
+
expect(transaction.errors[:amount].size).to eq(1)
|
157
|
+
expect(transaction.errors[:amount]).to include('Amount cannot be 0 for a sale')
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "validate" do
|
162
|
+
it "should not allow non-zero amounts" do
|
163
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :validate)
|
164
|
+
expect(transaction.save).to eq(false)
|
165
|
+
expect(transaction.errors.size).to eq(1)
|
166
|
+
expect(transaction.errors[:amount].size).to eq(1)
|
167
|
+
expect(transaction.errors[:amount]).to include('Amount must be 0 when validating a credit card')
|
168
|
+
end
|
169
|
+
it "should allow amount to be 0" do
|
170
|
+
expect(NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0, :type => :validate).save).to eq(true)
|
171
|
+
end
|
172
|
+
it "should not be allowed for checking account customer vaults" do
|
173
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => 0, :type => :validate)
|
174
|
+
expect(transaction.save).to eq(false)
|
175
|
+
expect(transaction.errors.size).to eq(1)
|
176
|
+
expect(transaction.errors[:type].size).to eq(1)
|
177
|
+
expect(transaction.errors[:type]).to include('validate is not a valid action for a customer vault that uses a checking account')
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "auth" do
|
182
|
+
it "should allow non-zero amounts for credit card customer vaults" do
|
183
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :auth)
|
184
|
+
expect(transaction.save).to eq(true), transaction.errors.inspect
|
185
|
+
end
|
186
|
+
it "should not allow amount to be 0 for credit card customer vaults" do
|
187
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0, :type => :auth)
|
188
|
+
expect(transaction.save).to eq(false)
|
189
|
+
expect(transaction.errors.size).to eq(1)
|
190
|
+
expect(transaction.errors[:amount].size).to eq(1)
|
191
|
+
expect(transaction.errors[:amount]).to include('Amount cannot be 0 for an authorization')
|
192
|
+
end
|
193
|
+
it "should not be allowed for checking account customer vaults" do
|
194
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => amount.call, :type => :auth)
|
195
|
+
expect(transaction.save).to eq(false)
|
196
|
+
expect(transaction.errors.size).to eq(1)
|
197
|
+
expect(transaction.errors[:type].size).to eq(1)
|
198
|
+
expect(transaction.errors[:type]).to include('auth is not a valid action for a customer vault that uses a checking account')
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "void" do
|
203
|
+
it "should be allowed for a pending sale" do
|
204
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
205
|
+
transaction.save!
|
206
|
+
expect(transaction.void!).to eq(true)
|
207
|
+
end
|
208
|
+
it "should not be allowed for validates" do
|
209
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => 0, :type => :validate)
|
210
|
+
transaction.save!
|
211
|
+
expect(transaction.void!).to eq(false)
|
212
|
+
expect(transaction.errors.size).to eq(1), transaction.errors.inspect
|
213
|
+
expect(transaction.errors[:type].size).to eq(1), transaction.errors.inspect
|
214
|
+
expect(transaction.errors[:type]).to include('Void is only a valid action for a pending or unsettled authorization, or an unsettled sale')
|
215
|
+
end
|
216
|
+
it "should be allowed for authorizations when saved and voided on same instantiation" do
|
217
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :auth)
|
218
|
+
expect(transaction.save).to eq(true), transaction.inspect
|
219
|
+
expect(transaction.void!).to eq(true), transaction.inspect
|
220
|
+
expect(transaction.errors).to be_empty, transaction.errors.inspect
|
221
|
+
end
|
222
|
+
it "should be allowed for authorizations when found by transaction ID" do
|
223
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :auth)
|
224
|
+
transaction.save!
|
225
|
+
transaction = NmiDirectPost::Transaction.find_by_transaction_id(transaction.transaction_id)
|
226
|
+
expect(transaction.void!).to eq(true), transaction.inspect
|
227
|
+
expect(transaction.errors).to be_empty, transaction.errors.inspect
|
228
|
+
end
|
229
|
+
it "should be allowed for authorizations when instantiated as a void" do
|
230
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :auth)
|
231
|
+
transaction.save!
|
232
|
+
transaction = NmiDirectPost::Transaction.new(:transaction_id => transaction.transaction_id, :type => :void)
|
233
|
+
expect(transaction.save).to eq(true), transaction.errors.inspect
|
234
|
+
expect(transaction.errors).to be_empty, transaction.errors.inspect
|
235
|
+
end
|
236
|
+
it "should not be allowed for an unpersisted transaction" do
|
237
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :auth)
|
238
|
+
expect(transaction.void!).to eq(false), transaction.inspect
|
239
|
+
expect(transaction.errors.size).to eq(1), transaction.errors.inspect
|
240
|
+
expect(transaction.errors[:type].size).to eq(1), transaction.errors.inspect
|
241
|
+
expect(transaction.errors[:type]).to include('Void is only a valid action for a transaction that has already been sent to NMI')
|
242
|
+
end
|
243
|
+
it "should not be allowed for a voided sale" do
|
244
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
245
|
+
transaction.save!
|
246
|
+
expect(transaction.void!).to eq(true)
|
247
|
+
expect(transaction.void!).to eq(false)
|
248
|
+
expect(transaction.errors.size).to eq(1), transaction.errors.inspect
|
249
|
+
expect(transaction.errors[:type].size).to eq(1), transaction.errors.inspect
|
250
|
+
expect(transaction.errors[:type]).to include('Void is only a valid action for a pending or unsettled authorization, or an unsettled sale')
|
251
|
+
end
|
252
|
+
it "should not be allowed for a voided auth" do
|
253
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call, :type => :auth)
|
254
|
+
transaction.save!
|
255
|
+
expect(transaction.void!).to eq(true)
|
256
|
+
expect(transaction.void!).to eq(false)
|
257
|
+
expect(transaction.errors.size).to eq(1), transaction.errors.inspect
|
258
|
+
expect(transaction.errors[:type].size).to eq(1), transaction.errors.inspect
|
259
|
+
expect(transaction.errors[:type]).to include('Void is only a valid action for a pending or unsettled authorization, or an unsettled sale')
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
describe "condition" do
|
265
|
+
def given_a_check_transaction
|
266
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_checking_account_customer_vault_id, :amount => amount.call)
|
267
|
+
transaction.save!
|
268
|
+
@amount = transaction.amount
|
269
|
+
@transaction = NmiDirectPost::Transaction.find_by_transaction_id(transaction.transaction_id)
|
270
|
+
end
|
271
|
+
def given_a_cc_transaction
|
272
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
273
|
+
transaction.save!
|
274
|
+
@amount = transaction.amount
|
275
|
+
@transaction = NmiDirectPost::Transaction.find_by_transaction_id(transaction.transaction_id)
|
276
|
+
end
|
277
|
+
it "should be pendingsettlement on a new check" do
|
278
|
+
given_a_check_transaction
|
279
|
+
expect(@transaction.condition).to eq("pendingsettlement")
|
280
|
+
expect(@transaction).to be_pending
|
281
|
+
expect(@transaction).not_to be_cleared
|
282
|
+
expect(@transaction.amount).to eq(@amount)
|
283
|
+
end
|
284
|
+
it "should be pending on a new CC charge" do
|
285
|
+
given_a_cc_transaction
|
286
|
+
expect(@transaction.condition).to eq("pendingsettlement")
|
287
|
+
expect(@transaction).to be_pending
|
288
|
+
expect(@transaction).not_to be_cleared
|
289
|
+
expect(@transaction.amount).to eq(@amount)
|
290
|
+
end
|
291
|
+
it "should be approved on an existing CC charge" do
|
292
|
+
transaction = NmiDirectPost::Transaction.find_by_transaction_id(TestCredentials::INSTANCE.cc_transaction)
|
293
|
+
expect(transaction.condition).to eq("complete")
|
294
|
+
expect(transaction).not_to be_pending
|
295
|
+
expect(transaction).to be_cleared
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should not reload when transaction_id is missing" do
|
300
|
+
transaction = NmiDirectPost::Transaction.new(:customer_vault_id => a_cc_customer_vault_id, :amount => amount.call)
|
301
|
+
expect{transaction.reload}.not_to raise_error
|
302
|
+
end
|
303
|
+
end
|
metadata
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nmi_direct_post
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Isaac Betesh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: addressable
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activemodel
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: activesupport
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.0'
|
125
|
+
description: Gem that encapsulates the NMI Direct Post API in an ActiveRecord-like
|
126
|
+
syntax
|
127
|
+
email:
|
128
|
+
- iybetesh@gmail.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".simplecov"
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- lib/nmi_direct_post.rb
|
141
|
+
- lib/nmi_direct_post/base.rb
|
142
|
+
- lib/nmi_direct_post/customer_vault.rb
|
143
|
+
- lib/nmi_direct_post/logger.rb
|
144
|
+
- lib/nmi_direct_post/transaction.rb
|
145
|
+
- lib/nmi_direct_post/version.rb
|
146
|
+
- nmi_direct_post.gemspec
|
147
|
+
- spec/base_spec.rb
|
148
|
+
- spec/customer_vault_spec.rb
|
149
|
+
- spec/logger_spec.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
- spec/support/credentials.rb.example
|
152
|
+
- spec/support/test_credentials.rb
|
153
|
+
- spec/transaction_spec.rb
|
154
|
+
homepage: https://github.com/betesh/nmi_direct_post
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.4.3
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: '# NmiDirectPost NmiDirectPost is a gem that encapsulates the NMI Direct
|
178
|
+
Post API in an ActiveRecord-like syntax. For more information on the NMI Direct
|
179
|
+
Post API, see: https://secure.nmi.com/merchants/resources/integration/integration_portal.php To
|
180
|
+
mimic ActivRecord syntax, it is necessary to blur, from the client''s standpoint,
|
181
|
+
the boundary between NMI''s Direct Post API and its Query API. This fuzziness is
|
182
|
+
part of the encapsulation. ## Installation Add this line to your application''s
|
183
|
+
Gemfile: gem ''nmi_direct_post'' And then execute: $ bundle Or install it yourself
|
184
|
+
as: $ gem install nmi_direct_post ## Usage 1) Before you can query or post, establish
|
185
|
+
the connection: NmiDirectPost::Base.establish_connection("MY_NMI_USERNAME", "MY_NMI_PASSWORD") Theoretically,
|
186
|
+
you can use a different connection for NmiDirectPost::Transaction or NmiDirectPost::CustomerVault
|
187
|
+
by calling establish_connection on either of those derived classes, instead of on
|
188
|
+
Base. However, it''s hard to imagine a case where this would be useful; the option
|
189
|
+
is only present to mimic the syntax of ActiveRecord. 2) Query the API: NmiDirectPost::Transaction.find_by_transaction_id(123456789)
|
190
|
+
NmiDirectPost::CustomerVault.find_by_customer_vault_id(123123123) 3) Create a CustomerVault: george
|
191
|
+
= NmiDirectPostCustomerVault.new(:first_name => ''George'', :last_name => ''Washington'',
|
192
|
+
:cc_number => ''4111111111111111'', :cc_exp => ''03/17'') george.create 4) Update
|
193
|
+
a CustomerVault: george.update!(:email => ''el_primero_presidente@whitehouse.gov'',
|
194
|
+
:address_1 => ''1600 Pennsylvania Ave NW'', :city => ''Washington'', :state => ''DC'',
|
195
|
+
:postal_code => ''20500'') ALTERNATIVELY: george.email = ''el_primero_presidente@whitehouse.gov''
|
196
|
+
george.address_1 = ''1600 Pennsylvania Ave NW'' george.city = ''Washington'' george.state
|
197
|
+
= ''DC'' george.postal_code = ''20500'' george.save! # Returns true 5) Delete a
|
198
|
+
CustomerVault: george.destroy # Returns the CustomerVault 6) Reload a CustomerVault: george.email
|
199
|
+
= ''el_primero_presidente@whitehouse.gov'' george.reload # Returns the Customer
|
200
|
+
Vault george.email # Returns the previously set email 7) CustomerVault class methods: NmiDirectPost::CustomerVault.all_ids
|
201
|
+
# Returns array of `customer_vault_id`s NmiDirectPost::CustomerVault.first NmiDirectPost::CustomerVault.last
|
202
|
+
NmiDirectPost::CustomerVault.all # Returns very, very big array. This method had
|
203
|
+
very poor performance and could be optimized significantly in a future version of
|
204
|
+
this gem. 8) Create a Transaction: parking_ticket = NmiDirectPost::Transaction(:type
|
205
|
+
=> :sale, :amount => 150.01, :customer_vault_id => george.customer_vault_id) parking_ticket.save!
|
206
|
+
# Returns true ## Contributing 1. Fork it 2. Create your feature branch (`git
|
207
|
+
checkout -b my-new-feature`) 3. Commit your changes (`git commit -am ''Add some
|
208
|
+
feature''`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new
|
209
|
+
Pull Request'
|
210
|
+
test_files:
|
211
|
+
- spec/base_spec.rb
|
212
|
+
- spec/customer_vault_spec.rb
|
213
|
+
- spec/logger_spec.rb
|
214
|
+
- spec/spec_helper.rb
|
215
|
+
- spec/support/credentials.rb.example
|
216
|
+
- spec/support/test_credentials.rb
|
217
|
+
- spec/transaction_spec.rb
|