killbill 3.2.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.travis.yml +26 -5
  4. data/Gemfile +1 -1
  5. data/Gemfile.head +5 -0
  6. data/Gemfile.lock +125 -0
  7. data/Jarfile +9 -9
  8. data/Jarfile.lock +54 -0
  9. data/NEWS +3 -0
  10. data/README.md +13 -0
  11. data/VERSION +1 -1
  12. data/generators/active_merchant/templates/.gitignore.rb +2 -3
  13. data/generators/active_merchant/templates/.travis.yml.rb +22 -3
  14. data/generators/active_merchant/templates/Gemfile.head.rb +5 -0
  15. data/generators/active_merchant/templates/Gemfile.rb +1 -1
  16. data/generators/active_merchant/templates/Jarfile.rb +9 -8
  17. data/generators/active_merchant/templates/LICENSE.rb +2 -2
  18. data/generators/active_merchant/templates/config.yml.rb +16 -6
  19. data/generators/active_merchant/templates/lib/plugin.rb +0 -1
  20. data/generators/active_merchant/templates/plugin.gemspec.rb +17 -15
  21. data/generators/active_merchant/templates/pom.xml.rb +1 -1
  22. data/generators/active_merchant/templates/release.sh.rb +34 -14
  23. data/generators/active_merchant/templates/spec/base_plugin_spec.rb +5 -7
  24. data/generators/active_merchant/templates/spec/integration_spec.rb +7 -18
  25. data/killbill.gemspec +21 -15
  26. data/lib/killbill/ext/active_merchant/typhoeus_connection.rb +3 -4
  27. data/lib/killbill/gen/api/account.rb +1 -1
  28. data/lib/killbill/gen/api/account_data.rb +1 -1
  29. data/lib/killbill/gen/api/audit_log.rb +2 -2
  30. data/lib/killbill/gen/api/audit_user_api.rb +3 -3
  31. data/lib/killbill/gen/api/block.rb +1 -1
  32. data/lib/killbill/gen/api/blocking_state.rb +1 -1
  33. data/lib/killbill/gen/api/call_context.rb +2 -2
  34. data/lib/killbill/gen/api/control_tag.rb +2 -2
  35. data/lib/killbill/gen/api/currency_conversion.rb +1 -1
  36. data/lib/killbill/gen/api/currency_conversion_api.rb +2 -2
  37. data/lib/killbill/gen/api/custom_field.rb +1 -1
  38. data/lib/killbill/gen/api/custom_field_user_api.rb +2 -2
  39. data/lib/killbill/gen/api/dry_run_arguments.rb +22 -3
  40. data/lib/killbill/gen/api/duration.rb +1 -1
  41. data/lib/killbill/gen/api/entitlement.rb +3 -3
  42. data/lib/killbill/gen/api/entitlement_ao_status_dry_run.rb +3 -3
  43. data/lib/killbill/gen/api/entitlement_api.rb +25 -7
  44. data/lib/killbill/gen/api/fixed.rb +1 -1
  45. data/lib/killbill/gen/api/invoice.rb +1 -1
  46. data/lib/killbill/gen/api/invoice_formatter.rb +2 -2
  47. data/lib/killbill/gen/api/invoice_item.rb +2 -2
  48. data/lib/killbill/gen/api/invoice_item_formatter.rb +2 -2
  49. data/lib/killbill/gen/api/invoice_payment.rb +3 -3
  50. data/lib/killbill/gen/api/invoice_user_api.rb +2 -2
  51. data/lib/killbill/gen/api/migration_plan.rb +1 -1
  52. data/lib/killbill/gen/api/mutable_account_data.rb +1 -1
  53. data/lib/killbill/gen/api/payment.rb +1 -1
  54. data/lib/killbill/gen/api/payment_api.rb +11 -11
  55. data/lib/killbill/gen/api/payment_transaction.rb +4 -4
  56. data/lib/killbill/gen/api/plan.rb +1 -1
  57. data/lib/killbill/gen/api/plan_change_result.rb +2 -2
  58. data/lib/killbill/gen/api/plan_phase.rb +1 -1
  59. data/lib/killbill/gen/api/plan_phase_price_override.rb +93 -0
  60. data/lib/killbill/gen/api/plan_phase_price_overrides_with_call_context.rb +77 -0
  61. data/lib/killbill/gen/api/plan_phase_specifier.rb +3 -3
  62. data/lib/killbill/gen/api/plan_specifier.rb +2 -2
  63. data/lib/killbill/gen/api/price.rb +1 -1
  64. data/lib/killbill/gen/api/product.rb +1 -1
  65. data/lib/killbill/gen/api/rate.rb +2 -2
  66. data/lib/killbill/gen/api/record_id_api.rb +1 -1
  67. data/lib/killbill/gen/api/recurring.rb +1 -1
  68. data/lib/killbill/gen/api/refund.rb +2 -2
  69. data/lib/killbill/gen/api/require_gen.rb +2 -0
  70. data/lib/killbill/gen/api/static_catalog.rb +2 -2
  71. data/lib/killbill/gen/api/subscription.rb +3 -3
  72. data/lib/killbill/gen/api/subscription_event.rb +3 -3
  73. data/lib/killbill/gen/api/tag.rb +1 -1
  74. data/lib/killbill/gen/api/tag_definition.rb +1 -1
  75. data/lib/killbill/gen/api/tag_user_api.rb +6 -6
  76. data/lib/killbill/gen/api/tiered_block.rb +1 -1
  77. data/lib/killbill/gen/api/usage.rb +3 -3
  78. data/lib/killbill/gen/plugin-api/currency_plugin_api.rb +1 -1
  79. data/lib/killbill/gen/plugin-api/ext_bus_event.rb +2 -2
  80. data/lib/killbill/gen/plugin-api/payment_transaction_info_plugin.rb +3 -3
  81. data/lib/killbill/helpers/active_merchant.rb +2 -2
  82. data/lib/killbill/helpers/active_merchant/active_record.rb +1 -1
  83. data/lib/killbill/helpers/active_merchant/active_record/active_record_helper.rb +14 -0
  84. data/lib/killbill/helpers/active_merchant/active_record/models/helpers.rb +8 -0
  85. data/lib/killbill/helpers/active_merchant/active_record/models/payment_method.rb +10 -8
  86. data/lib/killbill/helpers/active_merchant/active_record/models/response.rb +16 -3
  87. data/lib/killbill/helpers/active_merchant/active_record/models/streamy_result_set.rb +1 -3
  88. data/lib/killbill/helpers/active_merchant/active_record/models/transaction.rb +2 -0
  89. data/lib/killbill/helpers/active_merchant/configuration.rb +119 -27
  90. data/lib/killbill/helpers/active_merchant/gateway.rb +40 -27
  91. data/lib/killbill/helpers/active_merchant/killbill_spec_helper.rb +63 -45
  92. data/lib/killbill/helpers/active_merchant/payment_plugin.rb +121 -95
  93. data/lib/killbill/helpers/active_merchant/private_payment_plugin.rb +1 -1
  94. data/lib/killbill/helpers/active_merchant/properties.rb +9 -2
  95. data/lib/killbill/helpers/active_merchant/sinatra.rb +4 -8
  96. data/lib/killbill/helpers/active_merchant/utils.rb +44 -0
  97. data/lib/killbill/helpers/properties_helper.rb +41 -0
  98. data/lib/killbill/http_servlet.rb +11 -4
  99. data/lib/killbill/killbill_api.rb +6 -4
  100. data/lib/killbill/rake_task.rb +542 -102
  101. data/spec/killbill/helpers/configuration_spec.rb +117 -33
  102. data/spec/killbill/helpers/payment_method_spec.rb +20 -17
  103. data/spec/killbill/helpers/payment_plugin_spec.rb +401 -201
  104. data/spec/killbill/helpers/private_payment_plugin_spec.rb +3 -16
  105. data/spec/killbill/helpers/response_spec.rb +92 -22
  106. data/spec/killbill/helpers/streamy_result_set_spec.rb +3 -2
  107. data/spec/killbill/helpers/test_payment_method.rb +9 -0
  108. data/spec/killbill/helpers/test_response.rb +11 -0
  109. data/spec/killbill/helpers/test_schema.rb +6 -6
  110. data/spec/killbill/helpers/test_transaction.rb +11 -0
  111. data/spec/killbill/helpers/transaction_spec.rb +3 -13
  112. data/spec/killbill/helpers/utils_spec.rb +127 -69
  113. data/spec/spec_helper.rb +69 -18
  114. metadata +77 -71
  115. data/lib/killbill/ext/active_merchant/jdbc_connection.rb +0 -92
  116. data/lib/killbill/ext/active_merchant/proxy_support.rb +0 -58
  117. data/spec/killbill/helpers/gateway_spec.rb +0 -36
@@ -1,7 +1,4 @@
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::PrivatePaymentPlugin do
7
4
 
@@ -54,28 +51,18 @@ Pay!
54
51
  private
55
52
 
56
53
  def setup_public_plugin
57
- Dir.mktmpdir do |dir|
58
- file = File.new(File.join(dir, 'test.yml'), 'w+')
59
- file.write(<<-eos)
60
- :test:
61
- :test: true
62
- # As defined by spec_helper.rb
63
- :database:
64
- :adapter: 'sqlite3'
65
- :database: 'test.db'
66
- eos
67
- file.close
68
-
54
+ with_plugin_yaml_config('test.yml', :test => { :test => true }) do |file|
69
55
  plugin = ::Killbill::Plugin::ActiveMerchant::PaymentPlugin.new(Proc.new { |config| nil },
70
56
  :test,
71
57
  ::Killbill::Test::TestPaymentMethod,
72
58
  ::Killbill::Test::TestTransaction,
73
59
  ::Killbill::Test::TestResponse)
74
60
  payment_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaPaymentApi.new
75
- tenant_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaTenantUserApi.new({})
61
+ tenant_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaTenantUserApi.new
76
62
 
77
63
  plugin.kb_apis = ::Killbill::Plugin::KillbillApi.new('test', {:payment_api => payment_api, :tenant_user_api => tenant_api})
78
64
  plugin.logger = Logger.new(STDOUT)
65
+ plugin.logger.level = ActiveRecord::Base.logger.level
79
66
  plugin.conf_dir = File.dirname(file)
80
67
  plugin.root = File.dirname(file)
81
68
  # Start the plugin here - since the config file will be deleted
@@ -1,17 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'spec/killbill/helpers/transaction_spec'
3
-
4
- module Killbill #:nodoc:
5
- module Test #:nodoc:
6
- class TestResponse < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Response
7
-
8
- self.table_name = 'test_responses'
9
-
10
- has_one :test_transaction
11
-
12
- end
13
- end
14
- end
15
2
 
16
3
  describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
17
4
 
@@ -60,7 +47,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
60
47
  # No associated transaction
61
48
  ptip.amount.should be_nil
62
49
  ptip.currency.should be_nil
63
- ptip.status.should == :PROCESSED
50
+ ptip.status.should == :UNDEFINED
64
51
  ptip.gateway_error.should == 'Message'
65
52
  ptip.gateway_error_code.should be_nil
66
53
  ptip.first_payment_reference_id.should be_nil
@@ -72,10 +59,13 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
72
59
  api_call = 'for debugging only'
73
60
  kb_account_id = SecureRandom.uuid
74
61
  kb_payment_id = SecureRandom.uuid
62
+ kb_payment_id2 = SecureRandom.uuid
63
+ kb_payment_id3 = SecureRandom.uuid
75
64
  kb_payment_transaction_id = SecureRandom.uuid
76
65
  transaction_type = :PURCHASE
77
66
  payment_processor_account_id = 'petit_poucet'
78
67
  kb_tenant_id = SecureRandom.uuid
68
+ kb_tenant_id2 = SecureRandom.uuid
79
69
  success_response = ::ActiveMerchant::Billing::Response.new(true, 'Message', {}, {
80
70
  :authorization => SecureRandom.uuid,
81
71
  :avs_result => ::ActiveMerchant::Billing::AVSResult.new(:code => 'P')
@@ -85,6 +75,7 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
85
75
  :avs_result => ::ActiveMerchant::Billing::AVSResult.new(:code => 'P')
86
76
  })
87
77
 
78
+ # Successful response
88
79
  response, transaction = ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, success_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
89
80
  found_response = ::Killbill::Test::TestResponse.find(response.id)
90
81
  found_response.should == response
@@ -93,17 +84,36 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
93
84
  found_transaction.should == transaction
94
85
  found_transaction.test_response.should == response
95
86
 
87
+ successful_responses = ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id, kb_tenant_id)
88
+ successful_responses.size.should == 1
89
+ successful_responses[0].should == response
90
+
91
+ # Unsuccessful response
96
92
  response, transaction = ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, failure_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
97
93
  transaction.should be_nil
98
94
  found_response = ::Killbill::Test::TestResponse.find(response.id)
99
95
  found_response.should == response
100
96
  found_response.test_transaction.should be_nil
101
97
 
98
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id, kb_tenant_id).size == 2
99
+
100
+ # Another successful response for the same payment (different transaction)
101
+ ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id, SecureRandom.uuid, transaction_type, payment_processor_account_id, kb_tenant_id, success_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
102
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id, kb_tenant_id).size == 3
103
+
104
+ # Add other successful responses
105
+ ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id2, SecureRandom.uuid, transaction_type, payment_processor_account_id, kb_tenant_id, success_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
106
+ ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id3, SecureRandom.uuid, transaction_type, payment_processor_account_id, kb_tenant_id2, success_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
107
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id, kb_tenant_id).size == 3
108
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id2, kb_tenant_id).size == 1
109
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id3, kb_tenant_id2).size == 1
110
+
102
111
  # Lookup responses for kb_payment_id
103
112
  responses = ::Killbill::Test::TestResponse.responses_from_kb_payment_id(transaction_type, kb_payment_id, kb_tenant_id)
104
- responses.size.should == 2
113
+ responses.size.should == 3
105
114
  responses[0].success.should be_true
106
115
  responses[1].success.should be_false
116
+ responses[2].success.should be_true
107
117
 
108
118
  # Lookup responses for kb_payment_transaction_id
109
119
  responses = ::Killbill::Test::TestResponse.responses_from_kb_payment_transaction_id(transaction_type, kb_payment_transaction_id, kb_tenant_id)
@@ -118,25 +128,30 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
118
128
  ::Killbill::Test::TestResponse.responses_from_kb_payment_transaction_id(:foo, kb_payment_transaction_id, kb_tenant_id).size.should == 0
119
129
  ::Killbill::Test::TestResponse.responses_from_kb_payment_transaction_id(transaction_type, SecureRandom.uuid, kb_tenant_id).size.should == 0
120
130
  ::Killbill::Test::TestResponse.responses_from_kb_payment_transaction_id(transaction_type, kb_payment_transaction_id, SecureRandom.uuid).size.should == 0
131
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, SecureRandom.uuid, kb_tenant_id).size.should == 0
132
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id, SecureRandom.uuid).size.should == 0
133
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id, kb_tenant_id2).size == 0
134
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id2, kb_tenant_id2).size == 0
135
+ ::Killbill::Test::TestResponse.from_kb_payment_id(::Killbill::Test::TestTransaction, kb_payment_id3, kb_tenant_id).size == 0
121
136
  end
122
137
 
123
138
  it 'should generate the right SQL query' do
124
139
  # Check count query (search query numeric)
125
- 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\""
140
+ expected_query = "SELECT COUNT(DISTINCT #{q('test_responses')}.#{q('id')}) FROM #{q('test_responses')} WHERE ((((#{q('test_responses')}.#{q('kb_payment_id')} = '1234' OR #{q('test_responses')}.#{q('kb_payment_transaction_id')} = '1234') OR #{q('test_responses')}.#{q('message')} = '1234') OR #{q('test_responses')}.#{q('authorization')} = '1234') OR #{q('test_responses')}.#{q('fraud_review')} = '1234') AND #{q('test_responses')}.#{q('success')} = #{qtrue} AND #{q('test_responses')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_responses')}.#{q('id')}"
126
141
  # Note that Kill Bill will pass a String, even for numeric types
127
142
  ::Killbill::Test::TestResponse.search_query('1234', '11-22-33').to_sql.should == expected_query
128
143
 
129
144
  # Check query with results (search query numeric)
130
- 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"
145
+ expected_query = "SELECT DISTINCT #{q('test_responses')}.* FROM #{q('test_responses')} WHERE ((((#{q('test_responses')}.#{q('kb_payment_id')} = '1234' OR #{q('test_responses')}.#{q('kb_payment_transaction_id')} = '1234') OR #{q('test_responses')}.#{q('message')} = '1234') OR #{q('test_responses')}.#{q('authorization')} = '1234') OR #{q('test_responses')}.#{q('fraud_review')} = '1234') AND #{q('test_responses')}.#{q('success')} = #{qtrue} AND #{q('test_responses')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_responses')}.#{q('id')} LIMIT 10 OFFSET 0"
131
146
  # Note that Kill Bill will pass a String, even for numeric types
132
147
  ::Killbill::Test::TestResponse.search_query('1234', '11-22-33', 0, 10).to_sql.should == expected_query
133
148
 
134
149
  # Check count query (search query string)
135
- 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\""
150
+ expected_query = "SELECT COUNT(DISTINCT #{q('test_responses')}.#{q('id')}) FROM #{q('test_responses')} WHERE ((((#{q('test_responses')}.#{q('kb_payment_id')} = 'XXX' OR #{q('test_responses')}.#{q('kb_payment_transaction_id')} = 'XXX') OR #{q('test_responses')}.#{q('message')} = 'XXX') OR #{q('test_responses')}.#{q('authorization')} = 'XXX') OR #{q('test_responses')}.#{q('fraud_review')} = 'XXX') AND #{q('test_responses')}.#{q('success')} = #{qtrue} AND #{q('test_responses')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_responses')}.#{q('id')}"
136
151
  ::Killbill::Test::TestResponse.search_query('XXX', '11-22-33').to_sql.should == expected_query
137
152
 
138
153
  # Check query with results (search query string)
139
- 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"
154
+ expected_query = "SELECT DISTINCT #{q('test_responses')}.* FROM #{q('test_responses')} WHERE ((((#{q('test_responses')}.#{q('kb_payment_id')} = 'XXX' OR #{q('test_responses')}.#{q('kb_payment_transaction_id')} = 'XXX') OR #{q('test_responses')}.#{q('message')} = 'XXX') OR #{q('test_responses')}.#{q('authorization')} = 'XXX') OR #{q('test_responses')}.#{q('fraud_review')} = 'XXX') AND #{q('test_responses')}.#{q('success')} = #{qtrue} AND #{q('test_responses')}.#{q('kb_tenant_id')} = '11-22-33' ORDER BY #{q('test_responses')}.#{q('id')} LIMIT 10 OFFSET 0"
140
155
  ::Killbill::Test::TestResponse.search_query('XXX', '11-22-33', 0, 10).to_sql.should == expected_query
141
156
  end
142
157
 
@@ -147,14 +162,18 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
147
162
  :kb_account_id => '55-66-77-88',
148
163
  :kb_payment_id => '11-22-33-44',
149
164
  :kb_tenant_id => '11-22-33',
150
- :success => true
165
+ :success => true,
166
+ :created_at => Time.now.utc,
167
+ :updated_at => Time.now.utc
151
168
 
152
169
  # Not successful
153
170
  ignored2 = ::Killbill::Test::TestResponse.create :api_call => 'charge',
154
171
  :kb_account_id => '55-66-77-88',
155
172
  :kb_payment_id => pm.kb_payment_id,
156
173
  :kb_tenant_id => '11-22-33',
157
- :success => false
174
+ :success => false,
175
+ :created_at => Time.now.utc,
176
+ :updated_at => Time.now.utc
158
177
 
159
178
  do_search(pm.kb_payment_id).size.should == 1
160
179
 
@@ -162,11 +181,54 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
162
181
  :kb_account_id => '55-66-77-88',
163
182
  :kb_payment_id => pm.kb_payment_id,
164
183
  :kb_tenant_id => '11-22-33',
165
- :success => true
184
+ :success => true,
185
+ :created_at => Time.now.utc,
186
+ :updated_at => Time.now.utc
166
187
 
167
188
  do_search(pm.kb_payment_id).size.should == 2
168
189
  end
169
190
 
191
+ context 'performance' do
192
+ require 'benchmark'
193
+
194
+ it 'creates the transaction association fast' do
195
+ api_call = 'for debugging only'
196
+ kb_account_id = SecureRandom.uuid
197
+ kb_payment_id = SecureRandom.uuid
198
+ kb_payment_transaction_id = SecureRandom.uuid
199
+ transaction_type = :PURCHASE
200
+ payment_processor_account_id = SecureRandom.uuid
201
+ kb_tenant_id = SecureRandom.uuid
202
+ success_response = ::ActiveMerchant::Billing::Response.new(true, 'Message')
203
+
204
+ # Warm-up the stack
205
+ response, transaction = ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, success_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
206
+
207
+ runs = (ENV['NB_RUNS'] || 2).to_i
208
+
209
+ time = Benchmark::Tms.new
210
+ Benchmark.bm do |x|
211
+ runs.times do |n|
212
+ time += x.report("run ##{n}:") do
213
+ response, transaction = ::Killbill::Test::TestResponse.create_response_and_transaction('test', ::Killbill::Test::TestTransaction, api_call, kb_account_id, kb_payment_id, kb_payment_transaction_id, transaction_type, payment_processor_account_id, kb_tenant_id, success_response, 120, 'USD', {}, ::Killbill::Test::TestResponse)
214
+
215
+ response.id.should_not be_nil
216
+ response.created_at.should_not be_nil
217
+ response.updated_at.should_not be_nil
218
+
219
+ transaction.id.should_not be_nil
220
+ transaction.created_at.should_not be_nil
221
+ transaction.updated_at.should_not be_nil
222
+ transaction.test_response_id.should == response.id
223
+ end
224
+ end
225
+ end
226
+
227
+ puts " total:#{time.to_s}"
228
+ puts " avg:#{(time/runs).to_s}"
229
+ end
230
+ end
231
+
170
232
  private
171
233
 
172
234
  def do_search(search_key)
@@ -176,4 +238,12 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Response do
176
238
  pagination.total_nb_records.should == results.size
177
239
  results
178
240
  end
241
+
242
+ def q(arg)
243
+ ::ActiveRecord::Base.connection.quote_column_name(arg)
244
+ end
245
+
246
+ def qtrue
247
+ ::ActiveRecord::Base.connection.quoted_true
248
+ end
179
249
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'spec/killbill/helpers/payment_method_spec'
3
2
 
4
3
  describe Killbill::Plugin::ActiveMerchant::ActiveRecord do
5
4
 
@@ -12,7 +11,9 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord do
12
11
  ::Killbill::Test::TestPaymentMethod.create(:kb_account_id => SecureRandom.uuid,
13
12
  :kb_payment_method_id => SecureRandom.uuid,
14
13
  :kb_tenant_id => SecureRandom.uuid,
15
- :token => SecureRandom.uuid)
14
+ :token => SecureRandom.uuid,
15
+ :created_at => Time.now.utc,
16
+ :updated_at => Time.now.utc)
16
17
  end
17
18
  ::Killbill::Test::TestPaymentMethod.count.should == 35
18
19
 
@@ -0,0 +1,9 @@
1
+ module Killbill #:nodoc:
2
+ module Test #:nodoc:
3
+ class TestPaymentMethod < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::PaymentMethod
4
+
5
+ self.table_name = 'test_payment_methods'
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Killbill #:nodoc:
2
+ module Test #:nodoc:
3
+ class TestResponse < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Response
4
+
5
+ self.table_name = 'test_responses'
6
+
7
+ has_one :test_transaction
8
+
9
+ end
10
+ end
11
+ end
@@ -23,8 +23,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
23
23
  t.string "zip"
24
24
  t.string "country"
25
25
  t.boolean "is_deleted", :null => false, :default => false
26
- t.datetime "created_at", :null => false
27
- t.datetime "updated_at", :null => false
26
+ t.datetime "created_at", :null => false, :limit => 3
27
+ t.datetime "updated_at", :null => false, :limit => 3
28
28
  t.string "kb_account_id", :null => false
29
29
  t.string "kb_tenant_id", :null => false
30
30
  end
@@ -42,8 +42,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
42
42
  t.string "txn_id"
43
43
  t.integer "amount_in_cents"
44
44
  t.string "currency"
45
- t.datetime "created_at", :null => false
46
- t.datetime "updated_at", :null => false
45
+ t.datetime "created_at", :null => false, :limit => 3
46
+ t.datetime "updated_at", :null => false, :limit => 3
47
47
  t.string "kb_account_id", :null => false
48
48
  t.string "kb_tenant_id", :null => false
49
49
  end
@@ -67,8 +67,8 @@ ActiveRecord::Schema.define(:version => 20140410153635) do
67
67
  t.string "cvv_result_code"
68
68
  t.string "cvv_result_message"
69
69
  t.boolean "success"
70
- t.datetime "created_at", :null => false
71
- t.datetime "updated_at", :null => false
70
+ t.datetime "created_at", :null => false, :limit => 3
71
+ t.datetime "updated_at", :null => false, :limit => 3
72
72
  t.string "kb_account_id", :null => false
73
73
  t.string "kb_tenant_id", :null => false
74
74
  end
@@ -0,0 +1,11 @@
1
+ module Killbill #:nodoc:
2
+ module Test #:nodoc:
3
+ class TestTransaction < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Transaction
4
+
5
+ self.table_name = 'test_transactions'
6
+
7
+ belongs_to :test_response
8
+
9
+ end
10
+ end
11
+ end
@@ -1,17 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Killbill #:nodoc:
4
- module Test #:nodoc:
5
- class TestTransaction < ::Killbill::Plugin::ActiveMerchant::ActiveRecord::Transaction
6
-
7
- self.table_name = 'test_transactions'
8
-
9
- belongs_to :test_response
10
-
11
- end
12
- end
13
- end
14
-
15
3
  describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Transaction do
16
4
 
17
5
  before :all do
@@ -131,6 +119,8 @@ describe Killbill::Plugin::ActiveMerchant::ActiveRecord::Transaction do
131
119
  :currency => currency,
132
120
  :kb_account_id => kb_account_id,
133
121
  :kb_tenant_id => kb_tenant_id,
134
- :test_response_id => 0)
122
+ :test_response_id => 0,
123
+ :created_at => Time.now.utc,
124
+ :updated_at => Time.now.utc)
135
125
  end
136
126
  end
@@ -1,96 +1,154 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Killbill::Plugin::ActiveMerchant::Utils do
4
- it 'should convert back and forth UUIDs' do
5
- uuid = SecureRandom.uuid
6
- packed = Killbill::Plugin::ActiveMerchant::Utils.compact_uuid(uuid)
7
- unpacked = Killbill::Plugin::ActiveMerchant::Utils.unpack_uuid(packed)
8
- unpacked.should == uuid
9
- end
10
4
 
11
- it 'should respect leading 0s' do
12
- uuid = '0ae18a4c-be57-44c3-84ba-a82962a2de03'
13
- 0.upto(35) do |i|
14
- # Skip hyphens
15
- next if [8, 13, 18, 23].include?(i)
16
- uuid[i] = '0'
17
- packed = Killbill::Plugin::ActiveMerchant::Utils.compact_uuid(uuid)
5
+ context 'UUID' do
6
+ it 'should convert back and forth UUIDs' do
7
+ uuid = SecureRandom.uuid
8
+ packed = Killbill::Plugin::ActiveMerchant::Utils.compact_uuid(uuid)
18
9
  unpacked = Killbill::Plugin::ActiveMerchant::Utils.unpack_uuid(packed)
19
10
  unpacked.should == uuid
20
11
  end
12
+
13
+ it 'should respect leading 0s' do
14
+ uuid = '0ae18a4c-be57-44c3-84ba-a82962a2de03'
15
+ 0.upto(35) do |i|
16
+ # Skip hyphens
17
+ next if [8, 13, 18, 23].include?(i)
18
+ uuid[i] = '0'
19
+ packed = Killbill::Plugin::ActiveMerchant::Utils.compact_uuid(uuid)
20
+ unpacked = Killbill::Plugin::ActiveMerchant::Utils.unpack_uuid(packed)
21
+ unpacked.should == uuid
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'normalization' do
27
+ it 'normalizes true values' do
28
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(true).should be_true
29
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize('true').should be_true
30
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(' true ').should be_true
31
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(:true).should be_true
32
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize('yes').should be_true
33
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize('yes ').should be_true
34
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(:yes).should be_true
35
+ end
36
+
37
+ it 'normalizes false values' do
38
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(false).should be_false
39
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(' false ').should be_false
40
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(:false).should be_false
41
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize('no').should be_false
42
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize('no ').should be_false
43
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalize(:no).should be_false
44
+ end
45
+
46
+ it 'understands snake case and camel case' do
47
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:skip_gw => 'true'}, :skip_gw).should be_true
48
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:skip_gw => 'false'}, :skip_gw).should be_false
49
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:skipGw => 'true'}, :skip_gw).should be_true
50
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:skipGw => 'false'}, :skip_gw).should be_false
51
+ end
52
+
53
+ it 'normalizes non-boolean attributes' do
54
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({}, :cc_first_name).should be_nil
55
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:cc_first_name => ''}, :cc_first_name).should be_nil
56
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:cc_first_name => 'Paul'}, :cc_first_name).should == 'Paul'
57
+ ::Killbill::Plugin::ActiveMerchant::Utils.normalized({:ccFirstName => 'Paul'}, :cc_first_name).should == 'Paul'
58
+ end
59
+ end
60
+
61
+ context 'KBWiredumpDevice' do
62
+ it 'should implement a wiredump device for the Kill Bill logger' do
63
+ logger = Logger.new(STDOUT)
64
+ logger.level = Logger::INFO
65
+
66
+ io = ::Killbill::Plugin::ActiveMerchant::Utils::KBWiredumpDevice.new(logger)
67
+ io.sync = true
68
+ io.sync.should be_true
69
+ io << 'This is an I/O test'
70
+
71
+ jlogger = ::Killbill::Plugin::KillbillLogger.new(logger)
72
+ jio = ::Killbill::Plugin::ActiveMerchant::Utils::KBWiredumpDevice.new(jlogger)
73
+ jio.sync = true
74
+ jio.sync.should be_true
75
+ jio << 'This is an I/O test (via Java)'
76
+ end
21
77
  end
22
78
 
23
- it 'should implement a wiredump device for the Kill Bill logger' do
24
- logger = Logger.new(STDOUT)
25
- logger.level = Logger::INFO
79
+ context 'LazyEvaluator' do
80
+ it 'defers evaluation until called' do
81
+ argument = {:int => 12}
82
+
83
+ double_argument = ::Killbill::Plugin::ActiveMerchant::Utils::LazyEvaluator.new { argument[:int] *= 2 }
84
+ argument[:int].should == 12
26
85
 
27
- io = ::Killbill::Plugin::ActiveMerchant::Utils::KBWiredumpDevice.new(logger)
28
- io.sync = true
29
- io.sync.should be_true
30
- io << 'This is an I/O test'
86
+ double_argument.to_i.should == 24
87
+ argument[:int].should == 24
31
88
 
32
- jlogger = ::Killbill::Plugin::KillbillLogger.new(logger)
33
- jio = ::Killbill::Plugin::ActiveMerchant::Utils::KBWiredumpDevice.new(jlogger)
34
- jio.sync = true
35
- jio.sync.should be_true
36
- jio << 'This is an I/O test (via Java)'
89
+ # The block should be invoked exactly once
90
+ double_argument.to_i.should == 24
91
+ argument[:int].should == 24
92
+ end
37
93
  end
38
94
 
39
- it 'should implement a thread-safe LRU cache' do
40
- require 'benchmark'
41
-
42
- runs = 2
43
- cache_size = 50
44
- nb_threads = (ENV['NB_THREADS'] || 200).to_i
45
- keys_per_thread = 1000
46
-
47
- cache = nil
48
- Benchmark.bm do |x|
49
- runs.times do |n|
50
- x.report("run ##{n}:") do
51
- cache = ::Killbill::Plugin::ActiveMerchant::Utils::BoundedLRUCache.new(Proc.new { |value| -1 }, cache_size)
52
-
53
- threads = (0..nb_threads).map do |i|
54
- Thread.new do
55
- (0..keys_per_thread).each do |j|
56
- key = 1001 * i + j
57
- value = rand(2000)
58
- cache[key] = value
59
- cache[key].should satisfy { |cache_value| cache_value == -1 or cache_value == value }
95
+ context 'BoundedLRUCache' do
96
+ it 'should implement a thread-safe LRU cache' do
97
+ require 'benchmark'
98
+
99
+ runs = 2
100
+ cache_size = 50
101
+ nb_threads = (ENV['NB_THREADS'] || 200).to_i
102
+ keys_per_thread = 1000
103
+
104
+ cache = nil
105
+ Benchmark.bm do |x|
106
+ runs.times do |n|
107
+ x.report("run ##{n}:") do
108
+ cache = ::Killbill::Plugin::ActiveMerchant::Utils::BoundedLRUCache.new(Proc.new { |value| -1 }, cache_size)
109
+
110
+ threads = (0..nb_threads).map do |i|
111
+ Thread.new do
112
+ (0..keys_per_thread).each do |j|
113
+ key = 1001 * i + j
114
+ value = rand(2000)
115
+ cache[key] = value
116
+ cache[key].should satisfy { |cache_value| cache_value == -1 or cache_value == value }
117
+ end
60
118
  end
61
119
  end
62
- end
63
120
 
64
- threads.each { |thread| thread.join }
121
+ threads.each { |thread| thread.join }
122
+ end
65
123
  end
66
124
  end
67
- end
68
125
 
69
- last_keys = cache.keys
70
- last_values = cache.values
71
- 0.upto(cache_size - 1) do |i|
72
- # No overlap with test keys or values above
73
- cache[-1 * i - 1] = -2
126
+ last_keys = cache.keys
127
+ last_values = cache.values
128
+ 0.upto(cache_size - 1) do |i|
129
+ # No overlap with test keys or values above
130
+ cache[-1 * i - 1] = -2
74
131
 
75
- new_keys = cache.keys
76
- new_values = cache.values
132
+ new_keys = cache.keys
133
+ new_values = cache.values
77
134
 
78
- # Verify the changes we made
79
- 0.upto(i) do |j|
80
- idx = cache_size - j - 1
81
- expected_key = -1 * (i - j) - 1
82
- expected_value = -2
135
+ # Verify the changes we made
136
+ 0.upto(i) do |j|
137
+ idx = cache_size - j - 1
138
+ expected_key = -1 * (i - j) - 1
139
+ expected_value = -2
83
140
 
84
- new_keys[idx].should eq(expected_key), "i=#{i}, j=#{j}, idx=#{idx}, expected_key=#{expected_key}, new_keys=#{new_keys.inspect}, last_keys=#{last_keys}"
85
- new_values[idx].should eq(expected_value), "i=#{i}, j=#{j}, idx=#{idx}, expected_value=#{expected_value}, new_values=#{new_values.inspect}, last_values=#{last_values.inspect}"
86
- end
141
+ new_keys[idx].should eq(expected_key), "i=#{i}, j=#{j}, idx=#{idx}, expected_key=#{expected_key}, new_keys=#{new_keys.inspect}, last_keys=#{last_keys}"
142
+ new_values[idx].should eq(expected_value), "i=#{i}, j=#{j}, idx=#{idx}, expected_value=#{expected_value}, new_values=#{new_values.inspect}, last_values=#{last_values.inspect}"
143
+ end
87
144
 
88
- # Check we didn't override older entries
89
- new_keys.slice(0, cache_size - i - 1).should eq(last_keys.slice(i + 1, cache_size)), "i=#{i}, new_keys=#{new_keys.inspect}, last_keys=#{last_keys.inspect}"
90
- new_values.slice(0, cache_size - i - 1).should eq(last_values.slice(i + 1, cache_size)), "i=#{i}, new_values=#{new_values.inspect}, last_values=#{last_values.inspect}"
145
+ # Check we didn't override older entries
146
+ new_keys.slice(0, cache_size - i - 1).should eq(last_keys.slice(i + 1, cache_size)), "i=#{i}, new_keys=#{new_keys.inspect}, last_keys=#{last_keys.inspect}"
147
+ new_values.slice(0, cache_size - i - 1).should eq(last_values.slice(i + 1, cache_size)), "i=#{i}, new_values=#{new_values.inspect}, last_values=#{last_values.inspect}"
91
148
 
92
- # Check there is no change in cache size
93
- cache.size.should == cache_size
149
+ # Check there is no change in cache size
150
+ cache.size.should == cache_size
151
+ end
94
152
  end
95
153
  end
96
154
  end