nmi_direct_post 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d376bc5d9401a3274444f713f3ef40f04a4a41e3
4
- data.tar.gz: 383d6fb624a33d30f1121904b76c5b77eb0af761
3
+ metadata.gz: 8a7f96e99aff57d1745c1e1b1cd90619eca8d45b
4
+ data.tar.gz: 7b5faf05b492e67293278a702f1f8832e1ba617a
5
5
  SHA512:
6
- metadata.gz: d40ddf52eceb8174336a6b9675d8a3a0e7161135cbdaed6effd7c1a361c54ebcb84432e08391a9b8829ffed9dd366401123cd750ecbe488e5b9cccf13b77e8a4
7
- data.tar.gz: 9ac20fafa098b00e4069d05b994f0d15175033cd6b7408c617c10cd32e0318f1c6984039db20d95606fdb7375803c5413bef446914629ef29d74120cd3a53229
6
+ metadata.gz: a5584f91061e4ebf5d372a96efc7f2ca061134fc79b9e5c6c130e9220573c7bd978416e88f769038fbab0f7f391cea24cea9e0bf752d49032b9f0a3a4c2f6701
7
+ data.tar.gz: b5c1bb5556057f1df9acae2bf22b2b1ed462275e81c52ea811150cc365e1425b0f650746b7a35a044624e14071f0439add3b0a406184bba4455996ddec6d7084
data/README.md CHANGED
@@ -22,17 +22,21 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- 1) Before you can query or post, establish the connection:
25
+ 1) Before you query or post, you probably want to set a default username and password:
26
26
 
27
27
  NmiDirectPost::Base.establish_connection("MY_NMI_USERNAME", "MY_NMI_PASSWORD")
28
28
 
29
+ If you don't set a default, you'll need to include the username and password in the hash passed to the initializer when instantiating a new Transaction or CustomerVault.
30
+
29
31
  Theoretically, you can use a different connection for NmiDirectPost::Transaction or NmiDirectPost::CustomerVault by calling establish_connection on either of those derived classes, instead of on Base.
30
32
  However, it's hard to imagine a case where this would be useful; the option is only present to mimic the syntax of ActiveRecord.
31
33
 
32
34
  2) Query the API:
33
35
 
34
- NmiDirectPost::Transaction.find_by_transaction_id(123456789)
35
- NmiDirectPost::CustomerVault.find_by_customer_vault_id(123123123)
36
+ NmiDirectPost::Transaction.find_by_transaction_id(123456789, "MyUsername", "MyPassword")
37
+ NmiDirectPost::Transaction.find_by_transaction_id(123456789) # If you've already called establish_connection
38
+
39
+ NmiDirectPost::CustomerVault.find_by_customer_vault_id(123123123) # Note that there is no way to pass a username and password to this method. You must call establish_connection beforehand.
36
40
 
37
41
  3) Create a CustomerVault:
38
42
 
@@ -69,6 +73,8 @@ However, it's hard to imagine a case where this would be useful; the option is o
69
73
  NmiDirectPost::CustomerVault.last
70
74
  NmiDirectPost::CustomerVault.all # Returns very, very big array. This method had very poor performance and could be optimized significantly in a future version of this gem.
71
75
 
76
+ Note that there is no way to pass a username and password to these methods. You must call establish_connection beforehand.
77
+
72
78
  8) Create a Transaction:
73
79
 
74
80
  parking_ticket = NmiDirectPost::Transaction(:type => :sale, :amount => 150.01, :customer_vault_id => george.customer_vault_id)
@@ -28,8 +28,9 @@ module NmiDirectPost
28
28
  include ActiveModel::Conversion
29
29
  validates_presence_of :username, :password
30
30
 
31
- def initialize
32
- @username, @password = self.class.username, self.class.password
31
+ def initialize(attributes)
32
+ @username = attributes[:username] || attributes["username"] || self.class.username
33
+ @password = attributes[:password] || attributes["password"] || self.class.password
33
34
  end
34
35
 
35
36
  def persisted?
@@ -80,7 +81,7 @@ module NmiDirectPost
80
81
  url = URI.parse(uri)
81
82
  http = Net::HTTP.new(url.host, url.port)
82
83
  http.use_ssl = true
83
- http.ssl_version = :TLSv1
84
+ http.ssl_version = :TLSv1_2
84
85
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
85
86
  http.request(request)
86
87
  end
@@ -39,7 +39,7 @@ module NmiDirectPost
39
39
  :if => Proc.new { |record| :add_customer == record.customer_vault }
40
40
 
41
41
  def initialize(attributes)
42
- super()
42
+ super
43
43
  if attributes[:customer_vault_id].blank?
44
44
  set_attributes(attributes.dup) unless attributes.empty?
45
45
  else
@@ -84,7 +84,7 @@ module NmiDirectPost
84
84
  begin
85
85
  safe_params = customer_vault_instance_params
86
86
  logger.debug { "Loading NMI customer vault from customer_vault_id(#{customer_vault_id}) using query: #{safe_params}" }
87
- response = self.class.get(self.class.all_params(safe_params))["customer_vault"]
87
+ response = self.class.get(self.class.all_params(safe_params, self))["customer_vault"]
88
88
  raise CustomerVaultNotFoundError, "No record found for customer vault ID #{self.customer_vault_id}" if response.nil?
89
89
  attributes = response["customer"].with_indifferent_access
90
90
  READ_ONLY_ATTRIBUTES.each do |a|
@@ -115,7 +115,7 @@ module NmiDirectPost
115
115
  @report_type = :customer_vault
116
116
  safe_params = generate_query_string(MERCHANT_DEFINED_FIELDS + [:last_name, :email, :report_type]) # These are the only fields you can use when looking up without a customer_vault_id
117
117
  logger.info { "Querying NMI customer vault: #{safe_params}" }
118
- @customer_vault_id = self.class.get(self.class.all_params(safe_params))['customer_vault'][0]['customer_vault_id'] # This assumes there is only 1 result.
118
+ @customer_vault_id = self.class.get(self.class.all_params(safe_params, self))['customer_vault'][0]['customer_vault_id'] # This assumes there is only 1 result.
119
119
  # TODO: When there are multiple results, we don't know which one you want. Maybe raise an error in that case?
120
120
  reload
121
121
  ensure
@@ -126,10 +126,10 @@ module NmiDirectPost
126
126
  class << self
127
127
  attr_reader :report_type
128
128
 
129
- def find_by_customer_vault_id(customer_vault_id)
129
+ def find_by_customer_vault_id(customer_vault_id, username=nil, password=nil)
130
130
  raise StandardError, "CustomerVaultID cannot be blank" if customer_vault_id.blank?
131
131
  begin
132
- new(:customer_vault_id => customer_vault_id)
132
+ new(customer_vault_id: customer_vault_id, username: username, password: password)
133
133
  rescue CustomerVaultNotFoundError
134
134
  return nil
135
135
  end
@@ -161,8 +161,8 @@ module NmiDirectPost
161
161
  limit
162
162
  end
163
163
 
164
- def all_params(safe_params)
165
- [safe_params, generate_query_string(Base::AUTH_PARAMS)].join('&')
164
+ def all_params(safe_params, target=self)
165
+ [safe_params, generate_query_string(Base::AUTH_PARAMS, target)].join('&')
166
166
  end
167
167
 
168
168
  private
@@ -178,7 +178,7 @@ module NmiDirectPost
178
178
 
179
179
  def post(safe_params)
180
180
  logger.info { "Sending Direct Post to NMI: #{safe_params}" }
181
- response = self.class.post(self.class.all_params(safe_params))
181
+ response = self.class.post(self.class.all_params(safe_params, self))
182
182
  @response, @response_text, @response_code = response["response"].to_i, response["responsetext"], response["response_code"].to_i
183
183
  @customer_vault_id = response["customer_vault_id"].to_i if :add_customer == self.customer_vault
184
184
  end
@@ -25,7 +25,7 @@ module NmiDirectPost
25
25
  validate :save_successful?, :unless => 'response_text.blank?'
26
26
 
27
27
  def initialize(attributes)
28
- super()
28
+ super
29
29
  @type, @amount = attributes[:type].to_s, attributes[:amount].to_f
30
30
  @transaction_id = attributes[:transaction_id].to_i if attributes[:transaction_id]
31
31
  @customer_vault_id = attributes[:customer_vault_id].to_i if attributes[:customer_vault_id]
@@ -34,8 +34,13 @@ module NmiDirectPost
34
34
  end
35
35
 
36
36
  def save
37
- void! if ('void' == type && condition.blank?)
38
- return false if self.invalid?
37
+ return false if invalid?
38
+ if condition.blank?
39
+ if 'void' == type
40
+ reload
41
+ @type = 'void'
42
+ end
43
+ end
39
44
  _safe_params = safe_params
40
45
  logger.info { "Sending Direct Post Transaction to NMI: #{_safe_params}" }
41
46
  post([_safe_params, transaction_params].join('&'))
@@ -74,11 +79,6 @@ module NmiDirectPost
74
79
 
75
80
  def void!
76
81
  @type='void'
77
- if condition.blank?
78
- return false if invalid?
79
- reload
80
- @type = 'void'
81
- end
82
82
  save
83
83
  end
84
84
 
@@ -1,3 +1,3 @@
1
1
  module NmiDirectPost
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -25,6 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "simplecov"
26
26
 
27
27
  spec.add_dependency 'addressable'
28
- spec.add_dependency 'activemodel'
29
- spec.add_dependency 'activesupport', ' >= 3.0'
28
+ spec.add_dependency 'activemodel', '>= 4.0'
30
29
  end
@@ -34,4 +34,8 @@ describe NmiDirectPost::Base do
34
34
  NmiDirectPost::CustomerVault.establish_connection(credentials.nmi_username, credentials.nmi_password)
35
35
  expect{a_query}.to_not raise_error
36
36
  end
37
+ it "should allow the record to set its own username/password" do
38
+ a_query = ->{ NmiDirectPost::CustomerVault.find_by_customer_vault_id(a_cc_customer_vault_id, "ABC", "DEF") }
39
+ expect(a_query).not_to raise_error
40
+ end
37
41
  end
@@ -4,153 +4,151 @@ require_relative 'spec_helper'
4
4
  describe NmiDirectPost::Transaction do
5
5
  let(:a_cc_customer_vault_id) { TestCredentials::INSTANCE.cc_customer }
6
6
  let(:a_checking_account_customer_vault_id) { TestCredentials::INSTANCE.ach_customer }
7
- let(:amount) { lambda { @amount_generator.rand(50..500) } }
7
+ let(:amount) { Random.rand(50.0..500.0).round(2) }
8
+ let(:credentials) { TestCredentials::INSTANCE }
9
+ let(:cc_implicit_sale) { NmiDirectPost::Transaction.new(customer_vault_id: a_cc_customer_vault_id, amount: amount) }
10
+ let(:ach_implicit_sale) { NmiDirectPost::Transaction.new(customer_vault_id: a_checking_account_customer_vault_id, amount: amount) }
11
+ let(:cc_validation) { NmiDirectPost::Transaction.new(customer_vault_id: a_cc_customer_vault_id, amount: 0, type: :validate) }
8
12
 
9
- before :all do
10
- credentials = TestCredentials::INSTANCE
13
+ before(:each) do
11
14
  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
15
  end
37
16
 
38
17
  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
18
+ expect{cc_implicit_sale.save!}.not_to raise_error
41
19
  end
42
20
 
43
21
  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)
22
+ transaction = NmiDirectPost::Transaction.new(amount: amount)
23
+ expect{transaction.save!}.to raise_error(NmiDirectPost::TransactionNotSavedError)
46
24
  end
47
25
 
48
26
  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
27
+ expect(cc_implicit_sale.save).to eq(true), "Transaction failed to save for the following reasons: #{cc_implicit_sale.errors.messages.inspect}"
28
+ expect(cc_implicit_sale.response).to eq(1), cc_implicit_sale.inspect
29
+ expect(cc_implicit_sale.response_code).to eq(100), cc_implicit_sale.inspect
30
+ expect(cc_implicit_sale.response_text).to eq("SUCCESS"), cc_implicit_sale.inspect
31
+ expect(cc_implicit_sale).to be_success, cc_implicit_sale.inspect
53
32
  end
54
33
 
55
34
  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")
35
+ transaction = NmiDirectPost::Transaction.new(customer_vault_id: 1000, amount: amount)
36
+ expect(transaction.save).to eq(false)
37
+ expect(transaction.errors.size).to eq(1)
38
+ expect(transaction.errors[:customer_vault].size).to eq(1)
39
+ expect(transaction.errors[:customer_vault]).to include("Customer vault with the given customer_vault could not be found")
61
40
  end
62
41
 
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
42
+ describe "finding an existing transaction" do
43
+ let(:queried_transaction) { NmiDirectPost::Transaction.find_by_transaction_id(transaction.transaction_id) }
69
44
 
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
45
+ def it_should_find_the_transaction
46
+ expect(queried_transaction).not_to be_nil
47
+ expect(queried_transaction.amount).to eq transaction.amount
48
+ expect(queried_transaction.customer_vault_id).to eq transaction.customer_vault_id
49
+ expect(queried_transaction.customer_vault).not_to be_nil
50
+ expect(queried_transaction.customer_vault.first_name).to eq(transaction.customer_vault.first_name)
51
+ end
77
52
 
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
53
+ describe "a sale" do
54
+ let(:transaction) { cc_implicit_sale }
81
55
 
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
56
+ it "should be found" do
57
+ expect(cc_implicit_sale.save).to eq(true), "Transaction failed to save for the following reasons: #{cc_implicit_sale.errors.messages.inspect}"
58
+ expect(cc_implicit_sale.response).to eq(1), cc_implicit_sale.inspect
59
+ it_should_find_the_transaction
60
+ expect(queried_transaction.type).to eq "sale"
61
+ end
62
+ end
85
63
 
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
64
+ describe "a validate" do
65
+ let(:transaction) { cc_validation }
66
+
67
+ it "should be found" do
68
+ cc_validation.save
69
+ expect(cc_validation.response).to eq(1), cc_validation.inspect
70
+ it_should_find_the_transaction
71
+ expect(queried_transaction.type).to eq cc_validation.type
72
+ end
73
+ end
74
+
75
+ it "should raise an error when transaction_id is blank" do
76
+ expect{ NmiDirectPost::Transaction.find_by_transaction_id("") }.to raise_error(StandardError, "TransactionID cannot be blank")
77
+ end
78
+
79
+ it "should raise an error when transaction is not found using instance" do
80
+ expect{ NmiDirectPost::Transaction.new(transaction_id: 12345) }.to raise_error(NmiDirectPost::TransactionNotFoundError, "No transaction found for TransactionID 12345")
81
+ end
82
+
83
+ it "should return nil when transaction is not found using class method" do
84
+ expect(NmiDirectPost::Transaction.find_by_transaction_id(12345)).to be_nil
85
+ end
88
86
  end
89
87
 
90
88
  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
89
+ cc_validation.instance_variable_set("@password", '12345')
90
+ expect(cc_validation.save).to eq(false)
91
+ expect(cc_validation.errors.size).to eq(3), cc_validation.errors.inspect
92
+ expect(cc_validation.errors[:response].size).to eq(1), cc_validation.errors[:response].inspect
93
+ expect(cc_validation.errors[:response]).to include('3'), cc_validation.errors.inspect
94
+ expect(cc_validation.errors[:response_code].size).to eq(1), cc_validation.errors[:response_code].inspect
95
+ expect(cc_validation.errors[:response_code]).to include('300'), cc_validation.errors.inspect
96
+ expect(cc_validation.errors[:response_text].size).to eq(1), cc_validation.errors[:response_text].inspect
97
+ expect(cc_validation.errors[:response_text]).to include('Authentication Failed'), cc_validation.errors.inspect
101
98
  end
102
99
 
103
100
  describe "customer_vault" do
104
101
  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))
102
+ expect(cc_implicit_sale.customer_vault).to have_same_attributes_as(NmiDirectPost::CustomerVault.find_by_customer_vault_id(a_cc_customer_vault_id))
107
103
  end
108
104
 
109
105
  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
106
+ transaction = NmiDirectPost::Transaction.new(customer_vault_id: '123456', amount: amount)
107
+ expect(transaction.customer_vault).to be_nil
112
108
  end
113
109
  end
114
110
 
115
111
  describe "type" do
112
+ let(:cc_transaction) { NmiDirectPost::Transaction.new(customer_vault_id: a_cc_customer_vault_id, amount: amount, type: transaction_type) }
113
+ let(:cc_transaction_amount_0) { NmiDirectPost::Transaction.new(customer_vault_id: a_cc_customer_vault_id, amount: 0, type: transaction_type) }
114
+ let(:ach_transaction) { NmiDirectPost::Transaction.new(customer_vault_id: a_checking_account_customer_vault_id, amount: amount, type: transaction_type) }
115
+ let(:ach_transaction_amount_0) { NmiDirectPost::Transaction.new(customer_vault_id: a_checking_account_customer_vault_id, amount: 0, type: transaction_type) }
116
+
116
117
  describe "sale" do
118
+ let(:transaction_type) { :sale }
117
119
  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
+ expect(cc_transaction.save).to eq(true), cc_transaction.errors.inspect
120
121
  end
121
122
  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')
123
+ expect(cc_transaction_amount_0.save).to eq(false)
124
+ expect(cc_transaction_amount_0.errors.size).to eq(1)
125
+ expect(cc_transaction_amount_0.errors[:amount].size).to eq(1)
126
+ expect(cc_transaction_amount_0.errors[:amount]).to include('Amount cannot be 0 for a sale')
127
127
  end
128
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)
129
+ expect(ach_transaction.save).to eq(true)
130
130
  end
131
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')
132
+ expect(ach_transaction_amount_0.save).to eq(false)
133
+ expect(ach_transaction_amount_0.errors.size).to eq(1)
134
+ expect(ach_transaction_amount_0.errors[:amount].size).to eq(1)
135
+ expect(ach_transaction_amount_0.errors[:amount]).to include('Amount cannot be 0 for a sale')
137
136
  end
138
137
  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
138
+ expect(cc_implicit_sale.save).to eq(true), cc_implicit_sale.errors.inspect
141
139
  end
142
140
  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)
141
+ transaction = NmiDirectPost::Transaction.new(customer_vault_id: a_cc_customer_vault_id, amount: 0)
144
142
  expect(transaction.save).to eq(false)
145
143
  expect(transaction.errors.size).to eq(1)
146
144
  expect(transaction.errors[:amount].size).to eq(1)
147
145
  expect(transaction.errors[:amount]).to include('Amount cannot be 0 for a sale')
148
146
  end
149
147
  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)
148
+ expect(ach_implicit_sale.save).to eq(true)
151
149
  end
152
150
  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)
151
+ transaction = NmiDirectPost::Transaction.new(customer_vault_id: a_checking_account_customer_vault_id, amount: 0)
154
152
  expect(transaction.save).to eq(false)
155
153
  expect(transaction.errors.size).to eq(1)
156
154
  expect(transaction.errors[:amount].size).to eq(1)
@@ -159,134 +157,124 @@ describe NmiDirectPost::Transaction do
159
157
  end
160
158
 
161
159
  describe "validate" do
160
+ let(:transaction_type) { :validate }
162
161
  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')
162
+ expect(cc_transaction.save).to eq(false)
163
+ expect(cc_transaction.errors.size).to eq(1)
164
+ expect(cc_transaction.errors[:amount].size).to eq(1)
165
+ expect(cc_transaction.errors[:amount]).to include('Amount must be 0 when validating a credit card')
168
166
  end
169
167
  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)
168
+ expect(cc_transaction_amount_0.save).to eq(true)
171
169
  end
172
170
  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')
171
+ expect(ach_transaction_amount_0.save).to eq(false)
172
+ expect(ach_transaction_amount_0.errors.size).to eq(1)
173
+ expect(ach_transaction_amount_0.errors[:type].size).to eq(1)
174
+ expect(ach_transaction_amount_0.errors[:type]).to include('validate is not a valid action for a customer vault that uses a checking account')
178
175
  end
179
176
  end
180
177
 
181
178
  describe "auth" do
179
+ let(:transaction_type) { :auth }
182
180
  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
181
+ expect(cc_transaction.save).to eq(true), cc_transaction.errors.inspect
185
182
  end
186
183
  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')
184
+ expect(cc_transaction_amount_0.save).to eq(false)
185
+ expect(cc_transaction_amount_0.errors.size).to eq(1)
186
+ expect(cc_transaction_amount_0.errors[:amount].size).to eq(1)
187
+ expect(cc_transaction_amount_0.errors[:amount]).to include('Amount cannot be 0 for an authorization')
192
188
  end
193
189
  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')
190
+ expect(ach_transaction.save).to eq(false)
191
+ expect(ach_transaction.errors.size).to eq(1)
192
+ expect(ach_transaction.errors[:type].size).to eq(1)
193
+ expect(ach_transaction.errors[:type]).to include('auth is not a valid action for a customer vault that uses a checking account')
199
194
  end
200
195
  end
201
196
 
202
197
  describe "void" do
198
+ let(:cc_auth) { NmiDirectPost::Transaction.new(customer_vault_id: a_cc_customer_vault_id, amount: amount, type: :auth) }
203
199
  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)
200
+ cc_implicit_sale.save!
201
+ expect(cc_implicit_sale.void!).to eq(true)
207
202
  end
208
203
  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')
204
+ cc_validation.save!
205
+ expect(cc_validation.void!).to eq(false)
206
+ expect(cc_validation.errors.size).to eq(1), cc_validation.errors.inspect
207
+ expect(cc_validation.errors[:type].size).to eq(1), cc_validation.errors.inspect
208
+ expect(cc_validation.errors[:type]).to include('Void is only a valid action for a pending or unsettled authorization, or an unsettled sale')
215
209
  end
216
210
  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
211
+ expect(cc_auth.save).to eq(true), cc_auth.inspect
212
+ expect(cc_auth.void!).to eq(true), cc_auth.inspect
213
+ expect(cc_auth.errors).to be_empty, cc_auth.errors.inspect
221
214
  end
222
215
  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
216
+ cc_auth.save!
217
+ void = NmiDirectPost::Transaction.find_by_transaction_id(cc_auth.transaction_id)
218
+ expect(void.void!).to eq(true), void.inspect
219
+ expect(void.errors).to be_empty, void.errors.inspect
228
220
  end
229
221
  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
222
+ cc_auth.save!
223
+ void = NmiDirectPost::Transaction.new(transaction_id: cc_auth.transaction_id, type: :void)
224
+ expect(void.save).to eq(true), cc_auth.errors.inspect
225
+ expect(void.errors).to be_empty, cc_auth.errors.inspect
235
226
  end
236
227
  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')
228
+ expect(cc_auth.void!).to eq(false), cc_auth.inspect
229
+ expect(cc_auth.errors.size).to eq(1), cc_auth.errors.inspect
230
+ expect(cc_auth.errors[:type].size).to eq(1), cc_auth.errors.inspect
231
+ expect(cc_auth.errors[:type]).to include('Void is only a valid action for a transaction that has already been sent to NMI')
242
232
  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)
233
+
234
+ def expect_error_on_void_for(transaction)
248
235
  expect(transaction.errors.size).to eq(1), transaction.errors.inspect
249
236
  expect(transaction.errors[:type].size).to eq(1), transaction.errors.inspect
250
237
  expect(transaction.errors[:type]).to include('Void is only a valid action for a pending or unsettled authorization, or an unsettled sale')
251
238
  end
239
+
240
+ it "should not be allowed for a voided sale" do
241
+ cc_implicit_sale.save!
242
+ expect(cc_implicit_sale.void!).to eq(true)
243
+ expect(cc_implicit_sale.void!).to eq(false)
244
+ expect_error_on_void_for(cc_implicit_sale)
245
+ void = NmiDirectPost::Transaction.new(transaction_id: cc_implicit_sale.transaction_id, type: :void)
246
+ expect(void.save).to eq(false)
247
+ expect_error_on_void_for(void)
248
+ end
252
249
  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')
250
+ cc_auth.save!
251
+ expect(cc_auth.void!).to eq(true)
252
+ expect(cc_auth.void!).to eq(false)
253
+ expect_error_on_void_for(cc_auth)
254
+
255
+ void = NmiDirectPost::Transaction.new(transaction_id: cc_auth.transaction_id, type: :void)
256
+ expect(void.save).to eq(false)
257
+ expect_error_on_void_for(void)
260
258
  end
261
259
  end
262
260
  end
263
261
 
264
262
  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
263
  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)
264
+ ach_implicit_sale.save!
265
+ transaction = NmiDirectPost::Transaction.find_by_transaction_id(ach_implicit_sale.transaction_id)
266
+ expect(transaction.condition).to eq("pendingsettlement")
267
+ expect(transaction).to be_pending
268
+ expect(transaction).not_to be_cleared
269
+ expect(transaction.amount).to eq(amount)
283
270
  end
284
271
  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)
272
+ cc_implicit_sale.save!
273
+ transaction = NmiDirectPost::Transaction.find_by_transaction_id(cc_implicit_sale.transaction_id)
274
+ expect(transaction.condition).to eq("pendingsettlement")
275
+ expect(transaction).to be_pending
276
+ expect(transaction).not_to be_cleared
277
+ expect(transaction.amount).to eq(amount)
290
278
  end
291
279
  it "should be approved on an existing CC charge" do
292
280
  transaction = NmiDirectPost::Transaction.find_by_transaction_id(TestCredentials::INSTANCE.cc_transaction)
@@ -297,7 +285,6 @@ describe NmiDirectPost::Transaction do
297
285
  end
298
286
 
299
287
  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
288
+ expect{cc_implicit_sale.reload}.not_to raise_error
302
289
  end
303
290
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nmi_direct_post
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Isaac Betesh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-19 00:00:00.000000000 Z
11
+ date: 2015-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,28 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
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'
103
+ version: '4.0'
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - ">="
123
109
  - !ruby/object:Gem::Version
124
- version: '3.0'
110
+ version: '4.0'
125
111
  description: Gem that encapsulates the NMI Direct Post API in an ActiveRecord-like
126
112
  syntax
127
113
  email:
@@ -171,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
157
  version: '0'
172
158
  requirements: []
173
159
  rubyforge_project:
174
- rubygems_version: 2.4.3
160
+ rubygems_version: 2.4.8
175
161
  signing_key:
176
162
  specification_version: 4
177
163
  summary: '# NmiDirectPost NmiDirectPost is a gem that encapsulates the NMI Direct
@@ -181,14 +167,20 @@ summary: '# NmiDirectPost NmiDirectPost is a gem that encapsulates the NMI Dire
181
167
  the boundary between NMI''s Direct Post API and its Query API. This fuzziness is
182
168
  part of the encapsulation. ## Installation Add this line to your application''s
183
169
  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'',
170
+ as: $ gem install nmi_direct_post ## Usage 1) Before you query or post, you probably
171
+ want to set a default username and password: NmiDirectPost::Base.establish_connection("MY_NMI_USERNAME",
172
+ "MY_NMI_PASSWORD") If you don''t set a default, you''ll need to include the username
173
+ and password in the hash passed to the initializer when instantiating a new Transaction
174
+ or CustomerVault. Theoretically, you can use a different connection for NmiDirectPost::Transaction
175
+ or NmiDirectPost::CustomerVault by calling establish_connection on either of those
176
+ derived classes, instead of on Base. However, it''s hard to imagine a case where
177
+ this would be useful; the option is only present to mimic the syntax of ActiveRecord. 2)
178
+ Query the API: NmiDirectPost::Transaction.find_by_transaction_id(123456789, "MyUsername",
179
+ "MyPassword") NmiDirectPost::Transaction.find_by_transaction_id(123456789) # If
180
+ you''ve already called establish_connection NmiDirectPost::CustomerVault.find_by_customer_vault_id(123123123)
181
+ # Note that there is no way to pass a username and password to this method. You
182
+ must call establish_connection beforehand. 3) Create a CustomerVault: george =
183
+ NmiDirectPostCustomerVault.new(:first_name => ''George'', :last_name => ''Washington'',
192
184
  :cc_number => ''4111111111111111'', :cc_exp => ''03/17'') george.create 4) Update
193
185
  a CustomerVault: george.update!(:email => ''el_primero_presidente@whitehouse.gov'',
194
186
  :address_1 => ''1600 Pennsylvania Ave NW'', :city => ''Washington'', :state => ''DC'',
@@ -201,12 +193,13 @@ summary: '# NmiDirectPost NmiDirectPost is a gem that encapsulates the NMI Dire
201
193
  # Returns array of `customer_vault_id`s NmiDirectPost::CustomerVault.first NmiDirectPost::CustomerVault.last
202
194
  NmiDirectPost::CustomerVault.all # Returns very, very big array. This method had
203
195
  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'
196
+ this gem. Note that there is no way to pass a username and password to these methods. You
197
+ must call establish_connection beforehand. 8) Create a Transaction: parking_ticket
198
+ = NmiDirectPost::Transaction(:type => :sale, :amount => 150.01, :customer_vault_id
199
+ => george.customer_vault_id) parking_ticket.save! # Returns true ## Contributing 1.
200
+ Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit
201
+ your changes (`git commit -am ''Add some feature''`) 4. Push to the branch (`git
202
+ push origin my-new-feature`) 5. Create new Pull Request'
210
203
  test_files:
211
204
  - spec/base_spec.rb
212
205
  - spec/customer_vault_spec.rb