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
@@ -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