killbill 3.2.4 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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