killbill 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/Jarfile +7 -5
  3. data/NEWS +3 -0
  4. data/README.md +41 -17
  5. data/VERSION +1 -1
  6. data/generators/active_merchant/templates/Jarfile.rb +7 -5
  7. data/generators/active_merchant/templates/config.yml.rb +3 -3
  8. data/generators/active_merchant/templates/db/ddl.sql.rb +4 -0
  9. data/generators/active_merchant/templates/db/schema.rb +4 -0
  10. data/generators/active_merchant/templates/lib/api.rb +42 -22
  11. data/generators/active_merchant/templates/lib/models/response.rb +3 -1
  12. data/generators/active_merchant/templates/plugin.gemspec.rb +1 -1
  13. data/lib/killbill.rb +7 -4
  14. data/lib/killbill/gen/api/account.rb +4 -3
  15. data/lib/killbill/gen/api/account_api_exception.rb +4 -3
  16. data/lib/killbill/gen/api/account_audit_logs.rb +12 -68
  17. data/lib/killbill/gen/api/account_audit_logs_for_object_type.rb +4 -3
  18. data/lib/killbill/gen/api/account_data.rb +4 -3
  19. data/lib/killbill/gen/api/account_email.rb +4 -3
  20. data/lib/killbill/gen/api/account_user_api.rb +4 -3
  21. data/lib/killbill/gen/api/audit_log.rb +4 -3
  22. data/lib/killbill/gen/api/audit_user_api.rb +4 -3
  23. data/lib/killbill/gen/api/billing_exception_base.rb +4 -3
  24. data/lib/killbill/gen/api/block.rb +4 -3
  25. data/lib/killbill/gen/api/blockable.rb +4 -3
  26. data/lib/killbill/gen/api/blocking_api_exception.rb +4 -3
  27. data/lib/killbill/gen/api/blocking_state.rb +4 -3
  28. data/lib/killbill/gen/api/call_context.rb +4 -3
  29. data/lib/killbill/gen/api/catalog.rb +4 -3
  30. data/lib/killbill/gen/api/catalog_api_exception.rb +4 -3
  31. data/lib/killbill/gen/api/catalog_user_api.rb +4 -3
  32. data/lib/killbill/gen/api/column_info.rb +4 -3
  33. data/lib/killbill/gen/api/control_tag.rb +4 -3
  34. data/lib/killbill/gen/api/currency_conversion.rb +4 -3
  35. data/lib/killbill/gen/api/currency_conversion_api.rb +4 -3
  36. data/lib/killbill/gen/api/currency_conversion_exception.rb +4 -3
  37. data/lib/killbill/gen/api/currency_value_null.rb +4 -3
  38. data/lib/killbill/gen/api/custom_field.rb +4 -3
  39. data/lib/killbill/gen/api/custom_field_api_exception.rb +4 -3
  40. data/lib/killbill/gen/api/custom_field_user_api.rb +4 -3
  41. data/lib/killbill/gen/api/database_export_output_stream.rb +4 -3
  42. data/lib/killbill/gen/api/direct_payment.rb +39 -11
  43. data/lib/killbill/gen/api/direct_payment_api.rb +643 -31
  44. data/lib/killbill/gen/api/direct_payment_transaction.rb +37 -12
  45. data/lib/killbill/gen/api/duration.rb +4 -3
  46. data/lib/killbill/gen/api/entitlement.rb +4 -3
  47. data/lib/killbill/gen/api/entitlement_ao_status_dry_run.rb +4 -3
  48. data/lib/killbill/gen/api/entitlement_api.rb +4 -3
  49. data/lib/killbill/gen/api/entitlement_api_exception.rb +4 -3
  50. data/lib/killbill/gen/api/entity.rb +4 -3
  51. data/lib/killbill/gen/api/fixed.rb +4 -3
  52. data/lib/killbill/gen/api/illegal_plan_change.rb +4 -3
  53. data/lib/killbill/gen/api/international_price.rb +4 -3
  54. data/lib/killbill/gen/api/invalid_config_exception.rb +4 -3
  55. data/lib/killbill/gen/api/invoice.rb +4 -3
  56. data/lib/killbill/gen/api/invoice_api_exception.rb +4 -3
  57. data/lib/killbill/gen/api/invoice_creation_event.rb +4 -3
  58. data/lib/killbill/gen/api/invoice_formatter.rb +4 -3
  59. data/lib/killbill/gen/api/invoice_item.rb +4 -3
  60. data/lib/killbill/gen/api/invoice_item_formatter.rb +4 -3
  61. data/lib/killbill/gen/api/invoice_payment.rb +7 -7
  62. data/lib/killbill/gen/api/invoice_payment_api.rb +7 -153
  63. data/lib/killbill/gen/api/invoice_user_api.rb +22 -3
  64. data/lib/killbill/gen/api/limit.rb +4 -3
  65. data/lib/killbill/gen/api/listing.rb +4 -3
  66. data/lib/killbill/gen/api/migration_plan.rb +4 -3
  67. data/lib/killbill/gen/api/mutable_account_data.rb +4 -3
  68. data/lib/killbill/gen/api/osgi_killbill.rb +15 -7
  69. data/lib/killbill/gen/api/osgi_plugin_properties.rb +4 -3
  70. data/lib/killbill/gen/api/pagination.rb +4 -3
  71. data/lib/killbill/gen/api/payment_api_exception.rb +4 -3
  72. data/lib/killbill/gen/api/payment_gateway_api.rb +4 -3
  73. data/lib/killbill/gen/api/payment_method.rb +11 -4
  74. data/lib/killbill/gen/api/payment_method_plugin.rb +5 -76
  75. data/lib/killbill/gen/api/payment_options.rb +68 -0
  76. data/lib/killbill/gen/api/plan.rb +4 -3
  77. data/lib/killbill/gen/api/plan_change_result.rb +4 -3
  78. data/lib/killbill/gen/api/plan_phase.rb +4 -3
  79. data/lib/killbill/gen/api/plan_phase_specifier.rb +4 -3
  80. data/lib/killbill/gen/api/plan_specifier.rb +4 -3
  81. data/lib/killbill/gen/api/plugin_config_service_api.rb +4 -3
  82. data/lib/killbill/gen/api/plugin_property.rb +4 -3
  83. data/lib/killbill/gen/api/price.rb +4 -3
  84. data/lib/killbill/gen/api/price_list.rb +4 -3
  85. data/lib/killbill/gen/api/price_list_set.rb +4 -3
  86. data/lib/killbill/gen/api/product.rb +4 -3
  87. data/lib/killbill/gen/api/rate.rb +4 -3
  88. data/lib/killbill/gen/api/record_id_api.rb +4 -3
  89. data/lib/killbill/gen/api/recurring.rb +4 -3
  90. data/lib/killbill/gen/api/refund.rb +7 -6
  91. data/lib/killbill/gen/api/require_gen.rb +5 -6
  92. data/lib/killbill/gen/api/rolled_up_usage.rb +4 -3
  93. data/lib/killbill/gen/api/security_api_exception.rb +4 -3
  94. data/lib/killbill/gen/api/static_catalog.rb +4 -3
  95. data/lib/killbill/gen/api/subscription.rb +4 -3
  96. data/lib/killbill/gen/api/subscription_api.rb +4 -3
  97. data/lib/killbill/gen/api/subscription_api_exception.rb +4 -3
  98. data/lib/killbill/gen/api/subscription_bundle.rb +4 -3
  99. data/lib/killbill/gen/api/subscription_bundle_timeline.rb +4 -3
  100. data/lib/killbill/gen/api/subscription_event.rb +4 -3
  101. data/lib/killbill/gen/api/tag.rb +4 -3
  102. data/lib/killbill/gen/api/tag_api_exception.rb +4 -3
  103. data/lib/killbill/gen/api/tag_definition.rb +4 -3
  104. data/lib/killbill/gen/api/tag_definition_api_exception.rb +4 -3
  105. data/lib/killbill/gen/api/tag_user_api.rb +4 -3
  106. data/lib/killbill/gen/api/tenant.rb +4 -3
  107. data/lib/killbill/gen/api/tenant_api_exception.rb +4 -3
  108. data/lib/killbill/gen/api/tenant_context.rb +4 -3
  109. data/lib/killbill/gen/api/tenant_data.rb +4 -3
  110. data/lib/killbill/gen/api/tenant_kv.rb +4 -3
  111. data/lib/killbill/gen/api/tenant_user_api.rb +4 -3
  112. data/lib/killbill/gen/api/tier.rb +4 -3
  113. data/lib/killbill/gen/api/tiered_block.rb +4 -3
  114. data/lib/killbill/gen/api/unit.rb +4 -3
  115. data/lib/killbill/gen/api/usage.rb +4 -3
  116. data/lib/killbill/gen/api/usage_user_api.rb +4 -3
  117. data/lib/killbill/gen/plugin-api/currency_plugin_api.rb +4 -3
  118. data/lib/killbill/gen/plugin-api/ext_bus_event.rb +4 -3
  119. data/lib/killbill/gen/plugin-api/gateway_notification.rb +4 -3
  120. data/lib/killbill/gen/plugin-api/hosted_payment_page_form_descriptor.rb +4 -3
  121. data/lib/killbill/gen/plugin-api/notification_plugin_api.rb +4 -3
  122. data/lib/killbill/gen/plugin-api/payment_method_info_plugin.rb +4 -3
  123. data/lib/killbill/gen/plugin-api/payment_plugin_api.rb +75 -81
  124. data/lib/killbill/gen/plugin-api/payment_plugin_api_exception.rb +4 -3
  125. data/lib/killbill/gen/plugin-api/{payment_info_plugin.rb → payment_transaction_info_plugin.rb} +21 -6
  126. data/lib/killbill/gen/plugin-api/require_gen.rb +5 -5
  127. data/lib/killbill/helpers/active_merchant/active_record/models/payment_method.rb +20 -36
  128. data/lib/killbill/helpers/active_merchant/active_record/models/response.rb +72 -81
  129. data/lib/killbill/helpers/active_merchant/active_record/models/transaction.rb +62 -43
  130. data/lib/killbill/helpers/active_merchant/killbill_spec_helper.rb +0 -13
  131. data/lib/killbill/helpers/active_merchant/payment_plugin.rb +127 -125
  132. data/lib/killbill/http_servlet.rb +16 -1
  133. data/lib/killbill/killbill_api.rb +0 -3
  134. data/lib/killbill/payment.rb +22 -6
  135. data/lib/killbill/rake_task.rb +93 -31
  136. data/spec/killbill/helpers/payment_method_spec.rb +153 -0
  137. data/spec/killbill/helpers/response_spec.rb +58 -15
  138. data/spec/killbill/helpers/test_schema.rb +12 -8
  139. data/spec/killbill/helpers/transaction_spec.rb +134 -0
  140. data/spec/killbill/payment_plugin_api_spec.rb +18 -18
  141. data/spec/killbill/payment_plugin_spec.rb +26 -15
  142. data/spec/killbill/payment_test.rb +6 -7
  143. data/spec/spec_helper.rb +3 -0
  144. metadata +6 -5
  145. data/lib/killbill/gen/api/payment.rb +0 -187
  146. data/lib/killbill/gen/plugin-api/refund_info_plugin.rb +0 -152
@@ -7,27 +7,35 @@ module Killbill
7
7
  class OperationUnsupportedByGatewayError < NotImplementedError
8
8
  end
9
9
 
10
- def process_payment(kb_account_id, kb_payment_id, kb_payment_method_id, amount, currency, properties, context)
10
+ def authorize_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
11
11
  raise OperationUnsupportedByGatewayError
12
12
  end
13
13
 
14
- def get_payment_info(kb_account_id, kb_payment_id, properties, context)
14
+ def capture_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
15
15
  raise OperationUnsupportedByGatewayError
16
16
  end
17
17
 
18
- def search_payments(search_key, offset, limit, properties, context)
18
+ def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
19
+ raise OperationUnsupportedByGatewayError
20
+ end
21
+
22
+ def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
23
+ raise OperationUnsupportedByGatewayError
24
+ end
25
+
26
+ def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
19
27
  raise OperationUnsupportedByGatewayError
20
28
  end
21
29
 
22
- def process_refund(kb_account_id, kb_payment_id, refund_amount, currency, properties, context)
30
+ def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
23
31
  raise OperationUnsupportedByGatewayError
24
32
  end
25
33
 
26
- def get_refund_info(kb_account_id, kb_payment_id, properties, context)
34
+ def get_payment_info(kb_account_id, kb_payment_id, properties, context)
27
35
  raise OperationUnsupportedByGatewayError
28
36
  end
29
37
 
30
- def search_refunds(search_key, offset, limit, properties, context)
38
+ def search_payments(search_key, offset, limit, properties, context)
31
39
  raise OperationUnsupportedByGatewayError
32
40
  end
33
41
 
@@ -58,6 +66,14 @@ module Killbill
58
66
  def reset_payment_methods(kb_account_id, payment_methods, properties, context)
59
67
  raise OperationUnsupportedByGatewayError
60
68
  end
69
+
70
+ def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
71
+ raise OperationUnsupportedByGatewayError
72
+ end
73
+
74
+ def process_notification(notification, properties, context)
75
+ raise OperationUnsupportedByGatewayError
76
+ end
61
77
  end
62
78
  end
63
79
  end
@@ -15,14 +15,17 @@ module Killbill
15
15
  opts[:plugin_name], # Plugin name, e.g. 'klogger'
16
16
  opts[:gem_name], # Gem file name, e.g. 'klogger-1.0.0.gem'
17
17
  opts[:gemfile_name] || "Gemfile", # Gemfile name
18
- opts[:gemfile_lock_name] || "Gemfile.lock") # Gemfile.lock name
18
+ opts[:gemfile_lock_name] || "Gemfile.lock", # Gemfile.lock name
19
+ opts[:verbose] || false)
19
20
  .install
20
21
  end
21
22
  end
22
23
 
23
- def initialize(base_name, plugin_name, gem_name, gemfile_name, gemfile_lock_name)
24
+ def initialize(base_name, plugin_name, gem_name, gemfile_name, gemfile_lock_name, verbose)
25
+ @verbose = verbose
26
+
24
27
  @logger = Logger.new(STDOUT)
25
- @logger.level = Logger::INFO
28
+ @logger.level = @verbose ? Logger::DEBUG : Logger::INFO
26
29
 
27
30
  @base_name = base_name
28
31
  @plugin_name = plugin_name
@@ -53,26 +56,30 @@ module Killbill
53
56
  # Rely on the Gemfile definition, if it exists, to get all dependencies
54
57
  # (we assume the Gemfile includes the plugin gemspec, as it should).
55
58
  # Otherwise, use only the plugin gemspec.
56
- @specs ||= @gemfile_definition ? @gemfile_definition.specs : [@plugin_gemspec]
59
+ # When using the Gemfile definition, don't include the :development group -- should this be configurable?
60
+ @specs ||= @gemfile_definition ? @gemfile_definition.specs_for([:default]) : [@plugin_gemspec]
57
61
  end
58
62
 
59
63
  def install
60
64
  namespace :killbill do
61
65
  desc "Validate plugin tree"
62
66
  # The killbill.properties file is required, but not the config.ru one
63
- task :validate => killbill_properties_file do
67
+ task :validate, [:verbose] => killbill_properties_file do |t, args|
68
+ set_verbosity(args)
64
69
  validate
65
70
  end
66
71
 
67
72
  # Build the .tar.gz and .zip packages
68
- task :package => :stage
73
+ task :package, [:verbose] => :stage
69
74
  package_task = Rake::PackageTask.new(name, version) do |p|
70
75
  p.need_tar_gz = true
71
76
  p.need_zip = true
72
77
  end
73
78
 
74
79
  desc "Stage all dependencies"
75
- task :stage => :validate do
80
+ task :stage, [:verbose] => :validate do |t, args|
81
+ set_verbosity(args)
82
+
76
83
  stage_dependencies
77
84
  stage_extra_files
78
85
 
@@ -80,6 +87,32 @@ module Killbill
80
87
  package_task.package_files = Rake::FileList.new("#{@package_dir.basename}/**/*")
81
88
  end
82
89
 
90
+ desc "Deploy the plugin to Kill Bill"
91
+ task :deploy, [:force, :plugin_dir, :verbose] => :stage do |t, args|
92
+ set_verbosity(args)
93
+
94
+ plugins_dir = Pathname.new("#{args.plugin_dir || '/var/tmp/bundles/plugins/ruby'}").expand_path
95
+ mkdir_p plugins_dir, :verbose => @verbose
96
+
97
+ plugin_path = Pathname.new("#{plugins_dir}/#{name}")
98
+ if plugin_path.exist?
99
+ if args.force == "true"
100
+ @logger.info "Deleting previous plugin deployment #{plugin_path}"
101
+ rm_rf plugin_path, :verbose => @verbose
102
+ else
103
+ raise "Cowardly not deleting previous plugin deployment #{plugin_path} - override with rake killbill:deploy[true]"
104
+ end
105
+ end
106
+
107
+ cp_r @package_dir, plugins_dir, :verbose => @verbose
108
+
109
+ Rake::FileList.new("#{@base}/*.yml").each do |config_file|
110
+ config_file_path = Pathname.new("#{plugin_path}/#{version}/#{File.basename(config_file)}").expand_path
111
+ @logger.info "Deploying #{config_file} to #{config_file_path}"
112
+ cp config_file, config_file_path, :verbose => @verbose
113
+ end
114
+ end
115
+
83
116
  desc "List all dependencies"
84
117
  task :dependency => :validate do
85
118
  print_dependencies
@@ -94,8 +127,13 @@ module Killbill
94
127
 
95
128
  private
96
129
 
130
+ def set_verbosity(args)
131
+ return unless args.verbose == 'true'
132
+ @verbose = true
133
+ @logger.level = Logger::DEBUG
134
+ end
135
+
97
136
  def validate
98
- @plugin_gem_file = find_plugin_gem
99
137
  @gemfile_definition = find_gemfile
100
138
  end
101
139
 
@@ -121,21 +159,25 @@ module Killbill
121
159
  Bundler.load_gemspec(spec_path)
122
160
  end
123
161
 
124
- def find_plugin_gem
125
- if @gem_name
126
- # Absolute path?
127
- plugin_gem_file = Pathname.new(@gem_name).expand_path
128
- # Relative path to the base?
129
- plugin_gem_file = @base.join(@gem_name).expand_path unless plugin_gem_file.file?
130
- raise "Unable to find your plugin gem in #{@base}. Did you build it (`rake build')?" unless plugin_gem_file.file?
131
- else
132
- plugin_gem_files = Dir[File.join(@base, "**/#{name}-#{version}.gem")]
162
+ def find_plugin_gem(spec)
163
+ gem_name = spec.file_name
164
+ # spec.loaded_from is the path to the gemspec file
165
+ base = Pathname.new(File.dirname(spec.loaded_from)).expand_path
166
+
167
+ # Try in the base directory first
168
+ plugin_gem_file = Pathname.new(gem_name).expand_path
169
+ plugin_gem_file = base.join(gem_name).expand_path unless plugin_gem_file.file?
170
+
171
+ # Try in subdirectories next
172
+ unless plugin_gem_file.file?
173
+ plugin_gem_files = Dir[File.join(base, "**/#{spec.file_name}")]
133
174
  @logger.debug "Gem candidates found: #{plugin_gem_files}"
134
- raise "Unable to find your plugin gem in #{@base}. Did you build it? (`rake build')" unless plugin_gem_files.size >= 1
135
175
  # Take the first one, assume the other ones are from build directories (e.g. pkg)
136
- plugin_gem_file = plugin_gem_files.first
176
+ plugin_gem_file = Pathname.new(plugin_gem_files.first).expand_path unless plugin_gem_files.empty?
137
177
  end
138
178
 
179
+ raise "Unable to find #{gem_name} in #{base}. Did you build it? (`rake build')" unless plugin_gem_file.file?
180
+
139
181
  @logger.debug "Found #{plugin_gem_file}"
140
182
  Pathname.new(plugin_gem_file).expand_path
141
183
  end
@@ -159,34 +201,54 @@ module Killbill
159
201
 
160
202
  def stage_dependencies
161
203
  # Create the target directory
162
- mkdir_p @target_dir.to_s
204
+ mkdir_p @target_dir.to_s, :verbose => @verbose
163
205
 
164
206
  @logger.debug "Installing all gem dependencies to #{@target_dir}"
165
207
  # We can't simply use Bundler::Installer unfortunately, because we can't tell it to copy the gems for cached ones
166
208
  # (it will default to using Bundler::Source::Path references to the gemspecs on "install").
167
209
  specs.each do |spec|
168
- # For the plugin itself, install it manually (the cache path is likely to be wrong)
169
- next if spec.name == name and spec.version == version
170
- @logger.debug "Staging #{spec.name} (#{spec.version}) from #{spec.cache_file}"
171
- begin
172
- Gem::Installer.new(spec.cache_file, {:force => true, :install_dir => @target_dir}).install
173
- rescue => e
174
- @logger.warn "Unable to stage #{spec.name} (#{spec.version}) from #{spec.cache_file}: #{e}"
210
+ plugin_gem_file = Pathname.new(spec.cache_file).expand_path
211
+ if plugin_gem_file.file?
212
+ @logger.debug "Staging #{spec.name} (#{spec.version}) from #{plugin_gem_file}"
213
+ else
214
+ plugin_gem_file = find_plugin_gem(spec)
215
+ @logger.info "Staging custom gem #{spec.full_name} from #{plugin_gem_file}"
175
216
  end
217
+
218
+ do_install_gem(plugin_gem_file, spec.name, spec.version)
176
219
  end
220
+ end
177
221
 
178
- @logger.debug "Staging #{name} (#{version}) from #{@plugin_gem_file}"
179
- Gem::Installer.new(@plugin_gem_file, {:force => true, :install_dir => @target_dir}).install
222
+ def do_install_gem(path, name, version)
223
+ gem_installer = Gem::Installer.new(path,
224
+ {
225
+ :force => true,
226
+ :install_dir => @target_dir,
227
+ # Should be redundant with the tweaks below
228
+ :development => false,
229
+ :wrappers => true
230
+ })
231
+
232
+ # Tweak the spec file as there are a lot of things we don't care about
233
+ gem_installer.spec.executables = nil
234
+ gem_installer.spec.extensions = nil
235
+ gem_installer.spec.extra_rdoc_files = nil
236
+ gem_installer.spec.test_files = nil
237
+
238
+ gem_installer.install
239
+ rescue => e
240
+ @logger.warn "Unable to stage #{name} (#{version}) from #{path}: #{e}"
241
+ raise e
180
242
  end
181
243
 
182
244
  def stage_extra_files
183
245
  unless killbill_properties_file.nil?
184
246
  @logger.debug "Staging #{killbill_properties_file} to #{@plugin_root_target_dir}"
185
- cp killbill_properties_file, @plugin_root_target_dir
247
+ cp killbill_properties_file, @plugin_root_target_dir, :verbose => @verbose
186
248
  end
187
249
  unless config_ru_file.nil?
188
250
  @logger.debug "Staging #{config_ru_file} to #{@plugin_root_target_dir}"
189
- cp config_ru_file, @plugin_root_target_dir
251
+ cp config_ru_file, @plugin_root_target_dir, :verbose => @verbose
190
252
  end
191
253
  end
192
254
 
@@ -16,6 +16,145 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
16
16
  ::Killbill::Test::TestPaymentMethod.delete_all
17
17
  end
18
18
 
19
+ it 'should construct payment methods correctly' do
20
+ kb_account_id = SecureRandom.uuid
21
+ kb_payment_method_id = SecureRandom.uuid
22
+ kb_tenant_id = SecureRandom.uuid
23
+ response = ::ActiveMerchant::Billing::Response.new(true, nil, {}, {:authorization => SecureRandom.uuid})
24
+ options = {
25
+ :billing_address => {
26
+ :address1 => SecureRandom.uuid,
27
+ :address2 => SecureRandom.uuid,
28
+ :city => SecureRandom.uuid,
29
+ :state => SecureRandom.uuid,
30
+ :zip => SecureRandom.uuid,
31
+ :country => SecureRandom.uuid
32
+ }
33
+ }
34
+ cc = ::ActiveMerchant::Billing::CreditCard.new(
35
+ :first_name => 'Steve',
36
+ :last_name => 'Smith',
37
+ :month => '9',
38
+ :year => '2010',
39
+ :brand => 'visa',
40
+ :number => '4242424242424242'
41
+ )
42
+ token = SecureRandom.uuid
43
+
44
+ # Test storage of CC details
45
+ pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc, response, options, {}, ::Killbill::Test::TestPaymentMethod)
46
+ pm.kb_account_id.should == kb_account_id
47
+ pm.kb_payment_method_id.should == kb_payment_method_id
48
+ pm.kb_tenant_id.should == kb_tenant_id
49
+ pm.token.should == response.authorization
50
+ pm.cc_first_name.should == cc.first_name
51
+ pm.cc_last_name.should == cc.last_name
52
+ pm.cc_type.should == cc.brand
53
+ pm.cc_exp_month.should == cc.month.to_i
54
+ pm.cc_exp_year.should == cc.year.to_i
55
+ pm.cc_last_4.should == cc.last_digits.to_i
56
+ pm.address1.should == options[:billing_address][:address1]
57
+ pm.address2.should == options[:billing_address][:address2]
58
+ pm.city.should == options[:billing_address][:city]
59
+ pm.state.should == options[:billing_address][:state]
60
+ pm.zip.should == options[:billing_address][:zip]
61
+ pm.country.should == options[:billing_address][:country]
62
+ # Verify conversions
63
+ verify_conversion_to_kb_objects(pm, kb_account_id, kb_payment_method_id, response.authorization)
64
+
65
+ # Test storage of CC details with no billing address
66
+ pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, cc, response, {}, {}, ::Killbill::Test::TestPaymentMethod)
67
+ pm.kb_account_id.should == kb_account_id
68
+ pm.kb_payment_method_id.should == kb_payment_method_id
69
+ pm.kb_tenant_id.should == kb_tenant_id
70
+ pm.token.should == response.authorization
71
+ pm.cc_first_name.should == cc.first_name
72
+ pm.cc_last_name.should == cc.last_name
73
+ pm.cc_type.should == cc.brand
74
+ pm.cc_exp_month.should == cc.month.to_i
75
+ pm.cc_exp_year.should == cc.year.to_i
76
+ pm.cc_last_4.should == cc.last_digits.to_i
77
+ pm.address1.should be_nil
78
+ pm.address2.should be_nil
79
+ pm.city.should be_nil
80
+ pm.state.should be_nil
81
+ pm.zip.should be_nil
82
+ pm.country.should be_nil
83
+ # Verify conversions
84
+ verify_conversion_to_kb_objects(pm, kb_account_id, kb_payment_method_id, response.authorization)
85
+
86
+ # Test storage of token
87
+ pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, token, response, options, {}, ::Killbill::Test::TestPaymentMethod)
88
+ pm.kb_account_id.should == kb_account_id
89
+ pm.kb_payment_method_id.should == kb_payment_method_id
90
+ pm.kb_tenant_id.should == kb_tenant_id
91
+ pm.token.should == token
92
+ pm.cc_first_name.should be_nil
93
+ pm.cc_last_name.should be_nil
94
+ pm.cc_type.should be_nil
95
+ pm.cc_exp_month.should be_nil
96
+ pm.cc_exp_year.should be_nil
97
+ pm.cc_last_4.should be_nil
98
+ pm.address1.should == options[:billing_address][:address1]
99
+ pm.address2.should == options[:billing_address][:address2]
100
+ pm.city.should == options[:billing_address][:city]
101
+ pm.state.should == options[:billing_address][:state]
102
+ pm.zip.should == options[:billing_address][:zip]
103
+ pm.country.should == options[:billing_address][:country]
104
+ # Verify conversions
105
+ verify_conversion_to_kb_objects(pm, kb_account_id, kb_payment_method_id, token)
106
+
107
+ # Test storage of token with no billing address
108
+ pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, token, response, {}, {}, ::Killbill::Test::TestPaymentMethod)
109
+ pm.kb_account_id.should == kb_account_id
110
+ pm.kb_payment_method_id.should == kb_payment_method_id
111
+ pm.kb_tenant_id.should == kb_tenant_id
112
+ pm.token.should == token
113
+ pm.cc_first_name.should be_nil
114
+ pm.cc_last_name.should be_nil
115
+ pm.cc_type.should be_nil
116
+ pm.cc_exp_month.should be_nil
117
+ pm.cc_exp_year.should be_nil
118
+ pm.cc_last_4.should be_nil
119
+ pm.address1.should be_nil
120
+ pm.address2.should be_nil
121
+ pm.city.should be_nil
122
+ pm.state.should be_nil
123
+ pm.zip.should be_nil
124
+ pm.country.should be_nil
125
+ # Verify conversions
126
+ verify_conversion_to_kb_objects(pm, kb_account_id, kb_payment_method_id, token)
127
+ end
128
+
129
+ it 'should store and retrieve payment methods correctly' do
130
+ kb_account_id = SecureRandom.uuid
131
+ kb_payment_method_id = SecureRandom.uuid
132
+ kb_tenant_id = SecureRandom.uuid
133
+ response = ::ActiveMerchant::Billing::Response.new(true, nil, {}, {:authorization => SecureRandom.uuid})
134
+ token = SecureRandom.uuid
135
+ pm = ::Killbill::Test::TestPaymentMethod.from_response(kb_account_id, kb_payment_method_id, kb_tenant_id, token, response, {}, {}, ::Killbill::Test::TestPaymentMethod)
136
+ pm.save!
137
+
138
+ # Retrieve by account id
139
+ ::Killbill::Test::TestPaymentMethod.from_kb_account_id(kb_account_id, nil).size.should == 0
140
+ ::Killbill::Test::TestPaymentMethod.from_kb_account_id(kb_account_id, SecureRandom.uuid).size.should == 0
141
+ ::Killbill::Test::TestPaymentMethod.from_kb_account_id(SecureRandom.uuid, kb_tenant_id).size.should == 0
142
+ pms = ::Killbill::Test::TestPaymentMethod.from_kb_account_id(kb_account_id, kb_tenant_id)
143
+ pms.size.should == 1
144
+ pms[0].kb_payment_method_id.should == kb_payment_method_id
145
+
146
+ # Retrieve by payment method id
147
+ expect { ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(kb_payment_method_id, nil) }.to raise_error
148
+ expect { ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(kb_payment_method_id, SecureRandom.uuid) }.to raise_error
149
+ expect { ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(SecureRandom.uuid, kb_tenant_id) }.to raise_error
150
+ ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(kb_payment_method_id, kb_tenant_id).kb_payment_method_id.should == kb_payment_method_id
151
+
152
+ # Delete the payment method and verify we cannot find it anymore
153
+ ::Killbill::Test::TestPaymentMethod.mark_as_deleted!(kb_payment_method_id, kb_tenant_id)
154
+ ::Killbill::Test::TestPaymentMethod.from_kb_account_id(kb_account_id, kb_tenant_id).size.should == 0
155
+ expect { ::Killbill::Test::TestPaymentMethod.from_kb_payment_method_id(kb_payment_method_id, kb_tenant_id) }.to raise_error
156
+ end
157
+
19
158
  it 'should generate the right SQL query' do
20
159
  # Check count query (search query numeric)
21
160
  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\""
@@ -100,4 +239,18 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod do
100
239
  pagination.total_nb_records.should == results.size
101
240
  results
102
241
  end
242
+
243
+ def verify_conversion_to_kb_objects(pm, kb_account_id, kb_payment_method_id, external_payment_method_id)
244
+ # Verify conversion to PaymentMethodPlugin
245
+ pmp = pm.to_payment_method_plugin
246
+ pmp.kb_payment_method_id.should == kb_payment_method_id
247
+ pmp.external_payment_method_id.should == external_payment_method_id
248
+ pmp.properties.size.should == 12
249
+
250
+ # Verify conversion to PaymentMethodInfoPlugin
251
+ pmip = pm.to_payment_method_info_plugin
252
+ pmip.account_id.should == kb_account_id
253
+ pmip.payment_method_id.should == kb_payment_method_id
254
+ pmip.external_payment_method_id.should == external_payment_method_id
255
+ end
103
256
  end
@@ -16,24 +16,74 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
16
16
  ::Killbill::Test::TestResponse.delete_all
17
17
  end
18
18
 
19
+ it 'should construct responses correctly' do
20
+ api_call = 'for debugging only'
21
+ kb_account_id = SecureRandom.uuid
22
+ kb_payment_id = SecureRandom.uuid
23
+ kb_payment_transaction_id = SecureRandom.uuid
24
+ transaction_type = :PURCHASE
25
+ kb_tenant_id = SecureRandom.uuid
26
+ response = ::ActiveMerchant::Billing::Response.new(true, 'Message', {}, {
27
+ :authorization => SecureRandom.uuid,
28
+ :avs_result => ::ActiveMerchant::Billing::AVSResult.new(:code => 'P')
29
+ })
30
+
31
+ r = ::Killbill::Test::TestResponse.from_response(api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, kb_tenant_id, response, {}, ::Killbill::Test::TestResponse)
32
+ r.api_call.should == api_call
33
+ r.kb_account_id.should ==kb_account_id
34
+ r.kb_payment_id.should ==kb_payment_id
35
+ r.kb_payment_transaction_id.should ==kb_payment_transaction_id
36
+ r.transaction_type.should ==transaction_type
37
+ r.kb_tenant_id.should ==kb_tenant_id
38
+ r.message.should == response.message
39
+ r.authorization.should == response.authorization
40
+ r.fraud_review.should == response.fraud_review?
41
+ r.test.should == response.test
42
+ r.avs_result_code.should == 'P'
43
+ r.avs_result_message.should == 'Postal code matches, but street address not verified.'
44
+ r.avs_result_street_match.should be_nil
45
+ r.avs_result_postal_match.should == 'Y'
46
+ r.cvv_result_code.should be_nil
47
+ r.cvv_result_message.should be_nil
48
+ r.success.should == response.success?
49
+
50
+ # Verify conversion to PaymentTransactionInfoPlugin
51
+ ptip = r.to_transaction_info_plugin
52
+ ptip.kb_payment_id.should == kb_payment_id
53
+ ptip.kb_transaction_payment_id.should == kb_payment_transaction_id
54
+ ptip.transaction_type.should == transaction_type
55
+ # No associated transaction
56
+ ptip.amount.should be_nil
57
+ ptip.currency.should be_nil
58
+ # Row not created
59
+ ptip.created_date.should be_nil
60
+ ptip.effective_date.should be_nil
61
+ ptip.status.should == :PROCESSED
62
+ ptip.gateway_error.should == 'Message'
63
+ ptip.gateway_error_code.should be_nil
64
+ ptip.first_payment_reference_id.should be_nil
65
+ ptip.second_payment_reference_id.should be_nil
66
+ ptip.properties.size.should == 11
67
+ end
68
+
19
69
  it 'should generate the right SQL query' do
20
70
  # Check count query (search query numeric)
21
- expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\""
71
+ expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE ((((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"kb_payment_transaction_id\" = '1234') OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\""
22
72
  # Note that Kill Bill will pass a String, even for numeric types
23
- ::Killbill::Test::TestResponse.search_query('charge', '1234', '11-22-33').to_sql.should == expected_query
73
+ ::Killbill::Test::TestResponse.search_query('1234', '11-22-33').to_sql.should == expected_query
24
74
 
25
75
  # Check query with results (search query numeric)
26
- expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
76
+ expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE ((((\"test_responses\".\"kb_payment_id\" = '1234' OR \"test_responses\".\"kb_payment_transaction_id\" = '1234') OR \"test_responses\".\"message\" = '1234') OR \"test_responses\".\"authorization\" = '1234') OR \"test_responses\".\"fraud_review\" = '1234') AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
27
77
  # Note that Kill Bill will pass a String, even for numeric types
28
- ::Killbill::Test::TestResponse.search_query('charge', '1234', '11-22-33', 0, 10).to_sql.should == expected_query
78
+ ::Killbill::Test::TestResponse.search_query('1234', '11-22-33', 0, 10).to_sql.should == expected_query
29
79
 
30
80
  # Check count query (search query string)
31
- expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\""
32
- ::Killbill::Test::TestResponse.search_query('charge', 'XXX', '11-22-33').to_sql.should == expected_query
81
+ expected_query = "SELECT COUNT(DISTINCT \"test_responses\".\"id\") FROM \"test_responses\" WHERE ((((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"kb_payment_transaction_id\" = 'XXX') OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\""
82
+ ::Killbill::Test::TestResponse.search_query('XXX', '11-22-33').to_sql.should == expected_query
33
83
 
34
84
  # Check query with results (search query string)
35
- expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE (((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"api_call\" = 'charge' AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
36
- ::Killbill::Test::TestResponse.search_query('charge', 'XXX', '11-22-33', 0, 10).to_sql.should == expected_query
85
+ expected_query = "SELECT DISTINCT \"test_responses\".* FROM \"test_responses\" WHERE ((((\"test_responses\".\"kb_payment_id\" = 'XXX' OR \"test_responses\".\"kb_payment_transaction_id\" = 'XXX') OR \"test_responses\".\"message\" = 'XXX') OR \"test_responses\".\"authorization\" = 'XXX') OR \"test_responses\".\"fraud_review\" = 'XXX') AND \"test_responses\".\"success\" = 't' AND \"test_responses\".\"kb_tenant_id\" = '11-22-33' ORDER BY \"test_responses\".\"id\" LIMIT 10 OFFSET 0"
86
+ ::Killbill::Test::TestResponse.search_query('XXX', '11-22-33', 0, 10).to_sql.should == expected_query
37
87
  end
38
88
 
39
89
  it 'should search all fields' do
@@ -45,13 +95,6 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
45
95
  :kb_tenant_id => '11-22-33',
46
96
  :success => true
47
97
 
48
- # Wrong api_call
49
- ignored1 = ::Killbill::Test::TestResponse.create :api_call => 'add_payment_method',
50
- :kb_account_id => '55-66-77-88',
51
- :kb_payment_id => pm.kb_payment_id,
52
- :kb_tenant_id => '11-22-33',
53
- :success => true
54
-
55
98
  # Not successful
56
99
  ignored2 = ::Killbill::Test::TestResponse.create :api_call => 'charge',
57
100
  :kb_account_id => '55-66-77-88',