3scale_client 2.7.0 → 2.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8f639b2cd5fc3a94a43a71e46d25764a6069bcf3
4
- data.tar.gz: e78be7244735a016e216f68de2df731fd0da658f
3
+ metadata.gz: 881aa442d660c091dadbbd20b2446d506343cf38
4
+ data.tar.gz: 0a8d027ad84fda9f5f24a486124d2a003c3aa5ab
5
5
  SHA512:
6
- metadata.gz: 7a425a24452f22fbb738d07bccacaf3169db5ea0235839a3fb3bba7cb0c35c43a792dfece492ef989b4a8e681feff6975e7163e220c4ad04cc5ebb1a565a6486
7
- data.tar.gz: ae3cd7543511cbd604ff4dbf930181c3e1dfbc34463b89a189bd933da4eac56a9d7c46fb677eecc7b14eb25de79a0c58761ef4ca6e3b9f30066ce9db37f68f6c
6
+ metadata.gz: a2c751900a737e62312b0fd9dd530a6ac45a494eb46bf95e51fa8daed741f275a2e5c789b1b6477f79306490f9670d3c4f8ece97e21fdb28d9d0d23dcbfba26f
7
+ data.tar.gz: 99fbf6a2bf089e96ba7df746e56a53b5543fe76b237eee230c151a5ca16327931d4b346632e47801a54b0f4898f413866515395a7c9d0d7f5939c60b39b0144f
data/.travis.yml CHANGED
@@ -2,17 +2,26 @@ language: ruby
2
2
  cache: bundler
3
3
  sudo: false
4
4
  rvm:
5
- - 1.9.3
6
5
  - 2.0.0
7
6
  - 2.1
8
7
  - 2.2
9
8
  - 2.3.0
10
9
  - jruby
10
+ gemfile:
11
+ - Gemfile
12
+ - gemfiles/rack_1.gemfile
11
13
  matrix:
12
- include:
14
+ exclude:
15
+ - rvm: 2.0.0
16
+ gemfile: Gemfile
17
+ - rvm: 2.1
18
+ gemfile: Gemfile
19
+ - rvm: 2.2
20
+ gemfile: Gemfile
13
21
  - rvm: jruby
14
- env: JRUBY_OPTS="--2.0"
22
+ gemfile: Gemfile
15
23
  env:
16
24
  global:
17
25
  - TEST_3SCALE_APP_IDS=4d4b20b9 TEST_3SCALE_APP_KEYS=ecce202ecc2eb8dc7a499c34a34d5987
18
26
  - secure: VSElS0KvnufcZKStV7kj6xHFEiWvQkpxk1IEuhKq5JqywniN/6ScaNUFxbBKrOUrqhzXIRUCteBP2wvYRjlNhLFZSnYskzh7dLkOp/WV+WK6KjrdflTiF6UTxW4pBSsg6YDJ/wWJlmwsPVty1pRvOE3ru6uco+dTWCCLn4BvWqc=
27
+ - JRUBY_OPTS="--2.0"
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.required_ruby_version = '>= 2.0'
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.7"
22
24
  spec.add_development_dependency "rake"
23
25
  spec.add_development_dependency "rdoc"
@@ -26,5 +28,6 @@ Gem::Specification.new do |spec|
26
28
  spec.add_development_dependency "net-http-persistent"
27
29
  spec.add_development_dependency 'minitest'
28
30
  spec.add_development_dependency 'rack'
31
+ spec.add_development_dependency 'appraisal'
29
32
  spec.add_dependency 'nokogiri'
30
33
  end
data/Appraisals ADDED
@@ -0,0 +1,3 @@
1
+ appraise "rack-1" do
2
+ gem "rack", ['>= 1.0', '< 2.0']
3
+ end
data/CHANGELOG.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [2.8.0] - 2016-09-06
5
+ This version drops support for Ruby versions < 2.0.
6
+
7
+ ### Added
8
+ - Added support for reporting to services other than the default one.
9
+ `ThreeScale::Client#report` now accepts an optional `service_id`.
10
+ There has been a change in the params that the method accepts. This
11
+ change is backwards compatible but a deprecation warning is shown
12
+ when calling the method using the old params.
13
+ - The two authorize calls `ThreeScale::Client#Authorize` and
14
+ `ThreeScale::Client#oauth_authorize` now accept an optional predicted
15
+ usage parameter.
16
+ - It is now possible to specify a port different that the default
17
+ one for the API service management endpoint.
18
+
4
19
  ## [2.7.0] - 2016-08-26
5
20
  ### Added
6
21
  - Added support for 'user_key' authentication mode in 'report' method
data/README.md CHANGED
@@ -197,19 +197,30 @@ response.redirect_url
197
197
 
198
198
  ### Report
199
199
 
200
- To report usage, use the +report+ method. You can report multiple transaction at the same time:
200
+ To report usage, use the +report+ method. You can report multiple transactions at the same time:
201
201
 
202
202
  ```ruby
203
- response = client.report({:app_id => "first app id", :usage => {'hits' => 1}},
204
- {:app_id => "second app id", :usage => {'hits' => 1}})
203
+ response = client.report(
204
+ :transactions => [{:app_id => "first app id", :usage => {'hits' => 1}},
205
+ {:app_id => "second app id", :usage => {'hits' => 1}}])
206
+ ```
207
+
208
+ To specify a service other than the default one:
209
+ ```ruby
210
+ response = client.report(
211
+ :transactions => [{:app_id => "first app id", :usage => {'hits' => 1}},
212
+ {:app_id => "second app id", :usage => {'hits' => 1}}],
213
+ :service_id => 'service_123')
205
214
  ```
206
215
 
207
216
  The :app_id and :usage parameters are required. Additionaly, you can specify a timestamp
208
- of transaction:
217
+ of a transaction:
209
218
 
210
219
  ```ruby
211
- response = client.report({:app_id => "app id", :usage => {'hits' => 1},
212
- :timestamp => Time.local(2010, 4, 28, 12, 36)})
220
+ response = client.report(
221
+ :transactions => [{:app_id => "app id",
222
+ :usage => {'hits' => 1},
223
+ :timestamp => Time.local(2010, 4, 28, 12, 36)}])
213
224
  ```
214
225
 
215
226
  The timestamp can be either a Time object (from ruby's standard library) or something that
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.7.0
1
+ 2.8.0
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rack", [">= 1.0", "< 2.0"]
6
+
7
+ gemspec :path => "../"
data/lib/3scale/client.rb CHANGED
@@ -41,6 +41,12 @@ module ThreeScale
41
41
  class Client
42
42
  DEFAULT_HOST = 'su1.3scale.net'
43
43
 
44
+ DEPRECATION_MSG_OLD_REPORT = 'warning: def report(*transactions) is '\
45
+ 'deprecated. In next versions, the signature of the report method is '\
46
+ 'going to be: '\
47
+ 'def report(transactions: [], service_id: nil).'.freeze
48
+ private_constant :DEPRECATION_MSG_OLD_REPORT
49
+
44
50
  def initialize(options)
45
51
  if options[:provider_key].nil? || options[:provider_key] =~ /^\s*$/
46
52
  raise ArgumentError, 'missing :provider_key'
@@ -69,12 +75,7 @@ module ThreeScale
69
75
  end
70
76
 
71
77
  options_usage ||= {:hits => 1}
72
- usage = []
73
- options_usage.each_pair do |metric, value|
74
- escaped_metric = CGI.escape "[usage][#{metric}]"
75
- usage << "#{escaped_metric}=#{CGI.escape(value.to_s)}"
76
- end
77
- path += "&#{usage.join('&')}"
78
+ path += "&#{usage_query_params(options_usage)}"
78
79
 
79
80
  if options_log
80
81
  log = []
@@ -101,21 +102,23 @@ module ThreeScale
101
102
  #
102
103
  # == Parameters
103
104
  #
104
- # The parameters the transactions to report. Each transaction is a hash with
105
- # these elements:
106
- #
107
- # app_id:: ID of the application to report the transaction for. This parameter is
108
- # required.
109
- # usage:: Hash of usage values. The keys are metric names and values are
110
- # correspoding numeric values. Example: {'hits' => 1, 'transfer' => 1024}.
111
- # This parameter is required.
112
- # timestamp:: Timestamp of the transaction. This can be either a object of the
113
- # ruby's Time class, or a string in the "YYYY-MM-DD HH:MM:SS" format
114
- # (if the time is in the UTC), or a string in
115
- # the "YYYY-MM-DD HH:MM:SS ZZZZZ" format, where the ZZZZZ is the time offset
116
- # from the UTC. For example, "US Pacific Time" has offset -0800, "Tokyo"
117
- # has offset +0900. This parameter is optional, and if not provided, equals
118
- # to the current time.
105
+ # Hash with two fields:
106
+ #
107
+ # transactions:: It is required. It is an enumerable. Each element is a hash with the fields:
108
+ # app_id: ID of the application to report the transaction for. This parameter is
109
+ # required.
110
+ # usage: Hash of usage values. The keys are metric names and values are
111
+ # corresponding numeric values. Example: {'hits' => 1, 'transfer' => 1024}.
112
+ # This parameter is required.
113
+ # timestamp: Timestamp of the transaction. This can be either a object of the
114
+ # ruby's Time class, or a string in the "YYYY-MM-DD HH:MM:SS" format
115
+ # (if the time is in the UTC), or a string in
116
+ # the "YYYY-MM-DD HH:MM:SS ZZZZZ" format, where the ZZZZZ is the time offset
117
+ # from the UTC. For example, "US Pacific Time" has offset -0800, "Tokyo"
118
+ # has offset +0900. This parameter is optional, and if not provided, equals
119
+ # to the current time.
120
+ # service_id:: ID of the service. It is optional. When not specified, the transactions
121
+ # are reported to the default service.
119
122
  #
120
123
  # == Return
121
124
  #
@@ -127,20 +130,39 @@ module ThreeScale
127
130
  #
128
131
  # == Examples
129
132
  #
130
- # # Report two transactions of two applications.
131
- # client.report({:app_id => 'foo', :usage => {'hits' => 1}},
132
- # {:app_id => 'bar', :usage => {'hits' => 1}})
133
+ # Report two transactions of two applications. Using the default service.
134
+ # client.report(transactions: [{:app_id => 'foo', :usage => {'hits' => 1}},
135
+ # {:app_id => 'bar', :usage => {'hits' => 1}}])
136
+ #
137
+ # Report one transaction with timestamp. Using the default service.
138
+ # client.report(transactions: [{:app_id => 'foo',
139
+ # :timestamp => Time.local(2010, 4, 27, 15, 14),
140
+ # :usage => {'hits' => 1}])
141
+ #
142
+ # Report a transaction specifying the service.
143
+ # client.report(transactions: [{:app_id => 'foo', :usage => {'hits' => 1}}],
144
+ # service_id: 'a_service_id')
133
145
  #
134
- # # Report one transaction with timestamp.
135
- # client.report({:app_id => 'foo',
136
- # :timestamp => Time.local(2010, 4, 27, 15, 14),
137
- # :usage => {'hits' => 1})
146
+ # == Note
138
147
  #
139
- def report(*transactions)
140
- raise ArgumentError, 'no transactions to report' if transactions.empty?
148
+ # The signature of this method is a bit complicated because we decided to
149
+ # keep backwards compatibility with a previous version of the method:
150
+ # def report(*transactions)
151
+ def report(*reports, transactions: [], service_id: nil, **rest)
152
+ if (!transactions || transactions.empty?) && rest.empty?
153
+ raise ArgumentError, 'no transactions to report'
154
+ end
155
+
156
+ transactions = transactions.concat(reports)
157
+
158
+ unless rest.empty?
159
+ warn(DEPRECATION_MSG_OLD_REPORT)
160
+ transactions.concat([rest])
161
+ end
141
162
 
142
163
  payload = encode_transactions(transactions)
143
164
  payload['provider_key'] = CGI.escape(provider_key)
165
+ payload['service_id'] = CGI.escape(service_id.to_s) if service_id
144
166
 
145
167
  http_response = @http.post('/transactions.xml', payload)
146
168
 
@@ -164,6 +186,9 @@ module ThreeScale
164
186
  # app_key:: secret key assigned to the application. Required only if application has
165
187
  # a key defined.
166
188
  # service_id:: id of the service (required if you have more than one service)
189
+ # usage:: predicted usage. It is optional. It is a hash where the keys are metrics
190
+ # and the values their predicted usage.
191
+ # Example: {'hits' => 1, 'my_metric' => 100}
167
192
  #
168
193
  # == Return
169
194
  #
@@ -207,6 +232,9 @@ module ThreeScale
207
232
  #
208
233
  # app_id:: id of the application to authorize. This is required.
209
234
  # service_id:: id of the service (required if you have more than one service)
235
+ # usage:: predicted usage. It is optional. It is a hash where the keys are metrics
236
+ # and the values their predicted usage.
237
+ # Example: {'hits' => 1, 'my_metric' => 100}
210
238
  #
211
239
  # == Return
212
240
  #
@@ -247,14 +275,14 @@ module ThreeScale
247
275
 
248
276
  private
249
277
 
250
- OAUTH_PARAMS = [:app_id, :app_key, :service_id, :redirect_url]
251
- ALL_PARAMS = [:user_key, :app_id, :app_key, :service_id, :redirect_url]
278
+ OAUTH_PARAMS = [:app_id, :app_key, :service_id, :redirect_url, :usage]
279
+ ALL_PARAMS = [:user_key, :app_id, :app_key, :service_id, :redirect_url, :usage]
252
280
  REPORT_PARAMS = [:user_key, :app_id, :service_id, :timestamp]
253
281
 
254
282
  def options_to_params(options, allowed_keys)
255
283
  params = { :provider_key => provider_key }
256
284
 
257
- allowed_keys.each do |key|
285
+ (allowed_keys - [:usage]).each do |key|
258
286
  params[key] = options[key] if options.has_key?(key)
259
287
  end
260
288
 
@@ -262,7 +290,14 @@ module ThreeScale
262
290
  "#{key}=#{CGI.escape(value.to_s)}"
263
291
  end
264
292
 
265
- '?' + tuples.join('&')
293
+ res = '?' + tuples.join('&')
294
+
295
+ # Usage is a hash. The format is a bit different
296
+ if allowed_keys.include?(:usage) && options.has_key?(:usage)
297
+ res << "&#{usage_query_params(options[:usage])}"
298
+ end
299
+
300
+ res
266
301
  end
267
302
 
268
303
  def encode_transactions(transactions)
@@ -285,6 +320,10 @@ module ThreeScale
285
320
  result
286
321
  end
287
322
 
323
+ def usage_query_params(usage)
324
+ URI.encode_www_form(usage.map { |metric, value| ["[usage][#{metric}]", value ] })
325
+ end
326
+
288
327
  def append_value(result, index, names, value)
289
328
  result["transactions[#{index}][#{names.join('][')}]"] = value if value
290
329
  end
@@ -18,11 +18,12 @@ module ThreeScale
18
18
  @secure = !!options[:secure]
19
19
  @host = options.fetch(:host)
20
20
  @persistent = options[:persistent]
21
+ @port = options[:port] || (@secure ? 443 : 80)
21
22
 
22
23
  backend_class = @persistent ? self.class.persistent_backend : NetHttp or raise PersistenceNotAvailable
23
24
  backend_class.prepare
24
25
 
25
- @http = backend_class.new(@host)
26
+ @http = backend_class.new(@host, @port)
26
27
  @http.ssl! if @secure
27
28
  end
28
29
 
@@ -33,8 +34,9 @@ module ThreeScale
33
34
  def self.prepare
34
35
  end
35
36
 
36
- def initialize(host)
37
+ def initialize(host, port)
37
38
  @host = host
39
+ @port = port
38
40
  end
39
41
 
40
42
  def get_request(path)
@@ -65,7 +67,7 @@ module ThreeScale
65
67
  require 'net/http/persistent'
66
68
  end
67
69
 
68
- def initialize(host)
70
+ def initialize(host, port)
69
71
  super
70
72
  @http = ::Net::HTTP::Persistent.new
71
73
  @protocol = 'http'
@@ -87,7 +89,7 @@ module ThreeScale
87
89
  end
88
90
 
89
91
  def full_uri(path)
90
- URI.join "#{@protocol}://#{@host}", path
92
+ URI.join "#{@protocol}://#{@host}:#{@port}", path
91
93
  end
92
94
  end
93
95
 
@@ -95,13 +97,13 @@ module ThreeScale
95
97
  extend Forwardable
96
98
  def_delegators :@http, :use_ssl?, :active?
97
99
 
98
- def initialize(host)
100
+ def initialize(host, port)
99
101
  super
100
- @http = Net::HTTP.new(@host, 80)
102
+ @http = Net::HTTP.new(@host, port)
101
103
  end
102
104
 
103
105
  def ssl!
104
- @http = Net::HTTP.new(@host, 443)
106
+ @http = Net::HTTP.new(@host, @port)
105
107
  @http.use_ssl = true
106
108
  end
107
109
 
@@ -1,5 +1,5 @@
1
1
  module ThreeScale
2
2
  class Client
3
- VERSION = '2.7.0'
3
+ VERSION = '2.8.0'
4
4
  end
5
5
  end
data/test/client_test.rb CHANGED
@@ -212,6 +212,51 @@ class ThreeScale::ClientTest < MiniTest::Test
212
212
  end
213
213
  end
214
214
 
215
+ def test_authorize_with_usage_within_limits
216
+ url = "http://#{@host}/transactions/authorize.xml?provider_key=1234abcd"\
217
+ "&app_id=foo&%5Busage%5D%5Bmetric1%5D=1&%5Busage%5D%5Bmetric2%5D=2"
218
+
219
+ body = '<status>
220
+ <authorized>true</authorized>
221
+ <plan>Ultimate</plan>
222
+ </status>'
223
+
224
+ FakeWeb.register_uri(:get, url, :status => ['200', 'OK'], :body => body)
225
+
226
+ response = @client.authorize(:app_id => 'foo',
227
+ :usage => { 'metric1' => 1, 'metric2' => 2 })
228
+
229
+ assert response.success?
230
+ end
231
+
232
+ def test_authorize_with_usage_and_limits_exceeded
233
+ url = "http://#{@host}/transactions/authorize.xml?provider_key=1234abcd"\
234
+ "&app_id=foo&%5Busage%5D%5Bhits%5D=1"
235
+
236
+ body = '<status>
237
+ <authorized>false</authorized>
238
+ <reason>usage limits are exceeded</reason>
239
+
240
+ <plan>Ultimate</plan>
241
+
242
+ <usage_reports>
243
+ <usage_report metric="hits" period="day" exceeded="true">
244
+ <period_start>2010-04-26 00:00:00 +0000</period_start>
245
+ <period_end>2010-04-27 00:00:00 +0000</period_end>
246
+ <current_value>10</current_value>
247
+ <max_value>5</max_value>
248
+ </usage_report>
249
+ </usage_reports>
250
+ </status>'
251
+
252
+ FakeWeb.register_uri(:get, url, :status => ['409'], :body => body)
253
+
254
+ response = @client.authorize(:app_id => 'foo', :usage => { 'hits' => 1 })
255
+
256
+ assert !response.success?
257
+ assert_equal 'usage limits are exceeded', response.error_message
258
+ end
259
+
215
260
  def test_successful_oauth_authorize
216
261
  body = '<status>
217
262
  <authorized>true</authorized>
@@ -317,19 +362,74 @@ class ThreeScale::ClientTest < MiniTest::Test
317
362
  end
318
363
  end
319
364
 
365
+ def test_oauth_authorize_with_usage_within_limits
366
+ url = "http://#{@host}/transactions/oauth_authorize.xml"\
367
+ "?provider_key=1234abcd&app_id=foo&%5Busage%5D%5Bmetric1%5D=1"\
368
+ "&%5Busage%5D%5Bmetric2%5D=2"
369
+
370
+ body = '<status>
371
+ <authorized>true</authorized>
372
+ <plan>Ultimate</plan>
373
+ </status>'
374
+
375
+ FakeWeb.register_uri(:get, url, :status => ['200', 'OK'], :body => body)
376
+
377
+ response = @client.oauth_authorize(
378
+ :app_id => 'foo', :usage => { 'metric1' => 1, 'metric2' => 2 })
379
+
380
+ assert response.success?
381
+ end
382
+
383
+ def test_oauth_authorize_with_usage_and_limits_exceeded
384
+ url = "http://#{@host}/transactions/oauth_authorize.xml"\
385
+ "?provider_key=1234abcd&app_id=foo&%5Busage%5D%5Bhits%5D=1"
386
+
387
+ body = '<status>
388
+ <authorized>false</authorized>
389
+ <reason>usage limits are exceeded</reason>
390
+
391
+ <plan>Ultimate</plan>
392
+
393
+ <usage_reports>
394
+ <usage_report metric="hits" period="day" exceeded="true">
395
+ <period_start>2010-04-26 00:00:00 +0000</period_start>
396
+ <period_end>2010-04-27 00:00:00 +0000</period_end>
397
+ <current_value>10</current_value>
398
+ <max_value>5</max_value>
399
+ </usage_report>
400
+ </usage_reports>
401
+ </status>'
402
+
403
+ FakeWeb.register_uri(:get, url, :status => ['409'], :body => body)
404
+
405
+ response = @client.oauth_authorize(:app_id => 'foo',
406
+ :usage => { 'hits' => 1 })
407
+
408
+ assert !response.success?
409
+ assert_equal 'usage limits are exceeded', response.error_message
410
+ end
411
+
320
412
  def test_report_raises_an_exception_if_no_transactions_given
321
413
  assert_raises ArgumentError do
322
414
  @client.report
323
415
  end
416
+
417
+ [nil, []].each do |invalid_transactions|
418
+ assert_raises ArgumentError do
419
+ @client.report(transactions: invalid_transactions)
420
+ end
421
+ end
324
422
  end
325
423
 
326
424
  def test_successful_report
327
425
  FakeWeb.register_uri(:post, "http://#{@host}/transactions.xml",
328
426
  :status => ['200', 'OK'])
329
427
 
330
- response = @client.report({:app_id => 'foo',
331
- :timestamp => Time.local(2010, 4, 27, 15, 00),
332
- :usage => {'hits' => 1}})
428
+ transactions = [{ :app_id => 'foo',
429
+ :timestamp => Time.local(2010, 4, 27, 15, 00),
430
+ :usage => {'hits' => 1 } }]
431
+
432
+ response = @client.report(transactions: transactions)
333
433
 
334
434
  assert response.success?
335
435
  end
@@ -351,19 +451,20 @@ class ThreeScale::ClientTest < MiniTest::Test
351
451
  FakeWeb.register_uri(:post, "http://#{@host}/transactions.xml",
352
452
  :status => ['200', 'OK'])
353
453
 
354
- @client.report({:app_id => 'foo',
355
- :usage => {'hits' => 1},
356
- :timestamp => '2010-04-27 15:42:17 0200',
357
- :log => {
358
- 'request' => 'foo',
359
- 'response' => 'bar',
360
- 'code' => 200,
361
- }
362
- },
363
-
364
- {:app_id => 'bar',
365
- :usage => {'hits' => 1},
366
- :timestamp => Time.local(2010, 4, 27, 15, 00)})
454
+ transactions = [{ :app_id => 'foo',
455
+ :usage => { 'hits' => 1 },
456
+ :timestamp => '2010-04-27 15:42:17 0200',
457
+ :log => {
458
+ 'request' => 'foo',
459
+ 'response' => 'bar',
460
+ 'code' => 200
461
+ }
462
+ },
463
+ { :app_id => 'bar',
464
+ :usage => { 'hits' => 1 },
465
+ :timestamp => Time.local(2010, 4, 27, 15, 00) }]
466
+
467
+ @client.report(transactions: transactions)
367
468
 
368
469
  request = FakeWeb.last_request
369
470
 
@@ -381,12 +482,74 @@ class ThreeScale::ClientTest < MiniTest::Test
381
482
  FakeWeb.register_uri(:post, "http://#{@host}/transactions.xml",
382
483
  :status => ['200', 'OK'])
383
484
 
384
- @client.report({:user_key => 'foo',
385
- :usage => {'hits' => 1},
386
- :timestamp => '2016-07-18 15:42:17 0200'})
485
+ transactions = [{ :user_key => 'foo',
486
+ :usage => { 'hits' => 1 },
487
+ :timestamp => '2016-07-18 15:42:17 0200' }]
488
+
489
+ @client.report(transactions: transactions)
490
+
491
+ request = FakeWeb.last_request
492
+
493
+ assert_equal URI.encode_www_form(payload), request.body
494
+ end
495
+
496
+ def test_report_with_service_id
497
+ FakeWeb.register_uri(:post, "http://#{@host}/transactions.xml",
498
+ :status => ['200', 'OK'])
499
+
500
+ transactions = [{ :app_id => 'an_app_id',
501
+ :usage => { 'hits' => 1 },
502
+ :timestamp => '2016-07-18 15:42:17 0200' }]
503
+
504
+ @client.report(transactions: transactions, service_id: 'a_service_id')
505
+
506
+ request = FakeWeb.last_request
507
+
508
+ payload = {
509
+ 'transactions[0][app_id]' => 'an_app_id',
510
+ 'transactions[0][timestamp]' => '2016-07-18 15:42:17 0200',
511
+ 'transactions[0][usage][hits]' => '1',
512
+ 'provider_key' => '1234abcd',
513
+ 'service_id' => 'a_service_id'
514
+ }
515
+
516
+ assert_equal URI.encode_www_form(payload), request.body
517
+ end
518
+
519
+ # We changed the signature of the report method but we keep the compatibility
520
+ # with the old one: def report(*transactions).This tests only checks that
521
+ # backwards compatibility.
522
+ def test_report_compatibility_with_old_report_format
523
+ FakeWeb.register_uri(:post, "http://#{@host}/transactions.xml",
524
+ :status => ['200', 'OK'])
525
+
526
+ transactions = [{ :app_id => 'app_id_1',
527
+ :usage => { 'hits' => 1 },
528
+ :timestamp => '2016-07-18 15:42:17 0200' },
529
+ { :app_id => 'app_id_2',
530
+ :usage => { 'hits' => 2 },
531
+ :timestamp => '2016-07-19 15:42:17 0200' },
532
+ { :app_id => 'app_id_3',
533
+ :usage => { 'hits' => 3 },
534
+ :timestamp => '2016-07-20 15:42:17 0200' }]
535
+
536
+ @client.report(*transactions)
387
537
 
388
538
  request = FakeWeb.last_request
389
539
 
540
+ payload = {
541
+ 'transactions[0][app_id]' => 'app_id_1',
542
+ 'transactions[0][timestamp]' => '2016-07-18 15:42:17 0200',
543
+ 'transactions[0][usage][hits]' => '1',
544
+ 'transactions[1][app_id]' => 'app_id_2',
545
+ 'transactions[1][timestamp]' => '2016-07-19 15:42:17 0200',
546
+ 'transactions[1][usage][hits]' => '2',
547
+ 'transactions[2][app_id]' => 'app_id_3',
548
+ 'transactions[2][timestamp]' => '2016-07-20 15:42:17 0200',
549
+ 'transactions[2][usage][hits]' => '3',
550
+ 'provider_key' => '1234abcd'
551
+ }
552
+
390
553
  assert_equal URI.encode_www_form(payload), request.body
391
554
  end
392
555
 
@@ -398,7 +561,8 @@ class ThreeScale::ClientTest < MiniTest::Test
398
561
  :body => error_body)
399
562
 
400
563
  client = ThreeScale::Client.new(:provider_key => 'foo')
401
- response = client.report({:app_id => 'abc', :usage => {'hits' => 1}})
564
+ transactions = [{ :app_id => 'abc', :usage => { 'hits' => 1 } }]
565
+ response = client.report(transactions: transactions)
402
566
 
403
567
  assert !response.success?
404
568
  assert_equal 'provider_key_invalid', response.error_code
@@ -410,8 +574,10 @@ class ThreeScale::ClientTest < MiniTest::Test
410
574
  :status => ['500', 'Internal Server Error'],
411
575
  :body => 'OMG! WTF!')
412
576
 
577
+ transactions = [{ :app_id => 'foo', :usage => { 'hits' => 1 } }]
578
+
413
579
  assert_raises ThreeScale::ServerError do
414
- @client.report({:app_id => 'foo', :usage => {'hits' => 1}})
580
+ @client.report(transactions: transactions)
415
581
  end
416
582
  end
417
583
 
@@ -439,7 +605,8 @@ class ThreeScale::ClientTest < MiniTest::Test
439
605
  :status => ['200', 'OK'],
440
606
  :body => success_body)
441
607
  client = ThreeScale::Client.new(:provider_key => 'foo')
442
- response = client.report({:app_id => 'abc', :usage => {'hits' => 1}})
608
+ transactions = [{ :app_id => 'abc', :usage => { 'hits' => 1 } }]
609
+ client.report(transactions: transactions)
443
610
 
444
611
  request = FakeWeb.last_request
445
612
  assert_equal "plugin-ruby-v#{version}", request["X-3scale-User-Agent"]
data/test/remote_test.rb CHANGED
@@ -87,7 +87,7 @@ if ENV['TEST_3SCALE_PROVIDER_KEY'] &&
87
87
  :log => {:request => "a/a", :response => "b/b", :code => 200 }}
88
88
  end
89
89
 
90
- response = @client.report(*transactions)
90
+ response = @client.report(transactions: transactions)
91
91
  assert response.success?
92
92
  end
93
93
 
@@ -97,7 +97,7 @@ if ENV['TEST_3SCALE_PROVIDER_KEY'] &&
97
97
  end
98
98
 
99
99
  client = ThreeScale::Client.new(:provider_key => 'invalid-key')
100
- response = client.report(*transactions)
100
+ response = client.report(transactions: transactions)
101
101
  assert !response.success?
102
102
  assert_equal 'provider_key_invalid', response.error_code
103
103
  assert_equal 'provider key "invalid-key" is invalid', response.error_message
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 3scale_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Cichra
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2016-08-26 00:00:00.000000000 Z
15
+ date: 2016-09-06 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
@@ -126,6 +126,20 @@ dependencies:
126
126
  - - ">="
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
+ - !ruby/object:Gem::Dependency
130
+ name: appraisal
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
129
143
  - !ruby/object:Gem::Dependency
130
144
  name: nokogiri
131
145
  requirement: !ruby/object:Gem::Requirement
@@ -152,12 +166,14 @@ files:
152
166
  - ".gitignore"
153
167
  - ".travis.yml"
154
168
  - 3scale_client.gemspec
169
+ - Appraisals
155
170
  - CHANGELOG.md
156
171
  - Gemfile
157
172
  - LICENCE
158
173
  - README.md
159
174
  - Rakefile
160
175
  - VERSION
176
+ - gemfiles/rack_1.gemfile
161
177
  - lib/3scale/authorize_response.rb
162
178
  - lib/3scale/client.rb
163
179
  - lib/3scale/client/http_client.rb
@@ -182,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
198
  requirements:
183
199
  - - ">="
184
200
  - !ruby/object:Gem::Version
185
- version: '0'
201
+ version: '2.0'
186
202
  required_rubygems_version: !ruby/object:Gem::Requirement
187
203
  requirements:
188
204
  - - ">="
@@ -190,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
206
  version: '0'
191
207
  requirements: []
192
208
  rubyforge_project:
193
- rubygems_version: 2.6.4
209
+ rubygems_version: 2.6.6
194
210
  signing_key:
195
211
  specification_version: 4
196
212
  summary: Client for 3scale Web Service Management System API