killbill 3.2.4 → 4.0.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.travis.yml +26 -5
  4. data/Gemfile +1 -1
  5. data/Gemfile.head +5 -0
  6. data/Gemfile.lock +125 -0
  7. data/Jarfile +9 -9
  8. data/Jarfile.lock +54 -0
  9. data/NEWS +3 -0
  10. data/README.md +13 -0
  11. data/VERSION +1 -1
  12. data/generators/active_merchant/templates/.gitignore.rb +2 -3
  13. data/generators/active_merchant/templates/.travis.yml.rb +22 -3
  14. data/generators/active_merchant/templates/Gemfile.head.rb +5 -0
  15. data/generators/active_merchant/templates/Gemfile.rb +1 -1
  16. data/generators/active_merchant/templates/Jarfile.rb +9 -8
  17. data/generators/active_merchant/templates/LICENSE.rb +2 -2
  18. data/generators/active_merchant/templates/config.yml.rb +16 -6
  19. data/generators/active_merchant/templates/lib/plugin.rb +0 -1
  20. data/generators/active_merchant/templates/plugin.gemspec.rb +17 -15
  21. data/generators/active_merchant/templates/pom.xml.rb +1 -1
  22. data/generators/active_merchant/templates/release.sh.rb +34 -14
  23. data/generators/active_merchant/templates/spec/base_plugin_spec.rb +5 -7
  24. data/generators/active_merchant/templates/spec/integration_spec.rb +7 -18
  25. data/killbill.gemspec +21 -15
  26. data/lib/killbill/ext/active_merchant/typhoeus_connection.rb +3 -4
  27. data/lib/killbill/gen/api/account.rb +1 -1
  28. data/lib/killbill/gen/api/account_data.rb +1 -1
  29. data/lib/killbill/gen/api/audit_log.rb +2 -2
  30. data/lib/killbill/gen/api/audit_user_api.rb +3 -3
  31. data/lib/killbill/gen/api/block.rb +1 -1
  32. data/lib/killbill/gen/api/blocking_state.rb +1 -1
  33. data/lib/killbill/gen/api/call_context.rb +2 -2
  34. data/lib/killbill/gen/api/control_tag.rb +2 -2
  35. data/lib/killbill/gen/api/currency_conversion.rb +1 -1
  36. data/lib/killbill/gen/api/currency_conversion_api.rb +2 -2
  37. data/lib/killbill/gen/api/custom_field.rb +1 -1
  38. data/lib/killbill/gen/api/custom_field_user_api.rb +2 -2
  39. data/lib/killbill/gen/api/dry_run_arguments.rb +22 -3
  40. data/lib/killbill/gen/api/duration.rb +1 -1
  41. data/lib/killbill/gen/api/entitlement.rb +3 -3
  42. data/lib/killbill/gen/api/entitlement_ao_status_dry_run.rb +3 -3
  43. data/lib/killbill/gen/api/entitlement_api.rb +25 -7
  44. data/lib/killbill/gen/api/fixed.rb +1 -1
  45. data/lib/killbill/gen/api/invoice.rb +1 -1
  46. data/lib/killbill/gen/api/invoice_formatter.rb +2 -2
  47. data/lib/killbill/gen/api/invoice_item.rb +2 -2
  48. data/lib/killbill/gen/api/invoice_item_formatter.rb +2 -2
  49. data/lib/killbill/gen/api/invoice_payment.rb +3 -3
  50. data/lib/killbill/gen/api/invoice_user_api.rb +2 -2
  51. data/lib/killbill/gen/api/migration_plan.rb +1 -1
  52. data/lib/killbill/gen/api/mutable_account_data.rb +1 -1
  53. data/lib/killbill/gen/api/payment.rb +1 -1
  54. data/lib/killbill/gen/api/payment_api.rb +11 -11
  55. data/lib/killbill/gen/api/payment_transaction.rb +4 -4
  56. data/lib/killbill/gen/api/plan.rb +1 -1
  57. data/lib/killbill/gen/api/plan_change_result.rb +2 -2
  58. data/lib/killbill/gen/api/plan_phase.rb +1 -1
  59. data/lib/killbill/gen/api/plan_phase_price_override.rb +93 -0
  60. data/lib/killbill/gen/api/plan_phase_price_overrides_with_call_context.rb +77 -0
  61. data/lib/killbill/gen/api/plan_phase_specifier.rb +3 -3
  62. data/lib/killbill/gen/api/plan_specifier.rb +2 -2
  63. data/lib/killbill/gen/api/price.rb +1 -1
  64. data/lib/killbill/gen/api/product.rb +1 -1
  65. data/lib/killbill/gen/api/rate.rb +2 -2
  66. data/lib/killbill/gen/api/record_id_api.rb +1 -1
  67. data/lib/killbill/gen/api/recurring.rb +1 -1
  68. data/lib/killbill/gen/api/refund.rb +2 -2
  69. data/lib/killbill/gen/api/require_gen.rb +2 -0
  70. data/lib/killbill/gen/api/static_catalog.rb +2 -2
  71. data/lib/killbill/gen/api/subscription.rb +3 -3
  72. data/lib/killbill/gen/api/subscription_event.rb +3 -3
  73. data/lib/killbill/gen/api/tag.rb +1 -1
  74. data/lib/killbill/gen/api/tag_definition.rb +1 -1
  75. data/lib/killbill/gen/api/tag_user_api.rb +6 -6
  76. data/lib/killbill/gen/api/tiered_block.rb +1 -1
  77. data/lib/killbill/gen/api/usage.rb +3 -3
  78. data/lib/killbill/gen/plugin-api/currency_plugin_api.rb +1 -1
  79. data/lib/killbill/gen/plugin-api/ext_bus_event.rb +2 -2
  80. data/lib/killbill/gen/plugin-api/payment_transaction_info_plugin.rb +3 -3
  81. data/lib/killbill/helpers/active_merchant.rb +2 -2
  82. data/lib/killbill/helpers/active_merchant/active_record.rb +1 -1
  83. data/lib/killbill/helpers/active_merchant/active_record/active_record_helper.rb +14 -0
  84. data/lib/killbill/helpers/active_merchant/active_record/models/helpers.rb +8 -0
  85. data/lib/killbill/helpers/active_merchant/active_record/models/payment_method.rb +10 -8
  86. data/lib/killbill/helpers/active_merchant/active_record/models/response.rb +16 -3
  87. data/lib/killbill/helpers/active_merchant/active_record/models/streamy_result_set.rb +1 -3
  88. data/lib/killbill/helpers/active_merchant/active_record/models/transaction.rb +2 -0
  89. data/lib/killbill/helpers/active_merchant/configuration.rb +119 -27
  90. data/lib/killbill/helpers/active_merchant/gateway.rb +40 -27
  91. data/lib/killbill/helpers/active_merchant/killbill_spec_helper.rb +63 -45
  92. data/lib/killbill/helpers/active_merchant/payment_plugin.rb +121 -95
  93. data/lib/killbill/helpers/active_merchant/private_payment_plugin.rb +1 -1
  94. data/lib/killbill/helpers/active_merchant/properties.rb +9 -2
  95. data/lib/killbill/helpers/active_merchant/sinatra.rb +4 -8
  96. data/lib/killbill/helpers/active_merchant/utils.rb +44 -0
  97. data/lib/killbill/helpers/properties_helper.rb +41 -0
  98. data/lib/killbill/http_servlet.rb +11 -4
  99. data/lib/killbill/killbill_api.rb +6 -4
  100. data/lib/killbill/rake_task.rb +542 -102
  101. data/spec/killbill/helpers/configuration_spec.rb +117 -33
  102. data/spec/killbill/helpers/payment_method_spec.rb +20 -17
  103. data/spec/killbill/helpers/payment_plugin_spec.rb +401 -201
  104. data/spec/killbill/helpers/private_payment_plugin_spec.rb +3 -16
  105. data/spec/killbill/helpers/response_spec.rb +92 -22
  106. data/spec/killbill/helpers/streamy_result_set_spec.rb +3 -2
  107. data/spec/killbill/helpers/test_payment_method.rb +9 -0
  108. data/spec/killbill/helpers/test_response.rb +11 -0
  109. data/spec/killbill/helpers/test_schema.rb +6 -6
  110. data/spec/killbill/helpers/test_transaction.rb +11 -0
  111. data/spec/killbill/helpers/transaction_spec.rb +3 -13
  112. data/spec/killbill/helpers/utils_spec.rb +127 -69
  113. data/spec/spec_helper.rb +69 -18
  114. metadata +77 -71
  115. data/lib/killbill/ext/active_merchant/jdbc_connection.rb +0 -92
  116. data/lib/killbill/ext/active_merchant/proxy_support.rb +0 -58
  117. data/spec/killbill/helpers/gateway_spec.rb +0 -36
@@ -2,16 +2,22 @@ require 'spec_helper'
2
2
 
3
3
  describe Killbill::Plugin::ActiveMerchant do
4
4
 
5
- before(:all) do
6
- @logger = Logger.new(STDOUT)
7
- @logger.level = Logger::INFO
8
-
9
- @call_context = Killbill::Plugin::Model::CallContext.new
10
- @call_context.tenant_id = '00001011-a022-b033-0055-aa0000000066'
11
- @call_context = @call_context.to_ruby(@call_context)
5
+ let(:logger) do
6
+ logger = Logger.new(STDOUT)
7
+ logger.level = Logger::INFO
8
+ logger
9
+ end
12
10
 
11
+ let(:call_context) do
12
+ call_context = Killbill::Plugin::Model::CallContext.new
13
+ call_context.tenant_id = '00001011-a022-b033-0055-aa0000000066'
14
+ call_context.to_ruby(call_context)
13
15
  end
14
16
 
17
+ it 'supports deployments without global configuration' do
18
+ do_initialize_with_config_path!('')
19
+ do_initialize_with_config_path!(nil)
20
+ end
15
21
 
16
22
  it 'should support multi-tenancy configurations' do
17
23
  do_initialize!(<<-eos)
@@ -22,7 +28,7 @@ describe Killbill::Plugin::ActiveMerchant do
22
28
 
23
29
  do_common_checks
24
30
 
25
- gw = ::Killbill::Plugin::ActiveMerchant.gateways(@call_context.tenant_id)
31
+ gw = ::Killbill::Plugin::ActiveMerchant.gateways(call_context.tenant_id)
26
32
  gw.size.should == 1
27
33
  gw[:default][:login].should == 'admin2'
28
34
  gw[:default][:password].should == 'password2'
@@ -105,6 +111,64 @@ describe Killbill::Plugin::ActiveMerchant do
105
111
  gw[:default][:password].should == 'password_1'
106
112
  end
107
113
 
114
+ it 'should honor ActiveMerchant configuration options' do
115
+ do_initialize!
116
+ do_common_checks
117
+ verify_active_merchant_config
118
+
119
+ do_initialize!(<<-eos)
120
+ :retry_safe: true
121
+ :open_timeout: 12
122
+ :ssl_version: 5
123
+ :ssl_strict: false
124
+ eos
125
+ do_common_checks
126
+ verify_active_merchant_config(:retry_safe => true, :open_timeout => 12, :ssl_version => 5, :ssl_strict => false)
127
+ end
128
+
129
+ it 'overrides ActiveMerchant urls' do
130
+ # Verify we don't override the defaults
131
+ do_initialize!
132
+ ::ActiveMerchant::Billing::WorldpayGateway.test_url.should == 'https://secure-test.worldpay.com/jsp/merchant/xml/paymentService.jsp'
133
+ ::ActiveMerchant::Billing::WorldpayGateway.live_url.should == 'https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp'
134
+
135
+ # Override both the test and live urls
136
+ do_initialize!({:test_url => 'https://test.killbill.io', :live_url => 'https://live.killbill.io'},
137
+ database_config,
138
+ Proc.new { ::ActiveMerchant::Billing::WorldpayGateway.new :login => 'login', :password => 'password' })
139
+
140
+ gw = ::Killbill::Plugin::ActiveMerchant.gateways
141
+ gw.size.should == 1
142
+ # Verify the attributes have been updated on both the gateway instance and on the class (implementations may use both)
143
+ gw[:default].test_url.should == 'https://test.killbill.io'
144
+ gw[:default].live_url.should == 'https://live.killbill.io'
145
+ ::ActiveMerchant::Billing::WorldpayGateway.test_url.should == 'https://test.killbill.io'
146
+ ::ActiveMerchant::Billing::WorldpayGateway.live_url.should == 'https://live.killbill.io'
147
+ end
148
+
149
+ it 'sets up false pool with jndi database configuration' do
150
+ db_config = { :adapter => 'mysql2', :jndi => 'jdbc/MyDB', :pool => false }
151
+
152
+ ActiveRecord::Base.should_receive(:establish_connection).with(db_config).once
153
+ do_initialize!({ :test => true }, db_config)
154
+
155
+ pool_class = ActiveRecord::Base.connection_handler.connection_pool_class
156
+ expect( pool_class ).to be ActiveRecord::Bogacs::FalsePool
157
+ end
158
+
159
+ it 'interprets the config file through ERB' do
160
+ value = '<%= 12 %>'
161
+ do_initialize!({ :key => value })
162
+ ::Killbill::Plugin::ActiveMerchant.config[:test][:key].should == 12
163
+ end
164
+
165
+ after do
166
+ if ::ActiveRecord::ConnectionAdapters::ConnectionHandler.respond_to?(:connection_pool_class=)
167
+ pool_class = ::ActiveRecord::ConnectionAdapters::ConnectionPool # restore if Bogacs loaded
168
+ ::ActiveRecord::ConnectionAdapters::ConnectionHandler.connection_pool_class = pool_class
169
+ end
170
+ end
171
+
108
172
  private
109
173
 
110
174
  def do_common_checks
@@ -112,40 +176,60 @@ describe Killbill::Plugin::ActiveMerchant do
112
176
  ::Killbill::Plugin::ActiveMerchant.currency_conversions.should be_nil
113
177
  ::Killbill::Plugin::ActiveMerchant.initialized.should be_true
114
178
  ::Killbill::Plugin::ActiveMerchant.kb_apis.should_not be_nil
115
- ::Killbill::Plugin::ActiveMerchant.logger.should == @logger
179
+ ::Killbill::Plugin::ActiveMerchant.logger.should == logger
180
+ end
181
+
182
+ def verify_active_merchant_config(config = {})
183
+ ::ActiveMerchant::Billing::Gateway.open_timeout.should == (config.has_key?(:open_timeout) ? config[:open_timeout] : 60)
184
+ ::ActiveMerchant::Billing::Gateway.read_timeout.should == (config.has_key?(:read_timeout) ? config[:read_timeout] : 60)
185
+ ::ActiveMerchant::Billing::Gateway.retry_safe.should == (config.has_key?(:retry_safe) ? config[:retry_safe] : false)
186
+ ::ActiveMerchant::Billing::Gateway.ssl_strict.should == (config.has_key?(:ssl_strict) ? config[:ssl_strict] : true)
187
+ ::ActiveMerchant::Billing::Gateway.ssl_version.should == (config.has_key?(:ssl_version) ? config[:ssl_version] : nil)
188
+ ::ActiveMerchant::Billing::Gateway.max_retries.should == (config.has_key?(:max_retries) ? config[:max_retries] : 3)
189
+ ::ActiveMerchant::Billing::Gateway.proxy_address.should == (config.has_key?(:proxy_address) ? config[:proxy_address] : nil)
190
+ ::ActiveMerchant::Billing::Gateway.proxy_port.should == (config.has_key?(:proxy_port) ? config[:proxy_port] : nil)
116
191
  end
117
192
 
118
- def do_initialize!(extra_config='')
193
+ def do_initialize!(extra_config = '', db_config = database_config, gw_builder = Proc.new { |config| config })
194
+ extra_config_yaml = ''; db_config_yaml = ''
195
+
196
+ [[extra_config, extra_config_yaml],
197
+ [db_config, db_config_yaml]].each do |config, config_yaml|
198
+ if config.is_a?(String)
199
+ config_yaml.replace(config)
200
+ else
201
+ config.to_yaml.sub("---\n", '').each_line { |line| config_yaml << " #{line}" } # indent
202
+ end
203
+ end
204
+
119
205
  Dir.mktmpdir do |dir|
120
- file = File.new(File.join(dir, 'test.yml'), 'w+')
121
- file.write(<<-eos)
122
- :test:
123
- #{extra_config}
124
- # As defined by spec_helper.rb
125
- :database:
126
- :adapter: 'sqlite3'
127
- :database: 'test.db'
128
- eos
129
- file.close
206
+ File.open(path = File.join(dir, 'test.yml'), 'w+') do |file|
207
+ file.write(":test:\n#{extra_config_yaml}:database:\n#{db_config_yaml}")
208
+ file.close
209
+ do_initialize_with_config_path!(file.path, gw_builder)
210
+ end
211
+ end
212
+ end
213
+
214
+ def do_initialize_with_config_path!(path = nil, gw_builder = Proc.new { |config| config })
215
+ ::Killbill::Plugin::ActiveMerchant.initialize!(gw_builder,
216
+ :test,
217
+ logger,
218
+ :KEY,
219
+ path,
220
+ ::Killbill::Plugin::KillbillApi.new('test', svcs_with_per_tenant_config))
221
+ end
130
222
 
131
- per_tenant_config =<<-oes
223
+ def svcs_with_per_tenant_config
224
+ per_tenant_config =<<-oes
132
225
  :test:
133
226
  :login: admin2
134
227
  :password: password2
135
228
  :database:
136
229
  :adapter: 'sqlite3'
137
230
  :database: 'test.db'
138
- oes
139
-
140
- @tenant_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaTenantUserApi.new({@call_context.tenant_id => per_tenant_config})
141
- svcs = {:tenant_user_api => @tenant_api}
142
-
143
- ::Killbill::Plugin::ActiveMerchant.initialize! Proc.new { |config| config },
144
- :test,
145
- @logger,
146
- :KEY,
147
- file.path,
148
- ::Killbill::Plugin::KillbillApi.new('test', svcs)
149
- end
231
+ oes
232
+ @tenant_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaTenantUserApi.new({call_context.tenant_id => per_tenant_config})
233
+ {:tenant_user_api => @tenant_api}
150
234
  end
151
235
  end
@@ -1,15 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Killbill #:nodoc:
4
- module Test #:nodoc:
5
- class TestPaymentMethod < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod
6
-
7
- self.table_name = 'test_payment_methods'
8
-
9
- end
10
- end
11
- end
12
-
13
3
  describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
14
4
 
15
5
  before :each do
@@ -176,7 +166,12 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
176
166
  :city => 'city',
177
167
  :state => 'state',
178
168
  :zip => 'zip',
179
- :country => 'country'
169
+ :country => 'country',
170
+ :created_at => Time.now.utc,
171
+ :updated_at => Time.now.utc
172
+
173
+ pm.created_at.should_not be_nil
174
+ pm.updated_at.should_not be_nil
180
175
 
181
176
  pm = ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(pm.kb_payment_method_id, pm.kb_tenant_id)
182
177
  pm.cc_exp_month.should == '07'
@@ -187,21 +182,21 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
187
182
 
188
183
  it 'should generate the right SQL query' do
189
184
  # Check count query (search query numeric)
190
- expected_query = "SELECT COUNT(DISTINCT \"test_payment_methods\".\"id\") FROM \"test_payment_methods\" WHERE ((((((((((((((\"test_payment_methods\".\"kb_account_id\" = '1234' OR \"test_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"test_payment_methods\".\"token\" = '1234') OR \"test_payment_methods\".\"cc_type\" = '1234') OR \"test_payment_methods\".\"state\" = '1234') OR \"test_payment_methods\".\"zip\" = '1234') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"test_payment_methods\".\"address1\" LIKE '%1234%') OR \"test_payment_methods\".\"address2\" LIKE '%1234%') OR \"test_payment_methods\".\"city\" LIKE '%1234%') OR \"test_payment_methods\".\"country\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_exp_month\" = '1234') OR \"test_payment_methods\".\"cc_exp_year\" = '1234') OR \"test_payment_methods\".\"cc_last_4\" = '1234') AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\""
185
+ expected_query = "SELECT COUNT(DISTINCT #{q('test_payment_methods')}.#{q('id')}) FROM #{q('test_payment_methods')} WHERE ((((((((((((((#{q('test_payment_methods')}.#{q('kb_account_id')} = '1234' OR #{q('test_payment_methods')}.#{q('kb_payment_method_id')} = '1234') OR #{q('test_payment_methods')}.#{q('token')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_type')} = '1234') OR #{q('test_payment_methods')}.#{q('state')} = '1234') OR #{q('test_payment_methods')}.#{q('zip')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_first_name')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('cc_last_name')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('address1')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('address2')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('city')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('country')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('cc_exp_month')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_exp_year')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_last_4')} = '1234') AND #{q('test_payment_methods')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_payment_methods')}.#{q('id')}"
191
186
  # Note that Kill Bill will pass a String, even for numeric types
192
187
  ::Killbill::Test::TestPaymentMethod.search_query('1234', '11-22-33').to_sql.should == expected_query
193
188
 
194
189
  # Check query with results (search query numeric)
195
- expected_query = "SELECT DISTINCT \"test_payment_methods\".* FROM \"test_payment_methods\" WHERE ((((((((((((((\"test_payment_methods\".\"kb_account_id\" = '1234' OR \"test_payment_methods\".\"kb_payment_method_id\" = '1234') OR \"test_payment_methods\".\"token\" = '1234') OR \"test_payment_methods\".\"cc_type\" = '1234') OR \"test_payment_methods\".\"state\" = '1234') OR \"test_payment_methods\".\"zip\" = '1234') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%1234%') OR \"test_payment_methods\".\"address1\" LIKE '%1234%') OR \"test_payment_methods\".\"address2\" LIKE '%1234%') OR \"test_payment_methods\".\"city\" LIKE '%1234%') OR \"test_payment_methods\".\"country\" LIKE '%1234%') OR \"test_payment_methods\".\"cc_exp_month\" = '1234') OR \"test_payment_methods\".\"cc_exp_year\" = '1234') OR \"test_payment_methods\".\"cc_last_4\" = '1234') AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
190
+ expected_query = "SELECT DISTINCT #{q('test_payment_methods')}.* FROM #{q('test_payment_methods')} WHERE ((((((((((((((#{q('test_payment_methods')}.#{q('kb_account_id')} = '1234' OR #{q('test_payment_methods')}.#{q('kb_payment_method_id')} = '1234') OR #{q('test_payment_methods')}.#{q('token')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_type')} = '1234') OR #{q('test_payment_methods')}.#{q('state')} = '1234') OR #{q('test_payment_methods')}.#{q('zip')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_first_name')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('cc_last_name')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('address1')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('address2')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('city')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('country')} LIKE '%1234%') OR #{q('test_payment_methods')}.#{q('cc_exp_month')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_exp_year')} = '1234') OR #{q('test_payment_methods')}.#{q('cc_last_4')} = '1234') AND #{q('test_payment_methods')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_payment_methods')}.#{q('id')} LIMIT 10 OFFSET 0"
196
191
  # Note that Kill Bill will pass a String, even for numeric types
197
192
  ::Killbill::Test::TestPaymentMethod.search_query('1234', '11-22-33', 0, 10).to_sql.should == expected_query
198
193
 
199
194
  # Check count query (search query string)
200
- expected_query = "SELECT COUNT(DISTINCT \"test_payment_methods\".\"id\") FROM \"test_payment_methods\" WHERE (((((((((((\"test_payment_methods\".\"kb_account_id\" = 'XXX' OR \"test_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"test_payment_methods\".\"token\" = 'XXX') OR \"test_payment_methods\".\"cc_type\" = 'XXX') OR \"test_payment_methods\".\"state\" = 'XXX') OR \"test_payment_methods\".\"zip\" = 'XXX') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"address1\" LIKE '%XXX%') OR \"test_payment_methods\".\"address2\" LIKE '%XXX%') OR \"test_payment_methods\".\"city\" LIKE '%XXX%') OR \"test_payment_methods\".\"country\" LIKE '%XXX%') AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\""
195
+ expected_query = "SELECT COUNT(DISTINCT #{q('test_payment_methods')}.#{q('id')}) FROM #{q('test_payment_methods')} WHERE (((((((((((#{q('test_payment_methods')}.#{q('kb_account_id')} = 'XXX' OR #{q('test_payment_methods')}.#{q('kb_payment_method_id')} = 'XXX') OR #{q('test_payment_methods')}.#{q('token')} = 'XXX') OR #{q('test_payment_methods')}.#{q('cc_type')} = 'XXX') OR #{q('test_payment_methods')}.#{q('state')} = 'XXX') OR #{q('test_payment_methods')}.#{q('zip')} = 'XXX') OR #{q('test_payment_methods')}.#{q('cc_first_name')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('cc_last_name')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('address1')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('address2')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('city')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('country')} LIKE '%XXX%') AND #{q('test_payment_methods')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_payment_methods')}.#{q('id')}"
201
196
  ::Killbill::Test::TestPaymentMethod.search_query('XXX', '11-22-33').to_sql.should == expected_query
202
197
 
203
198
  # Check query with results (search query string)
204
- expected_query = "SELECT DISTINCT \"test_payment_methods\".* FROM \"test_payment_methods\" WHERE (((((((((((\"test_payment_methods\".\"kb_account_id\" = 'XXX' OR \"test_payment_methods\".\"kb_payment_method_id\" = 'XXX') OR \"test_payment_methods\".\"token\" = 'XXX') OR \"test_payment_methods\".\"cc_type\" = 'XXX') OR \"test_payment_methods\".\"state\" = 'XXX') OR \"test_payment_methods\".\"zip\" = 'XXX') OR \"test_payment_methods\".\"cc_first_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"cc_last_name\" LIKE '%XXX%') OR \"test_payment_methods\".\"address1\" LIKE '%XXX%') OR \"test_payment_methods\".\"address2\" LIKE '%XXX%') OR \"test_payment_methods\".\"city\" LIKE '%XXX%') OR \"test_payment_methods\".\"country\" LIKE '%XXX%') AND \"test_payment_methods\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_payment_methods\".\"id\" LIMIT 10 OFFSET 0"
199
+ expected_query = "SELECT DISTINCT #{q('test_payment_methods')}.* FROM #{q('test_payment_methods')} WHERE (((((((((((#{q('test_payment_methods')}.#{q('kb_account_id')} = 'XXX' OR #{q('test_payment_methods')}.#{q('kb_payment_method_id')} = 'XXX') OR #{q('test_payment_methods')}.#{q('token')} = 'XXX') OR #{q('test_payment_methods')}.#{q('cc_type')} = 'XXX') OR #{q('test_payment_methods')}.#{q('state')} = 'XXX') OR #{q('test_payment_methods')}.#{q('zip')} = 'XXX') OR #{q('test_payment_methods')}.#{q('cc_first_name')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('cc_last_name')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('address1')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('address2')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('city')} LIKE '%XXX%') OR #{q('test_payment_methods')}.#{q('country')} LIKE '%XXX%') AND #{q('test_payment_methods')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_payment_methods')}.#{q('id')} LIMIT 10 OFFSET 0"
205
200
  ::Killbill::Test::TestPaymentMethod.search_query('XXX', '11-22-33', 0, 10).to_sql.should == expected_query
206
201
  end
207
202
 
@@ -222,7 +217,9 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
222
217
  :city => 'city',
223
218
  :state => 'state',
224
219
  :zip => 'zip',
225
- :country => 'country'
220
+ :country => 'country',
221
+ :created_at => Time.now.utc,
222
+ :updated_at => Time.now.utc
226
223
 
227
224
  do_search('foo').size.should == 0
228
225
  do_search('ccType').size.should == 1
@@ -247,7 +244,9 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
247
244
  :city => 'city',
248
245
  :state => 'state',
249
246
  :zip => 'zip',
250
- :country => 'country'
247
+ :country => 'country',
248
+ :created_at => Time.now.utc,
249
+ :updated_at => Time.now.utc
251
250
 
252
251
  do_search('foo').size.should == 0
253
252
  do_search('ccType').size.should == 2
@@ -283,4 +282,8 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
283
282
  pmip.payment_method_id.should == kb_payment_method_id
284
283
  pmip.external_payment_method_id.should == external_payment_method_id
285
284
  end
285
+
286
+ def q(arg)
287
+ ::ActiveRecord::Base.connection.quote_column_name(arg)
288
+ end
286
289
  end
@@ -1,227 +1,408 @@
1
1
  require 'spec_helper'
2
- require 'spec/killbill/helpers/payment_method_spec'
3
- require 'spec/killbill/helpers/response_spec'
4
- require 'spec/killbill/helpers/transaction_spec'
5
2
 
6
3
  describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
7
4
  include Killbill::Plugin::ActiveMerchant::RSpec
8
5
 
9
- before(:all) do
10
- Dir.mktmpdir do |dir|
11
- file = File.new(File.join(dir, 'test.yml'), "w+")
12
- file.write(<<-eos)
13
- :test:
14
- - :account_id: default
15
- :test: true
16
- - :account_id: something_non_standard
17
- :test: true
18
- # As defined by spec_helper.rb
19
- :database:
20
- :adapter: 'sqlite3'
21
- :database: 'test.db'
22
- eos
23
- file.close
24
-
25
- @plugin = ::Killbill::Plugin::ActiveMerchant::PaymentPlugin.new(Proc.new { |config| nil },
26
- :test,
27
- ::Killbill::Test::TestPaymentMethod,
28
- ::Killbill::Test::TestTransaction,
29
- ::Killbill::Test::TestResponse)
30
- @payment_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaPaymentApi.new
31
- @tenant_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaTenantUserApi.new({})
32
-
33
- @plugin.kb_apis = ::Killbill::Plugin::KillbillApi.new('test', {:payment_api => @payment_api, :tenant_user_api => @tenant_api})
34
- @plugin.logger = Logger.new(STDOUT)
35
- @plugin.logger.level = Logger::INFO
36
- @plugin.conf_dir = File.dirname(file)
37
- @plugin.root = File.dirname(file)
38
-
39
- # Start the plugin here - since the config file will be deleted
40
- @plugin.start_plugin
41
- end
6
+ let(:payment_api) { ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaPaymentApi.new }
7
+ let(:tenant_api) { ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaTenantUserApi.new }
8
+ let(:kb_apis) { ::Killbill::Plugin::KillbillApi.new('test', {:payment_api => payment_api, :tenant_user_api => tenant_api}) }
9
+ let(:logger) do
10
+ logger = Logger.new(STDOUT)
11
+ logger.level = Logger::INFO
12
+ logger
42
13
  end
43
14
 
44
15
  before(:each) do
45
- @kb_account_id = SecureRandom.uuid
46
- @kb_payment_id = SecureRandom.uuid
16
+ @kb_account_id = SecureRandom.uuid
17
+ @kb_payment_id = SecureRandom.uuid
47
18
  @kb_payment_method_id = SecureRandom.uuid
48
19
 
49
- @amount_in_cents = rand(100000)
50
- @currency = 'USD'
51
- @call_context = Killbill::Plugin::Model::CallContext.new
20
+ @amount_in_cents = rand(100000)
21
+ @currency = 'USD'
22
+ @call_context = Killbill::Plugin::Model::CallContext.new
52
23
  @call_context.tenant_id = SecureRandom.uuid
53
24
 
54
- property = ::Killbill::Plugin::Model::PluginProperty.new
55
- property.key = 'skip_gw'
56
- property.value = 'true'
57
- @properties = [property]
58
-
59
- @ppai = ::Killbill::Plugin::Model::PluginProperty.new
60
- @ppai.key = 'payment_processor_account_id'
61
- @ppai.value = 'something_non_standard'
62
- @properties_with_ppai = @properties.dup
63
- @properties_with_ppai << @ppai
64
-
65
- token = ::Killbill::Plugin::Model::PluginProperty.new
66
- token.key = 'token'
67
- token.value = SecureRandom.uuid
68
- @payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
25
+ token = ::Killbill::Plugin::Model::PluginProperty.new
26
+ token.key = 'token'
27
+ token.value = SecureRandom.uuid
28
+ @payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
69
29
  @payment_method_props.properties = [token]
70
30
  end
71
31
 
72
- after(:all) do
73
- @plugin.stop_plugin
74
- end
32
+ context 'when skipping the gateway' do
33
+ let(:plugin) do
34
+ plugin = ::Killbill::Plugin::ActiveMerchant::PaymentPlugin.new(Proc.new { |config| nil },
35
+ :test,
36
+ ::Killbill::Test::TestPaymentMethod,
37
+ ::Killbill::Test::TestTransaction,
38
+ ::Killbill::Test::TestResponse)
39
+ plugin.kb_apis = kb_apis
40
+ plugin.logger = logger
41
+
42
+ plugin_config = {
43
+ :test => [
44
+ {:account_id => 'default', :test => true},
45
+ {:account_id => 'something_non_standard', :test => true}
46
+ ]
47
+ }
48
+ with_plugin_yaml_config('test.yml', plugin_config) do |file|
49
+ plugin.conf_dir = File.dirname(file)
50
+ plugin.root = File.dirname(file)
51
+
52
+ # Start the plugin here - since the config file will be deleted
53
+ plugin.start_plugin
54
+ end
55
+
56
+ plugin
57
+ end
75
58
 
76
- it 'should implement payment plugin API calls' do
77
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
78
-
79
- @plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, @properties, @call_context)
80
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 1
81
- ::Killbill::Test::TestPaymentMethod.where(:kb_payment_method_id => @kb_payment_method_id).first.token.should == @payment_method_props.properties[0].value
82
-
83
- authorization_id = SecureRandom.uuid
84
- @payment_api.add_payment(@kb_payment_id, authorization_id, SecureRandom.uuid, :AUTHORIZE)
85
- authorization = @plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
86
- verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1)
87
-
88
- capture_id = SecureRandom.uuid
89
- @payment_api.add_payment(@kb_payment_id, capture_id, SecureRandom.uuid, :CAPTURE)
90
- capture = @plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
91
- verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2)
92
-
93
- purchase_id = SecureRandom.uuid
94
- @payment_api.add_payment(@kb_payment_id, purchase_id, SecureRandom.uuid, :PURCHASE)
95
- purchase = @plugin.purchase_payment(@kb_account_id, @kb_payment_id, purchase_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
96
- verify_transaction_info_plugin(purchase, purchase_id, :PURCHASE, 3)
97
-
98
- void_id = SecureRandom.uuid
99
- @payment_api.add_payment(@kb_payment_id, void_id, SecureRandom.uuid, :VOID)
100
- void = @plugin.void_payment(@kb_account_id, @kb_payment_id, void_id, @kb_payment_method_id, @properties, @call_context)
101
- verify_transaction_info_plugin(void, void_id, :VOID, 4)
102
-
103
- credit_id = SecureRandom.uuid
104
- @payment_api.add_payment(@kb_payment_id, credit_id, SecureRandom.uuid, :CREDIT)
105
- credit = @plugin.credit_payment(@kb_account_id, @kb_payment_id, credit_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
106
- verify_transaction_info_plugin(credit, credit_id, :CREDIT, 5)
107
-
108
- refund_id = SecureRandom.uuid
109
- @payment_api.add_payment(@kb_payment_id, refund_id, SecureRandom.uuid, :REFUND)
110
- refund = @plugin.refund_payment(@kb_account_id, @kb_payment_id, refund_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
111
- verify_transaction_info_plugin(refund, refund_id, :REFUND, 6)
112
-
113
- @plugin.delete_payment_method(@kb_account_id, @kb_payment_method_id, @properties, @call_context)
114
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
115
- end
59
+ before(:each) do
60
+ property = ::Killbill::Plugin::Model::PluginProperty.new
61
+ property.key = 'skip_gw'
62
+ property.value = 'true'
63
+ @properties = [property]
64
+
65
+ @ppai = ::Killbill::Plugin::Model::PluginProperty.new
66
+ @ppai.key = 'payment_processor_account_id'
67
+ @ppai.value = 'something_non_standard'
68
+ @properties_with_ppai = @properties.dup
69
+ @properties_with_ppai << @ppai
70
+ end
71
+
72
+ after(:all) do
73
+ plugin.stop_plugin
74
+ end
116
75
 
117
- it 'should support different payment_processor_account_ids' do
118
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
76
+ it 'should implement payment plugin API calls' do
77
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
78
+
79
+ plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, @properties, @call_context)
80
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 1
81
+ ::Killbill::Test::TestPaymentMethod.where(:kb_payment_method_id => @kb_payment_method_id).first.token.should == @payment_method_props.properties[0].value
82
+
83
+ authorization_id = SecureRandom.uuid
84
+ payment_api.add_payment(@kb_payment_id, authorization_id, SecureRandom.uuid, :AUTHORIZE)
85
+ authorization = plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
86
+ verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1)
87
+
88
+ capture_id = SecureRandom.uuid
89
+ payment_api.add_payment(@kb_payment_id, capture_id, SecureRandom.uuid, :CAPTURE)
90
+ capture = plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
91
+ verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2)
92
+
93
+ purchase_id = SecureRandom.uuid
94
+ payment_api.add_payment(@kb_payment_id, purchase_id, SecureRandom.uuid, :PURCHASE)
95
+ purchase = plugin.purchase_payment(@kb_account_id, @kb_payment_id, purchase_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
96
+ verify_transaction_info_plugin(purchase, purchase_id, :PURCHASE, 3)
97
+
98
+ void_id = SecureRandom.uuid
99
+ payment_api.add_payment(@kb_payment_id, void_id, SecureRandom.uuid, :VOID)
100
+ void = plugin.void_payment(@kb_account_id, @kb_payment_id, void_id, @kb_payment_method_id, @properties, @call_context)
101
+ verify_transaction_info_plugin(void, void_id, :VOID, 4)
102
+
103
+ credit_id = SecureRandom.uuid
104
+ payment_api.add_payment(@kb_payment_id, credit_id, SecureRandom.uuid, :CREDIT)
105
+ credit = plugin.credit_payment(@kb_account_id, @kb_payment_id, credit_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
106
+ verify_transaction_info_plugin(credit, credit_id, :CREDIT, 5)
107
+
108
+ refund_id = SecureRandom.uuid
109
+ payment_api.add_payment(@kb_payment_id, refund_id, SecureRandom.uuid, :REFUND)
110
+ refund = plugin.refund_payment(@kb_account_id, @kb_payment_id, refund_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
111
+ verify_transaction_info_plugin(refund, refund_id, :REFUND, 6)
112
+
113
+ plugin.delete_payment_method(@kb_account_id, @kb_payment_method_id, @properties, @call_context)
114
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
115
+ end
119
116
 
120
- @plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, @properties, @call_context)
121
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 1
122
- ::Killbill::Test::TestPaymentMethod.where(:kb_payment_method_id => @kb_payment_method_id).first.token.should == @payment_method_props.properties[0].value
117
+ it 'should support different payment_processor_account_ids' do
118
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
123
119
 
124
- authorization_id = SecureRandom.uuid
125
- @payment_api.add_payment(@kb_payment_id, authorization_id, SecureRandom.uuid, :AUTHORIZE)
126
- authorization = @plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties_with_ppai, @call_context)
127
- verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1, @ppai.value)
120
+ plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, @properties, @call_context)
121
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 1
122
+ ::Killbill::Test::TestPaymentMethod.where(:kb_payment_method_id => @kb_payment_method_id).first.token.should == @payment_method_props.properties[0].value
128
123
 
129
- capture_id = SecureRandom.uuid
130
- @payment_api.add_payment(@kb_payment_id, capture_id, SecureRandom.uuid, :CAPTURE)
131
- # We omit the payment_processor_account_id to verify we can retrieve it
132
- capture = @plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
133
- verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2, @ppai.value)
134
- end
124
+ authorization_id = SecureRandom.uuid
125
+ payment_api.add_payment(@kb_payment_id, authorization_id, SecureRandom.uuid, :AUTHORIZE)
126
+ authorization = plugin.authorize_payment(@kb_account_id, @kb_payment_id, authorization_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties_with_ppai, @call_context)
127
+ verify_transaction_info_plugin(authorization, authorization_id, :AUTHORIZE, 1, @ppai.value)
135
128
 
136
- it 'should support storing a credit card' do
137
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
138
-
139
- properties = []
140
- properties << create_pm_kv_info('ccNumber', '41111111111111111')
141
- properties << create_pm_kv_info('ccFirstName', 'Paul')
142
- properties << create_pm_kv_info('ccLastName', 'Dupond')
143
- properties << create_pm_kv_info('ccType', 'VISA')
144
- properties << create_pm_kv_info('ccExpirationMonth', '12')
145
- properties << create_pm_kv_info('ccExpirationYear', '17')
146
- payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
147
- payment_method_props.properties = properties
148
- @plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, payment_method_props, true, @properties, @call_context)
149
-
150
- pms = @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
151
- pms.size.should == 1
152
- pm = @plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
153
- @plugin.find_value_from_properties(pm.properties, 'token').should be_nil
154
- @plugin.find_value_from_properties(pm.properties, 'ccFirstName').should == 'Paul'
155
- @plugin.find_value_from_properties(pm.properties, 'ccLastName').should == 'Dupond'
156
- @plugin.find_value_from_properties(pm.properties, 'ccType').should == 'visa'
157
- @plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should == '12'
158
- @plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should == '17'
159
- @plugin.find_value_from_properties(pm.properties, 'ccLast4').should == '1111'
160
- @plugin.find_value_from_properties(pm.properties, 'ccNumber').should == '41111111111111111'
161
-
162
- # Verify we can retrieve the payment source, during the payment call
163
- source = @plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
164
- source.is_a?(::ActiveMerchant::Billing::CreditCard).should be_true
165
- source.first_name.should == 'Paul'
166
- source.last_name.should == 'Dupond'
167
- source.brand.should == 'visa'
168
- source.month.should == 12
169
- source.year.should == 17
170
- source.number.should == '41111111111111111'
171
- end
129
+ capture_id = SecureRandom.uuid
130
+ payment_api.add_payment(@kb_payment_id, capture_id, SecureRandom.uuid, :CAPTURE)
131
+ # We omit the payment_processor_account_id to verify we can retrieve it
132
+ capture = plugin.capture_payment(@kb_account_id, @kb_payment_id, capture_id, @kb_payment_method_id, @amount_in_cents, @currency, @properties, @call_context)
133
+ verify_transaction_info_plugin(capture, capture_id, :CAPTURE, 2, @ppai.value)
134
+ end
172
135
 
173
- it 'should support storing a token' do
174
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
175
-
176
- properties = []
177
- properties << create_pm_kv_info('token', 'ABCDEF')
178
- payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
179
- payment_method_props.properties = properties
180
- @plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, payment_method_props, true, @properties, @call_context)
181
-
182
- pms = @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
183
- pms.size.should == 1
184
- pm = @plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
185
- @plugin.find_value_from_properties(pm.properties, 'token').should == 'ABCDEF'
186
- @plugin.find_value_from_properties(pm.properties, 'ccFirstName').should be_nil
187
- @plugin.find_value_from_properties(pm.properties, 'ccLastName').should be_nil
188
- @plugin.find_value_from_properties(pm.properties, 'ccType').should be_nil
189
- @plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should be_nil
190
- @plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should be_nil
191
- @plugin.find_value_from_properties(pm.properties, 'ccLast4').should be_nil
192
- @plugin.find_value_from_properties(pm.properties, 'ccNumber').should be_nil
193
-
194
- # Verify we can retrieve the payment source, during the payment call
195
- source = @plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
196
- source.should == 'ABCDEF'
136
+ it 'should support storing a credit card' do
137
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
138
+
139
+ properties = []
140
+ properties << build_property('ccNumber', '41111111111111111')
141
+ properties << build_property('ccFirstName', 'Paul')
142
+ properties << build_property('ccLastName', 'Dupond')
143
+ properties << build_property('ccType', 'visa')
144
+ properties << build_property('ccExpirationMonth', '12')
145
+ properties << build_property('ccExpirationYear', '17')
146
+ payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
147
+ payment_method_props.properties = properties
148
+ plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, payment_method_props, true, @properties, @call_context)
149
+
150
+ pms = plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
151
+ pms.size.should == 1
152
+ pm = plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
153
+ plugin.find_value_from_properties(pm.properties, 'token').should be_nil
154
+ plugin.find_value_from_properties(pm.properties, 'ccFirstName').should == 'Paul'
155
+ plugin.find_value_from_properties(pm.properties, 'ccLastName').should == 'Dupond'
156
+ plugin.find_value_from_properties(pm.properties, 'ccType').should == 'visa'
157
+ plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should == '12'
158
+ plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should == '17'
159
+ plugin.find_value_from_properties(pm.properties, 'ccLast4').should == '1111'
160
+ plugin.find_value_from_properties(pm.properties, 'ccNumber').should == '41111111111111111'
161
+
162
+ # Verify we can retrieve the payment source, during the payment call
163
+ source = plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
164
+ source.is_a?(::ActiveMerchant::Billing::CreditCard).should be_true
165
+ source.first_name.should == 'Paul'
166
+ source.last_name.should == 'Dupond'
167
+ source.brand.should == 'visa'
168
+ source.month.should == 12
169
+ source.year.should == 17
170
+ source.number.should == '41111111111111111'
171
+ end
172
+
173
+ it 'should support storing a token' do
174
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
175
+
176
+ properties = []
177
+ properties << build_property('token', 'ABCDEF')
178
+ payment_method_props = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
179
+ payment_method_props.properties = properties
180
+ plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, payment_method_props, true, @properties, @call_context)
181
+
182
+ pms = plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
183
+ pms.size.should == 1
184
+ pm = plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
185
+ plugin.find_value_from_properties(pm.properties, 'token').should == 'ABCDEF'
186
+ plugin.find_value_from_properties(pm.properties, 'ccFirstName').should be_nil
187
+ plugin.find_value_from_properties(pm.properties, 'ccLastName').should be_nil
188
+ plugin.find_value_from_properties(pm.properties, 'ccType').should be_nil
189
+ plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should be_nil
190
+ plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should be_nil
191
+ plugin.find_value_from_properties(pm.properties, 'ccLast4').should be_nil
192
+ plugin.find_value_from_properties(pm.properties, 'ccNumber').should be_nil
193
+
194
+ # Verify we can retrieve the payment source, during the payment call
195
+ source = plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
196
+ source.should == 'ABCDEF'
197
+ end
198
+
199
+ it 'should support storing a placeholder row' do
200
+ plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
201
+
202
+ plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, ::Killbill::Plugin::Model::PaymentMethodPlugin.new, true, @properties, @call_context)
203
+
204
+ pms = plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
205
+ pms.size.should == 1
206
+ pm = plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
207
+ plugin.find_value_from_properties(pm.properties, 'token').should be_nil
208
+ plugin.find_value_from_properties(pm.properties, 'ccFirstName').should be_nil
209
+ plugin.find_value_from_properties(pm.properties, 'ccLastName').should be_nil
210
+ plugin.find_value_from_properties(pm.properties, 'ccType').should be_nil
211
+ plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should be_nil
212
+ plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should be_nil
213
+ plugin.find_value_from_properties(pm.properties, 'ccLast4').should be_nil
214
+ plugin.find_value_from_properties(pm.properties, 'ccNumber').should be_nil
215
+
216
+ # Verify we can retrieve the payment source, during the payment call
217
+ source = plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
218
+ source.is_a?(::ActiveMerchant::Billing::CreditCard).should be_true
219
+ source.first_name.should be_nil
220
+ source.last_name.should be_nil
221
+ source.brand.should be_nil
222
+ source.month.should be_nil
223
+ source.year.should be_nil
224
+ source.number.should be_nil
225
+ end
226
+
227
+ it 'recognizes a tokenized card by the network' do
228
+ options = {
229
+ :cc_number => '4242424242424242',
230
+ :cc_type => 'visa',
231
+ :cc_expiration_month => 12,
232
+ :cc_expiration_year => 2019,
233
+ :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
234
+ :eci => '05'
235
+ }
236
+ source = plugin.get_payment_source(nil, [], options, @call_context)
237
+ source.is_a?(::ActiveMerchant::Billing::NetworkTokenizationCreditCard).should be_true
238
+ source.type.should == 'network_tokenization'
239
+ source.number.should == '4242424242424242'
240
+ source.brand.should == 'visa'
241
+ source.month.should == 12
242
+ source.year.should == 2019
243
+ source.payment_cryptogram.should == 'EHuWW9PiBkWvqE5juRwDzAUFBAk='
244
+ source.eci.should == '05'
245
+ end
246
+
247
+ it 'recognizes an ApplePay token' do
248
+ options = {
249
+ :token => '{"data":"BDPNWStMmGewQUWGg4o7E/j+1cq1T78qyU84b67itjcYI8wPYAOhshjhZPrqdUr4XwPMbj4zcGMdy++1H2VkPOY+BOMF25ub19cX4nCvkXUUOTjDllB1TgSr8JHZxgp9rCgsSUgbBgKf60XKutXf6aj/o8ZIbKnrKQ8Sh0ouLAKloUMn+vPu4+A7WKrqrauz9JvOQp6vhIq+HKjUcUNCITPyFhmOEtq+H+w0vRa1CE6WhFBNnCHqzzWKckB/0nqLZRTYbF0p+vyBiVaWHeghERfHxRtbzpeczRPPuFsfpHVs48oPLC/k/1MNd47kz/pHDcR/Dy6aUM+lNfoily/QJN+tS3m0HfOtISAPqOmXemvr6xJCjCZlCuw0C9mXz/obHpofuIES8r9cqGGsUAPDpw7g642m4PzwKF+HBuYUneWDBNSD2u6jbAG3","version":"EC_v1","header":{"applicationData":"94ee059335e587e501cc4bf90613e0814f00a7b08bc7c648fd865a2af6a22cc2","transactionId":"c1caf5ae72f0039a82bad92b828363734f85bf2f9cadf193d1bad9ddcb60a795","ephemeralPublicKey":"MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABGm+gsl0PZFT/kDdUSkxwyfo8JpwTQQzBm9lJJnmTl4DGUvAD4GseGj/pshBZ0K3TeuqDt/tDLbE+8/m0yCmoxw=","publicKeyHash":"/bb9CNC36uBheHFPbmohB7Oo1OsX2J+kJqv48zOVViQ="},"signature":"MIIDQgYJKoZIhvcNAQcCoIIDMzCCAy8CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCAiswggInMIIBlKADAgECAhBcl+Pf3+U4pk13nVD9nwQQMAkGBSsOAwIdBQAwJzElMCMGA1UEAx4cAGMAaABtAGEAaQBAAHYAaQBzAGEALgBjAG8AbTAeFw0xNDAxMDEwNjAwMDBaFw0yNDAxMDEwNjAwMDBaMCcxJTAjBgNVBAMeHABjAGgAbQBhAGkAQAB2AGkAcwBhAC4AYwBvAG0wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANC8+kgtgmvWF1OzjgDNrjTEBRuo/5MKvlM146pAf7Gx41blE9w4fIXJAD7FfO7QKjIXYNt39rLyy7xDwb/5IkZM60TZ2iI1pj55Uc8fd4fzOpk3ftZaQGXNLYptG1d9V7IS82Oup9MMo1BPVrXTPHNcsM99EPUnPqdbeGc87m0rAgMBAAGjXDBaMFgGA1UdAQRRME+AEHZWPrWtJd7YZ431hCg7YFShKTAnMSUwIwYDVQQDHhwAYwBoAG0AYQBpAEAAdgBpAHMAYQAuAGMAbwBtghBcl+Pf3+U4pk13nVD9nwQQMAkGBSsOAwIdBQADgYEAbUKYCkuIKS9QQ2mFcMYREIm2l+Xg8/JXv+GBVQJkOKoscY4iNDFA/bQlogf9LLU84THwNRnsvV3Prv7RTY81gq0dtC8zYcAaAkCHII3yqMnJ4AOu6EOW9kJk232gSE7WlCtHbfLSKfuSgQX8KXQYuZLk2Rr63N8ApXsXwBL3cJ0xgeAwgd0CAQEwOzAnMSUwIwYDVQQDHhwAYwBoAG0AYQBpAEAAdgBpAHMAYQAuAGMAbwBtAhBcl+Pf3+U4pk13nVD9nwQQMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYBaK3ElOstbH8WooseDABf+Jg/129JcIawm7c6Vxn7ZasNbAq3tAt8Pty+uQCgssXqZkLA7kz2GzMolNtv9wYmu9Ujwar1PHYS+B/oGnoz591wjagXWRz0nMo5y3O1KzX0d8CRHAVa88SrV1a5JIiRev3oStIqwv5xuZldag6Tr8w=="}',
250
+ :payment_instrument_name => 'SomeBank Points Card',
251
+ :payment_network => 'MasterCard',
252
+ :transaction_identifier => 'uniqueidentifier123'
253
+ }
254
+ source = plugin.get_payment_source(nil, [], options, @call_context)
255
+ source.is_a?(::ActiveMerchant::Billing::ApplePayPaymentToken).should be_true
256
+ source.type.should == 'apple_pay'
257
+ source.payment_instrument_name.should == 'SomeBank Points Card'
258
+ source.payment_network.should == 'MasterCard'
259
+ # Not set in ApplePayPaymentToken?
260
+ #source.transaction_identifier.should == 'uniqueidentifier123'
261
+ source.payment_data.should == {
262
+ 'data' => 'BDPNWStMmGewQUWGg4o7E/j+1cq1T78qyU84b67itjcYI8wPYAOhshjhZPrqdUr4XwPMbj4zcGMdy++1H2VkPOY+BOMF25ub19cX4nCvkXUUOTjDllB1TgSr8JHZxgp9rCgsSUgbBgKf60XKutXf6aj/o8ZIbKnrKQ8Sh0ouLAKloUMn+vPu4+A7WKrqrauz9JvOQp6vhIq+HKjUcUNCITPyFhmOEtq+H+w0vRa1CE6WhFBNnCHqzzWKckB/0nqLZRTYbF0p+vyBiVaWHeghERfHxRtbzpeczRPPuFsfpHVs48oPLC/k/1MNd47kz/pHDcR/Dy6aUM+lNfoily/QJN+tS3m0HfOtISAPqOmXemvr6xJCjCZlCuw0C9mXz/obHpofuIES8r9cqGGsUAPDpw7g642m4PzwKF+HBuYUneWDBNSD2u6jbAG3',
263
+ 'version' => 'EC_v1',
264
+ 'header' => {
265
+ 'applicationData' => '94ee059335e587e501cc4bf90613e0814f00a7b08bc7c648fd865a2af6a22cc2',
266
+ 'transactionId' => 'c1caf5ae72f0039a82bad92b828363734f85bf2f9cadf193d1bad9ddcb60a795',
267
+ 'ephemeralPublicKey' => 'MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABGm+gsl0PZFT/kDdUSkxwyfo8JpwTQQzBm9lJJnmTl4DGUvAD4GseGj/pshBZ0K3TeuqDt/tDLbE+8/m0yCmoxw=',
268
+ 'publicKeyHash' => '/bb9CNC36uBheHFPbmohB7Oo1OsX2J+kJqv48zOVViQ='
269
+ },
270
+ 'signature' => 'MIIDQgYJKoZIhvcNAQcCoIIDMzCCAy8CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCAiswggInMIIBlKADAgECAhBcl+Pf3+U4pk13nVD9nwQQMAkGBSsOAwIdBQAwJzElMCMGA1UEAx4cAGMAaABtAGEAaQBAAHYAaQBzAGEALgBjAG8AbTAeFw0xNDAxMDEwNjAwMDBaFw0yNDAxMDEwNjAwMDBaMCcxJTAjBgNVBAMeHABjAGgAbQBhAGkAQAB2AGkAcwBhAC4AYwBvAG0wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANC8+kgtgmvWF1OzjgDNrjTEBRuo/5MKvlM146pAf7Gx41blE9w4fIXJAD7FfO7QKjIXYNt39rLyy7xDwb/5IkZM60TZ2iI1pj55Uc8fd4fzOpk3ftZaQGXNLYptG1d9V7IS82Oup9MMo1BPVrXTPHNcsM99EPUnPqdbeGc87m0rAgMBAAGjXDBaMFgGA1UdAQRRME+AEHZWPrWtJd7YZ431hCg7YFShKTAnMSUwIwYDVQQDHhwAYwBoAG0AYQBpAEAAdgBpAHMAYQAuAGMAbwBtghBcl+Pf3+U4pk13nVD9nwQQMAkGBSsOAwIdBQADgYEAbUKYCkuIKS9QQ2mFcMYREIm2l+Xg8/JXv+GBVQJkOKoscY4iNDFA/bQlogf9LLU84THwNRnsvV3Prv7RTY81gq0dtC8zYcAaAkCHII3yqMnJ4AOu6EOW9kJk232gSE7WlCtHbfLSKfuSgQX8KXQYuZLk2Rr63N8ApXsXwBL3cJ0xgeAwgd0CAQEwOzAnMSUwIwYDVQQDHhwAYwBoAG0AYQBpAEAAdgBpAHMAYQAuAGMAbwBtAhBcl+Pf3+U4pk13nVD9nwQQMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYBaK3ElOstbH8WooseDABf+Jg/129JcIawm7c6Vxn7ZasNbAq3tAt8Pty+uQCgssXqZkLA7kz2GzMolNtv9wYmu9Ujwar1PHYS+B/oGnoz591wjagXWRz0nMo5y3O1KzX0d8CRHAVa88SrV1a5JIiRev3oStIqwv5xuZldag6Tr8w=='
271
+ }
272
+ end
273
+
274
+ # Apple Pay integration with CyberSource for example
275
+ it 'merges tokenized cards with payment method information' do
276
+ # Create a payment method with just a first and last name
277
+ cc_first_name = ::Killbill::Plugin::Model::PluginProperty.new
278
+ cc_first_name.key = 'cc_first_name'
279
+ cc_first_name.value = 'John'
280
+ cc_last_name = ::Killbill::Plugin::Model::PluginProperty.new
281
+ cc_last_name.key = 'cc_last_name'
282
+ cc_last_name.value = 'Doe'
283
+ skip_gw = ::Killbill::Plugin::Model::PluginProperty.new
284
+ skip_gw.key = 'skip_gw'
285
+ skip_gw.value = 'true'
286
+ pm_properties = ::Killbill::Plugin::Model::PaymentMethodPlugin.new
287
+ plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, pm_properties, true, [skip_gw, cc_first_name, cc_last_name], @call_context)
288
+
289
+ # Build the NetworkTokenizationCreditCard
290
+ options = {
291
+ :cc_number => '4242424242424242',
292
+ :cc_type => 'visa',
293
+ :cc_expiration_month => 12,
294
+ :cc_expiration_year => 2019,
295
+ :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
296
+ :eci => '05'
297
+ }
298
+ source = plugin.get_payment_source(@kb_payment_method_id, [], options, @call_context)
299
+ source.is_a?(::ActiveMerchant::Billing::NetworkTokenizationCreditCard).should be_true
300
+ source.type.should == 'network_tokenization'
301
+ source.number.should == '4242424242424242'
302
+ source.brand.should == 'visa'
303
+ source.month.should == 12
304
+ source.year.should == 2019
305
+ source.payment_cryptogram.should == 'EHuWW9PiBkWvqE5juRwDzAUFBAk='
306
+ source.eci.should == '05'
307
+ # The first and last name should have been populated from the payment method
308
+ source.first_name.should == 'John'
309
+ source.last_name.should == 'Doe'
310
+ end
197
311
  end
198
312
 
199
- it 'should support storing a placeholder row' do
200
- @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context).size.should == 0
201
-
202
- @plugin.add_payment_method(@kb_account_id, SecureRandom.uuid, ::Killbill::Plugin::Model::PaymentMethodPlugin.new, true, @properties, @call_context)
203
-
204
- pms = @plugin.get_payment_methods(@kb_account_id, true, @properties, @call_context)
205
- pms.size.should == 1
206
- pm = @plugin.get_payment_method_detail(@kb_account_id, pms[0].payment_method_id, @properties, @call_context)
207
- @plugin.find_value_from_properties(pm.properties, 'token').should be_nil
208
- @plugin.find_value_from_properties(pm.properties, 'ccFirstName').should be_nil
209
- @plugin.find_value_from_properties(pm.properties, 'ccLastName').should be_nil
210
- @plugin.find_value_from_properties(pm.properties, 'ccType').should be_nil
211
- @plugin.find_value_from_properties(pm.properties, 'ccExpirationMonth').should be_nil
212
- @plugin.find_value_from_properties(pm.properties, 'ccExpirationYear').should be_nil
213
- @plugin.find_value_from_properties(pm.properties, 'ccLast4').should be_nil
214
- @plugin.find_value_from_properties(pm.properties, 'ccNumber').should be_nil
215
-
216
- # Verify we can retrieve the payment source, during the payment call
217
- source = @plugin.get_payment_source(pm.kb_payment_method_id, [], {}, @call_context)
218
- source.is_a?(::ActiveMerchant::Billing::CreditCard).should be_true
219
- source.first_name.should be_nil
220
- source.last_name.should be_nil
221
- source.brand.should be_nil
222
- source.month.should be_nil
223
- source.year.should be_nil
224
- source.number.should be_nil
313
+ context 'with a dummy gateway' do
314
+ let(:gateway) { DummyRecordingGateway.new }
315
+
316
+ let(:plugin) do
317
+ plugin = ::Killbill::Plugin::ActiveMerchant::PaymentPlugin.new(Proc.new { |config| gateway },
318
+ :test,
319
+ ::Killbill::Test::TestPaymentMethod,
320
+ ::Killbill::Test::TestTransaction,
321
+ ::Killbill::Test::TestResponse)
322
+ plugin.kb_apis = kb_apis
323
+ plugin.logger = logger
324
+
325
+ plugin_config = {
326
+ :test => [
327
+ {:account_id => 'default', :test => true},
328
+ ]
329
+ }
330
+ with_plugin_yaml_config('test.yml', plugin_config) do |file|
331
+ plugin.conf_dir = File.dirname(file)
332
+ plugin.root = File.dirname(file)
333
+
334
+ # Start the plugin here - since the config file will be deleted
335
+ plugin.start_plugin
336
+ end
337
+
338
+ plugin
339
+ end
340
+
341
+ after(:each) do
342
+ gateway.call_stack.clear
343
+ end
344
+
345
+ after(:all) do
346
+ plugin.stop_plugin
347
+ end
348
+
349
+ it 'sets the kb_payment_transaction_id as order_id by default' do
350
+ plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, [], @call_context)
351
+
352
+ kb_payment_transaction_id = SecureRandom.uuid
353
+ plugin.purchase_payment(@kb_account_id, @kb_payment_id, kb_payment_transaction_id, @kb_payment_method_id, @amount_in_cents, @currency, [], @call_context)
354
+
355
+ sent_options = gateway.call_stack[-1][:options]
356
+ sent_options.size.should == 11
357
+ sent_options[:currency].should == @currency
358
+ sent_options[:description].should == "Kill Bill purchase for #{kb_payment_transaction_id}"
359
+ sent_options[:order_id].should == kb_payment_transaction_id
360
+ end
361
+
362
+ it 'sets the kb_payment_transaction_id as order_id if specified' do
363
+ plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, [], @call_context)
364
+
365
+ property = ::Killbill::Plugin::Model::PluginProperty.new
366
+ property.key = 'external_key_as_order_id'
367
+ property.value = 'false'
368
+
369
+ kb_payment_transaction_id = SecureRandom.uuid
370
+ plugin.purchase_payment(@kb_account_id, @kb_payment_id, kb_payment_transaction_id, @kb_payment_method_id, @amount_in_cents, @currency, [property], @call_context)
371
+
372
+ sent_options = gateway.call_stack[-1][:options]
373
+ sent_options.size.should == 12
374
+ sent_options[:currency].should == @currency
375
+ sent_options[:description].should == "Kill Bill purchase for #{kb_payment_transaction_id}"
376
+ sent_options[:order_id].should == kb_payment_transaction_id
377
+ end
378
+
379
+ it 'sets the payment transaction external key as order_id if specified' do
380
+ plugin.add_payment_method(@kb_account_id, @kb_payment_method_id, @payment_method_props, true, [], @call_context)
381
+
382
+ property = ::Killbill::Plugin::Model::PluginProperty.new
383
+ property.key = 'external_key_as_order_id'
384
+ property.value = 'true'
385
+
386
+ kb_payment_transaction_id = SecureRandom.uuid
387
+ kb_payment_transaction_external_key = SecureRandom.uuid
388
+ payment_api.add_payment(@kb_payment_id, kb_payment_transaction_id, kb_payment_transaction_external_key, :PURCHASE)
389
+ plugin.purchase_payment(@kb_account_id, @kb_payment_id, kb_payment_transaction_id, @kb_payment_method_id, @amount_in_cents, @currency, [property], @call_context)
390
+
391
+ sent_options = gateway.call_stack[-1][:options]
392
+ sent_options.size.should == 12
393
+ sent_options[:currency].should == @currency
394
+ sent_options[:description].should == "Kill Bill purchase for #{kb_payment_transaction_id}"
395
+ sent_options[:order_id].should == kb_payment_transaction_external_key
396
+ end
397
+
398
+ it 'closes the connection after each request' do
399
+ ::ActiveRecord::Base.retrieve_connection
400
+ ::ActiveRecord::Base.connection_pool.active_connection?.should == true
401
+
402
+ plugin.after_request
403
+
404
+ ::ActiveRecord::Base.connection_pool.active_connection?.should == false
405
+ end
225
406
  end
226
407
 
227
408
  private
@@ -242,8 +423,27 @@ describe Killbill::Plugin::ActiveMerchant::PaymentPlugin do
242
423
  # Verify we routed to the right gateway
243
424
  (t_info_plugin.properties.find { |kv| kv.key.to_s == 'payment_processor_account_id' }).value.to_s.should == payment_processor_account_id
244
425
 
245
- transactions = @plugin.get_payment_info(@kb_account_id, @kb_payment_id, [], @call_context)
426
+ transactions = plugin.get_payment_info(@kb_account_id, @kb_payment_id, [], @call_context)
246
427
  transactions.size.should == transaction_nb
247
428
  transactions[transaction_nb - 1].to_json.should == t_info_plugin.to_json
248
429
  end
430
+
431
+ class DummyRecordingGateway < ::ActiveMerchant::Billing::Gateway
432
+
433
+ attr_reader :call_stack
434
+
435
+ def initialize
436
+ @call_stack = []
437
+ end
438
+
439
+ def purchase(money, paysource, options = {})
440
+ @call_stack << {:money => money, :source => paysource, :options => options}
441
+ ::ActiveMerchant::Billing::Response.new(true, 'Success!', {:authorized_amount => money}, :test => true, :authorization => 12345)
442
+ end
443
+
444
+ def store(paysource, options = {})
445
+ @call_stack << {:source => paysource, :options => options}
446
+ ::ActiveMerchant::Billing::Response.new(true, 'Success!', {:billingid => '1'}, :test => true, :authorization => 12345)
447
+ end
448
+ end
249
449
  end