nmi_direct_post 0.2.0 → 0.3.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 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