koala 3.1.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3209d60dbf8ab51fac40f7b990f221076bb453329641194dce55b800d0611856
4
- data.tar.gz: 9dfb75f13c1b1e187c325453793b6dfcdc085a0f42e119d40df7a30d7b492250
3
+ metadata.gz: f3709b2644f9f0259e68e181d629754ffe3ba0213322cfb3bad0d369ad04543c
4
+ data.tar.gz: 7c3e3760d2ee7958b199713c7308f291552ee80a7badddc9ea9434a71cb024a9
5
5
  SHA512:
6
- metadata.gz: 2aa7c4c61594d111e5654788712a56eea9005e4e3f6ce133536de6d2089f6014a6a0f5a059012b3bccf2204862b6c28212b517a4a264ea4b2cc272530d11cb4f
7
- data.tar.gz: 318d505d832d0d2e70cd9df39040254c1eea64bdf3c743cf29c6311e8fe2cd68159f3237a27a6a066136b5d3306029771fae2935fc4c768860a2c12525f29137
6
+ metadata.gz: a22e1b9de96408d3273816150d5e0d55768f72b8b48a93ea276b7d2dc5d35f45de38cb8aad847345faf9c6997d7d0f19d21f177882cfb024e472e8681c9bbd2d
7
+ data.tar.gz: 5d66a1c10d8bd3d8153eb8faa02ee7ae901aae7321141d12f39abaeb33b6193cea2e3c7215b813942b714965d6048abda867f1d269de39dbdfc0bc137f3a0dc6
@@ -10,7 +10,7 @@ jobs:
10
10
  strategy:
11
11
  fail-fast: false
12
12
  matrix:
13
- ruby: [2.5, 2.6, 2.7, "3.0", 3.1, head]
13
+ ruby: [2.7, "3.0", 3.1, head]
14
14
 
15
15
  steps:
16
16
  - name: Checkout repository
data/Gemfile CHANGED
@@ -10,10 +10,11 @@ group :development, :test do
10
10
  gem "psych", '< 4.0.0' # safe_load signature not compatible with older rubies
11
11
  gem "rake"
12
12
  gem "typhoeus" unless defined? JRUBY_VERSION
13
+ gem 'faraday-typhoeus' unless defined? JRUBY_VERSION
13
14
  end
14
15
 
15
16
  group :test do
16
- gem "rspec", '~> 3.4'
17
+ gem "rspec", "~> 3.0", "< 3.10" # resrict rspec version until https://github.com/rspec/rspec-support/pull/537 gets merged
17
18
  gem "vcr", github: 'vcr/vcr', ref: '8ced6c96e01737a418cd270e0382a8c2c6d85f7f' # needs https://github.com/vcr/vcr/pull/907 for ruby 3.1
18
19
  gem "webmock"
19
20
  gem "simplecov"
data/changelog.md CHANGED
@@ -15,7 +15,35 @@ Testing improvements:
15
15
 
16
16
  Others:
17
17
 
18
- v3.1.0 (2022-18-01)
18
+ v3.3.0 (2022-09-27)
19
+ ======
20
+
21
+ Updated features:
22
+
23
+ * Removed restriction on faraday < 2 ([#666](https://github.com/arsduo/koala/pull/666))
24
+
25
+ Internal improvements:
26
+
27
+ * Remove multipart hack and use default faraday multipart middleware ([#664](https://github.com/arsduo/koala/pull/664))
28
+
29
+ Testing improvements:
30
+
31
+ * Fix tests with ruby-head ([#674](https://github.com/arsduo/koala/pull/674))
32
+ * Keep supported rubies (non EOL) for CI ([#675](https://github.com/arsduo/koala/pull/675))
33
+
34
+ v3.2.0 (2022-05-27)
35
+ ======
36
+
37
+ New features:
38
+
39
+ * Exposes limiting headers(`x-business-use-case-usage, x-ad-account-usage, x-app-usage`) to APIError ([#668](https://github.com/arsduo/koala/pull/668))
40
+ * Add `rate_limit_hook` configuration to get rate limiting headers (`x-business-use-case-usage, x-ad-account-usage, x-app-usage`) ([#670](https://github.com/arsduo/koala/pull/670))
41
+
42
+ Testing improvements:
43
+
44
+ * Fix builds for ruby 3.x
45
+
46
+ v3.1.0 (2022-01-18)
19
47
  ======
20
48
 
21
49
  New features:
data/koala.gemspec CHANGED
@@ -23,7 +23,8 @@ Gem::Specification.new do |gem|
23
23
 
24
24
  gem.required_ruby_version = '>= 2.1'
25
25
 
26
- gem.add_runtime_dependency("faraday", "< 2")
26
+ gem.add_runtime_dependency("faraday")
27
+ gem.add_runtime_dependency("faraday-multipart")
27
28
  gem.add_runtime_dependency("addressable")
28
29
  gem.add_runtime_dependency("json", ">= 1.8")
29
30
  gem.add_runtime_dependency("rexml")
@@ -17,7 +17,7 @@ module Koala
17
17
 
18
18
  # Facebook can return debug information in the response headers -- see
19
19
  # https://developers.facebook.com/docs/graph-api/using-graph-api#bugdebug
20
- DEBUG_HEADERS = ["x-fb-debug", "x-fb-rev", "x-fb-trace-id"]
20
+ DEBUG_HEADERS = %w[x-fb-debug x-fb-rev x-fb-trace-id x-business-use-case-usage x-ad-account-usage x-app-usage]
21
21
 
22
22
  def error_if_appropriate
23
23
  if http_status >= 400
data/lib/koala/api.rb CHANGED
@@ -13,14 +13,16 @@ module Koala
13
13
  # signed by default, unless you pass appsecret_proof:
14
14
  # false as an option to the API call. (See
15
15
  # https://developers.facebook.com/docs/graph-api/securing-requests/)
16
+ # @param [Block] rate_limit_hook block called with limits received in facebook response headers
16
17
  # @note If no access token is provided, you can only access some public information.
17
18
  # @return [Koala::Facebook::API] the API client
18
- def initialize(access_token = Koala.config.access_token, app_secret = Koala.config.app_secret)
19
+ def initialize(access_token = Koala.config.access_token, app_secret = Koala.config.app_secret, rate_limit_hook = Koala.config.rate_limit_hook)
19
20
  @access_token = access_token
20
21
  @app_secret = app_secret
22
+ @rate_limit_hook = rate_limit_hook
21
23
  end
22
24
 
23
- attr_reader :access_token, :app_secret
25
+ attr_reader :access_token, :app_secret, :rate_limit_hook
24
26
 
25
27
  include GraphAPIMethods
26
28
 
@@ -58,6 +60,18 @@ module Koala
58
60
  API::GraphCollection.evaluate(response, self)
59
61
  end
60
62
 
63
+ if rate_limit_hook
64
+ limits = %w(x-business-use-case-usage x-ad-account-usage x-app-usage).each_with_object({}) do |key, hash|
65
+ value = response.headers.fetch(key, nil)
66
+ next unless value
67
+ hash[key] = JSON.parse(response.headers[key])
68
+ rescue JSON::ParserError => e
69
+ Koala::Utils.logger.error("#{e.class}: #{e.message} while parsing #{key} = #{value}")
70
+ end
71
+
72
+ rate_limit_hook.call(limits) if limits.keys.any?
73
+ end
74
+
61
75
  # now process as appropriate for the given call (get picture header, etc.)
62
76
  post_processing ? post_processing.call(desired_data) : desired_data
63
77
  end
@@ -31,6 +31,9 @@ class Koala::Configuration
31
31
  # Whether or not to mask tokens
32
32
  attr_accessor :mask_tokens
33
33
 
34
+ # Called with the info for the rate limits in the response header
35
+ attr_accessor :rate_limit_hook
36
+
34
37
  # Certain Facebook services (beta, video) require you to access different
35
38
  # servers. If you're using your own servers, for instance, for a proxy,
36
39
  # you can change both the matcher (what value to change when updating the URL) and the
data/lib/koala/errors.rb CHANGED
@@ -23,7 +23,10 @@ module Koala
23
23
  :fb_error_user_title,
24
24
  :fb_error_trace_id,
25
25
  :fb_error_debug,
26
- :fb_error_rev
26
+ :fb_error_rev,
27
+ :fb_buc_usage,
28
+ :fb_ada_usage,
29
+ :fb_app_usage
27
30
 
28
31
  # Create a new API Error
29
32
  #
@@ -66,6 +69,9 @@ module Koala
66
69
  self.fb_error_trace_id = error_info["x-fb-trace-id"]
67
70
  self.fb_error_debug = error_info["x-fb-debug"]
68
71
  self.fb_error_rev = error_info["x-fb-rev"]
72
+ self.fb_buc_usage = json_parse_for(error_info, "x-business-use-case-usage")
73
+ self.fb_ada_usage = json_parse_for(error_info, "x-ad-account-usage")
74
+ self.fb_app_usage = json_parse_for(error_info, "x-app-usage")
69
75
 
70
76
  error_array = []
71
77
  %w(type code error_subcode message error_user_title error_user_msg x-fb-trace-id).each do |key|
@@ -82,6 +88,20 @@ module Koala
82
88
 
83
89
  super(message)
84
90
  end
91
+
92
+ private
93
+
94
+ # refs: https://developers.facebook.com/docs/graph-api/overview/rate-limiting/#headers
95
+ # NOTE: The header will contain a JSON-formatted string that describes current application rate limit usage.
96
+ def json_parse_for(error_info, key)
97
+ string = error_info[key]
98
+ return if string.nil?
99
+
100
+ JSON.parse(string)
101
+ rescue JSON::ParserError => e
102
+ Koala::Utils.logger.error("#{e.class}: #{e.message} while parsing #{key} = #{string}")
103
+ nil
104
+ end
85
105
  end
86
106
 
87
107
  # Facebook returned an invalid response body
@@ -1,4 +1,3 @@
1
- require "net/http/post/multipart"
2
1
  require "tempfile"
3
2
 
4
3
  module Koala
@@ -1,5 +1,5 @@
1
1
  require 'faraday'
2
- require 'koala/http_service/multipart_request'
2
+ require 'faraday/multipart' unless defined? Faraday::FilePart # hack for faraday < 1.9 to avoid warnings
3
3
  require 'koala/http_service/uploadable_io'
4
4
  require 'koala/http_service/response'
5
5
  require 'koala/http_service/request'
@@ -19,7 +19,7 @@ module Koala
19
19
  # We encode requests in a Facebook-compatible multipart request,
20
20
  # and use whichever adapter has been configured for this application.
21
21
  DEFAULT_MIDDLEWARE = Proc.new do |builder|
22
- builder.use Koala::HTTPService::MultipartRequest
22
+ builder.request :multipart
23
23
  builder.request :url_encoded
24
24
  builder.adapter Faraday.default_adapter
25
25
  end
data/lib/koala/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Koala
2
- VERSION = "3.1.0"
2
+ VERSION = "3.3.0"
3
3
  end
data/readme.md CHANGED
@@ -177,6 +177,37 @@ Koala::Facebook::RealtimeUpdates.meet_challenge(params, your_verify_token)
177
177
  ```
178
178
  For more information about meet_challenge and the RealtimeUpdates class, check out the Real-Time Updates page on the wiki.
179
179
 
180
+ Rate limits
181
+ -----------
182
+
183
+ We support Facebook rate limit informations as defined here: [https://developers.facebook.com/docs/graph-api/overview/rate-limiting/](https://developers.facebook.com/docs/graph-api/overview/rate-limiting/)
184
+
185
+ The information is available either via the `Facebook::APIError`:
186
+
187
+ ```ruby
188
+ error.fb_buc_usage
189
+ error.fb_ada_usage
190
+ error.fb_app_usage
191
+ ```
192
+
193
+ Or with the rate_limit_hook:
194
+
195
+ ```ruby
196
+ # App level configuration
197
+
198
+ Koala.configure do |config|
199
+ config.rate_limit_hook = ->(limits) {
200
+ limits["x-app-usage"] # {"call_count"=>0, "total_cputime"=>0, "total_time"=>0}
201
+ limits["x-ad-account-usage"] # {"acc_id_util_pct"=>9.67}
202
+ limits["x-business-use-case-usage"] # {"123456789012345"=>[{"type"=>"messenger", "call_count"=>1, "total_cputime"=>1, "total_time"=>1, "estimated_time_to_regain_access"=>0}]}
203
+ }
204
+ end
205
+
206
+ # Per API configuration
207
+
208
+ Koala::Facebook::API.new('', '', ->(limits) {})
209
+ ```
210
+
180
211
  Test Users
181
212
  ----------
182
213
 
@@ -282,4 +282,81 @@ describe "Koala::Facebook::API" do
282
282
  expect(@service.graph_call('anything')).to be_falsey
283
283
  end
284
284
  end
285
+
286
+ describe "Rate limit hook" do
287
+ it "is called when x-business-use-case-usage header is present" do
288
+ api = Koala::Facebook::API.new('', '', ->(limits) {
289
+ expect(limits["x-business-use-case-usage"]).to eq({"123456789012345"=>[{"type"=>"messenger", "call_count"=>1, "total_cputime"=>1, "total_time"=>1, "estimated_time_to_regain_access"=>0}]})
290
+ })
291
+
292
+ result = {"a" => 2}
293
+ response = Koala::HTTPService::Response.new(200, result.to_json, { "x-business-use-case-usage" => "{\"123456789012345\":[{\"type\":\"messenger\",\"call_count\":1,\"total_cputime\":1,\"total_time\":1,\"estimated_time_to_regain_access\":0}]}" })
294
+ allow(Koala).to receive(:make_request).and_return(response)
295
+
296
+ api.graph_call('anything')
297
+ end
298
+
299
+ it "is called when x-ad-account-usage header is present" do
300
+ api = Koala::Facebook::API.new('', '', ->(limits) {
301
+ expect(limits["x-ad-account-usage"]).to eq({"acc_id_util_pct"=>9.67})
302
+ })
303
+
304
+ result = {"a" => 2}
305
+ response = Koala::HTTPService::Response.new(200, result.to_json, { "x-ad-account-usage" => "{\"acc_id_util_pct\":9.67}" })
306
+ allow(Koala).to receive(:make_request).and_return(response)
307
+
308
+ api.graph_call('anything')
309
+ end
310
+
311
+ it "is called when x-app-usage header is present" do
312
+ api = Koala::Facebook::API.new('', '', ->(limits) {
313
+ expect(limits["x-app-usage"]).to eq({"call_count"=>0, "total_cputime"=>0, "total_time"=>0})
314
+ })
315
+
316
+ result = {"a" => 2}
317
+ response = Koala::HTTPService::Response.new(200, result.to_json, { "x-app-usage" => "{\"call_count\":0,\"total_cputime\":0,\"total_time\":0}" })
318
+ allow(Koala).to receive(:make_request).and_return(response)
319
+
320
+ api.graph_call('anything')
321
+ end
322
+
323
+ it "isn't called if none of the rate limit header is present" do
324
+ rate_limit_hook_called = false
325
+
326
+ api = Koala::Facebook::API.new('', '', ->(limits) {
327
+ rate_limit_hook_called = true
328
+ })
329
+
330
+ result = {"a" => 2}
331
+ response = Koala::HTTPService::Response.new(200, result.to_json, {})
332
+ allow(Koala).to receive(:make_request).and_return(response)
333
+
334
+ api.graph_call('anything')
335
+
336
+ expect(rate_limit_hook_called).to be(false)
337
+ end
338
+
339
+ it "isn't called if no rate limit hook is defined" do
340
+ api = Koala::Facebook::API.new('', '', ->(limits) {
341
+ #noop
342
+ })
343
+
344
+ result = {"a" => 2}
345
+ response = Koala::HTTPService::Response.new(200, result.to_json, { "x-ad-account-usage" => "{\"acc_id_util_pct\"9.67}"})
346
+ allow(Koala).to receive(:make_request).and_return(response)
347
+
348
+ expect(Koala::Utils.logger).to receive(:error).with(/JSON::ParserError:.*unexpected token at '{"acc_id_util_pct"9.67}' while parsing x-ad-account-usage = {"acc_id_util_pct"9.67}/)
349
+ api.graph_call('anything')
350
+ end
351
+
352
+ it "logs an error if the rate limit header can't be properly parsed" do
353
+ api = Koala::Facebook::API.new('', '', nil)
354
+
355
+ result = {"a" => 2}
356
+ response = Koala::HTTPService::Response.new(200, result.to_json, {})
357
+ allow(Koala).to receive(:make_request).and_return(response)
358
+
359
+ api.graph_call('anything')
360
+ end
361
+ end
285
362
  end
@@ -1,5 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
+ BUC_USAGE_JSON = "{\"123456789012345\":[{\"type\":\"messenger\",\"call_count\":1,\"total_cputime\":1,\"total_time\":1,\"estimated_time_to_regain_access\":0}]}"
4
+ ADA_USAGE_JSON = "{\"acc_id_util_pct\":9.67}"
5
+ APP_USAGE_JSON = "{\"call_count\":0,\"total_cputime\":0,\"total_time\":0}"
6
+
3
7
  describe Koala::Facebook::APIError do
4
8
  it "is a Koala::KoalaError" do
5
9
  expect(Koala::Facebook::APIError.new(nil, nil)).to be_a(Koala::KoalaError)
@@ -32,7 +36,10 @@ describe Koala::Facebook::APIError do
32
36
  'error_user_title' => 'error user title',
33
37
  'x-fb-trace-id' => 'fb trace id',
34
38
  'x-fb-debug' => 'fb debug token',
35
- 'x-fb-rev' => 'fb revision'
39
+ 'x-fb-rev' => 'fb revision',
40
+ 'x-business-use-case-usage' => BUC_USAGE_JSON,
41
+ 'x-ad-account-usage' => ADA_USAGE_JSON,
42
+ 'x-app-usage' => APP_USAGE_JSON
36
43
  }
37
44
  Koala::Facebook::APIError.new(400, '', error_info)
38
45
  }
@@ -46,7 +53,10 @@ describe Koala::Facebook::APIError do
46
53
  :fb_error_user_title => 'error user title',
47
54
  :fb_error_trace_id => 'fb trace id',
48
55
  :fb_error_debug => 'fb debug token',
49
- :fb_error_rev => 'fb revision'
56
+ :fb_error_rev => 'fb revision',
57
+ :fb_buc_usage => JSON.parse(BUC_USAGE_JSON),
58
+ :fb_ada_usage => JSON.parse(ADA_USAGE_JSON),
59
+ :fb_app_usage => JSON.parse(APP_USAGE_JSON)
50
60
  }.each_pair do |accessor, value|
51
61
  it "sets #{accessor} to #{value}" do
52
62
  expect(error.send(accessor)).to eq(value)
@@ -76,7 +86,10 @@ describe Koala::Facebook::APIError do
76
86
  :fb_error_code => 1,
77
87
  :fb_error_subcode => 'subcode',
78
88
  :fb_error_user_msg => 'error user message',
79
- :fb_error_user_title => 'error user title'
89
+ :fb_error_user_title => 'error user title',
90
+ :fb_buc_usage => nil,
91
+ :fb_ada_usage => nil,
92
+ :fb_app_usage => nil
80
93
  }.each_pair do |accessor, value|
81
94
  expect(error.send(accessor)).to eq(value)
82
95
  end
@@ -593,7 +593,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
593
593
  hash_including(@other_access_token_args.dup),
594
594
  anything,
595
595
  anything
596
- ).and_return(Koala::HTTPService::Response.new(200, "", ""))
596
+ ).and_return(Koala::HTTPService::Response.new(200, "", {}))
597
597
 
598
598
  # Page the collection
599
599
  app_event_types.next_page
@@ -11,7 +11,10 @@ module Koala
11
11
  expect(GraphErrorChecker::DEBUG_HEADERS).to match_array([
12
12
  "x-fb-rev",
13
13
  "x-fb-debug",
14
- "x-fb-trace-id"
14
+ "x-fb-trace-id",
15
+ "x-business-use-case-usage",
16
+ "x-ad-account-usage",
17
+ "x-app-usage"
15
18
  ])
16
19
  end
17
20
 
@@ -84,10 +87,25 @@ module Koala
84
87
  "x-fb-debug" => double("fb debug"),
85
88
  "x-fb-rev" => double("fb rev"),
86
89
  "x-fb-trace-id" => double("fb trace id"),
90
+ "x-business-use-case-usage" => { 'a' => 1, 'b' => 2 }.to_json,
91
+ "x-ad-account-usage" => { 'c' => 3, 'd' => 4 }.to_json,
92
+ "x-app-usage" => { 'e' => 5, 'f' => 6 }.to_json
87
93
  )
88
94
  expect(error.fb_error_trace_id).to eq(headers["x-fb-trace-id"])
89
95
  expect(error.fb_error_debug).to eq(headers["x-fb-debug"])
90
96
  expect(error.fb_error_rev).to eq(headers["x-fb-rev"])
97
+ expect(error.fb_buc_usage).to eq({ 'a' => 1, 'b' => 2 })
98
+ expect(error.fb_ada_usage).to eq({ 'c' => 3, 'd' => 4 })
99
+ expect(error.fb_app_usage).to eq({ 'e' => 5, 'f' => 6 })
100
+ end
101
+
102
+ it "logs if one of the FB debug headers can't be parsed" do
103
+ headers.merge!(
104
+ "x-app-usage" => '{invalid:json}'
105
+ )
106
+
107
+ expect(Koala::Utils.logger).to receive(:error).with(/JSON::ParserError:.*unexpected token at '{invalid:json}' while parsing x-app-usage = {invalid:json}/)
108
+ expect(error.fb_app_usage).to eq(nil)
91
109
  end
92
110
 
93
111
  context "it returns an AuthenticationError" do
@@ -39,8 +39,7 @@ describe Koala::HTTPService do
39
39
 
40
40
  it "adds the right default middleware" do
41
41
  Koala::HTTPService::DEFAULT_MIDDLEWARE.call(builder)
42
- expect(builder.requests).to eq([:url_encoded])
43
- expect(builder.uses).to eq([Koala::HTTPService::MultipartRequest])
42
+ expect(builder.requests).to eq([:multipart, :url_encoded])
44
43
  expect(builder.adapters).to eq([Faraday.default_adapter])
45
44
  end
46
45
  end
@@ -194,18 +193,16 @@ describe Koala::HTTPService do
194
193
 
195
194
  it "uses the default builder block if HTTPService.faraday_middleware block is not defined" do
196
195
  block = Proc.new { |builder|
197
- builder.use Koala::HTTPService::MultipartRequest
196
+ builder.request :multipart
198
197
  builder.request :url_encoded
199
- builder.use Koala::HTTPService::MultipartRequest
200
198
  }
201
199
  stub_const("Koala::HTTPService::DEFAULT_MIDDLEWARE", block)
202
200
  allow(Koala::HTTPService).to receive(:faraday_middleware).and_return(nil)
203
201
 
204
202
  expect_any_instance_of(Faraday::Connection).to receive(:get) do |instance|
205
203
  expect(instance.builder.handlers).to eq([
206
- Koala::HTTPService::MultipartRequest,
204
+ Faraday::Multipart::Middleware,
207
205
  Faraday::Request::UrlEncoded,
208
- Koala::HTTPService::MultipartRequest
209
206
  ])
210
207
  mock_http_response
211
208
  end
@@ -215,17 +212,15 @@ describe Koala::HTTPService do
215
212
 
216
213
  it "uses the defined HTTPService.faraday_middleware block if defined" do
217
214
  block = Proc.new { |builder|
218
- builder.use Koala::HTTPService::MultipartRequest
215
+ builder.request :multipart
219
216
  builder.request :url_encoded
220
- builder.use Koala::HTTPService::MultipartRequest
221
217
  }
222
218
  expect(Koala::HTTPService).to receive(:faraday_middleware).and_return(block)
223
219
 
224
220
  expect_any_instance_of(Faraday::Connection).to receive(:get) do |instance|
225
221
  expect(instance.builder.handlers).to eq([
226
- Koala::HTTPService::MultipartRequest,
222
+ Faraday::Multipart::Middleware,
227
223
  Faraday::Request::UrlEncoded,
228
- Koala::HTTPService::MultipartRequest
229
224
  ])
230
225
  mock_http_response
231
226
  end
@@ -238,11 +238,11 @@ module KoalaTest
238
238
  # JRuby doesn't support typhoeus on Travis
239
239
  unless defined? JRUBY_VERSION
240
240
  require adapter
241
- require 'typhoeus/adapters/faraday' if adapter.to_s == "typhoeus"
241
+ require "faraday/#{adapter}"
242
242
  Faraday.default_adapter = adapter.to_sym
243
243
  end
244
- rescue ParserError
245
- puts "Unable to load adapter #{adapter}, using Net::HTTP."
244
+ rescue => e
245
+ puts "Unable to load adapter #{adapter}, using Net::HTTP. #{e.class} #{e.message}"
246
246
  ensure
247
247
  @adapter_activation_attempted = true
248
248
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: koala
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Koppel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-18 00:00:00.000000000 Z
11
+ date: 2022-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "<"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '2'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "<"
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday-multipart
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
25
32
  - !ruby/object:Gem::Version
26
- version: '2'
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: addressable
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -101,7 +115,6 @@ files:
101
115
  - lib/koala/configuration.rb
102
116
  - lib/koala/errors.rb
103
117
  - lib/koala/http_service.rb
104
- - lib/koala/http_service/multipart_request.rb
105
118
  - lib/koala/http_service/request.rb
106
119
  - lib/koala/http_service/response.rb
107
120
  - lib/koala/http_service/uploadable_io.rb
@@ -123,7 +136,6 @@ files:
123
136
  - spec/cases/http_service_spec.rb
124
137
  - spec/cases/koala_spec.rb
125
138
  - spec/cases/koala_test_spec.rb
126
- - spec/cases/multipart_request_spec.rb
127
139
  - spec/cases/oauth_spec.rb
128
140
  - spec/cases/realtime_updates_spec.rb
129
141
  - spec/cases/test_users_spec.rb
@@ -165,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
177
  - !ruby/object:Gem::Version
166
178
  version: '0'
167
179
  requirements: []
168
- rubygems_version: 3.0.0
180
+ rubygems_version: 3.4.0.dev
169
181
  signing_key:
170
182
  specification_version: 4
171
183
  summary: A lightweight, flexible library for Facebook with support for the Graph API,
@@ -1,37 +0,0 @@
1
- require 'faraday'
2
-
3
- module Koala
4
- module HTTPService
5
- class MultipartRequest < Faraday::Request::Multipart
6
- # Facebook expects nested parameters to be passed in a certain way
7
- # Based on our testing (https://github.com/arsduo/koala/issues/125),
8
- # Faraday needs two changes to make that work:
9
- # 1) [] need to be escaped (e.g. params[foo]=bar ==> params%5Bfoo%5D=bar)
10
- # 2) such messages need to be multipart-encoded
11
-
12
- self.mime_type = 'multipart/form-data'.freeze
13
-
14
- def process_request?(env)
15
- # if the request values contain any hashes or arrays, multipart it
16
- super || !!(env[:body].respond_to?(:values) && env[:body].values.find {|v| v.is_a?(Hash) || v.is_a?(Array)})
17
- end
18
-
19
-
20
- def process_params(params, prefix = nil, pieces = nil, &block)
21
- params.inject(pieces || []) do |all, (key, value)|
22
- key = "#{prefix}%5B#{key}%5D" if prefix
23
-
24
- case value
25
- when Array
26
- values = value.inject([]) { |a,v| a << [nil, v] }
27
- process_params(values, key, all, &block)
28
- when Hash
29
- process_params(value, key, all, &block)
30
- else
31
- all << block.call(key, value)
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,65 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Koala::HTTPService::MultipartRequest do
4
- it "is a subclass of Faraday::Request::Multipart" do
5
- expect(Koala::HTTPService::MultipartRequest.superclass).to eq(Faraday::Request::Multipart)
6
- end
7
-
8
- it "defines mime_type as multipart/form-data" do
9
- expect(Koala::HTTPService::MultipartRequest.mime_type).to eq('multipart/form-data')
10
- end
11
-
12
- describe "#process_request?" do
13
- before :each do
14
- @env = Faraday::Env.new
15
- @multipart = Koala::HTTPService::MultipartRequest.new
16
- allow(@multipart).to receive(:request_type).and_return("")
17
- end
18
-
19
- # no way to test the call to super, unfortunately
20
- it "returns true if env[:body] is a hash with at least one hash in its values" do
21
- @env[:body] = {:a => {:c => 2}}
22
- expect(@multipart.process_request?(@env)).to be_truthy
23
- end
24
-
25
- it "returns true if env[:body] is a hash with at least one array in its values" do
26
- @env[:body] = {:a => [:c, 2]}
27
- expect(@multipart.process_request?(@env)).to be_truthy
28
- end
29
-
30
- it "returns true if env[:body] is a hash with mixed objects in its values" do
31
- @env[:body] = {:a => [:c, 2], :b => {:e => :f}}
32
- expect(@multipart.process_request?(@env)).to be_truthy
33
- end
34
-
35
- it "returns false if env[:body] is a string" do
36
- @env[:body] = "my body"
37
- expect(@multipart.process_request?(@env)).to be_falsey
38
- end
39
-
40
- it "returns false if env[:body] is a hash without an array or hash value" do
41
- @env[:body] = {:a => 3}
42
- expect(@multipart.process_request?(@env)).to be_falsey
43
- end
44
- end
45
-
46
- describe "#process_params" do
47
- before :each do
48
- @parent = Faraday::Request::Multipart.new
49
- @multipart = Koala::HTTPService::MultipartRequest.new
50
- @block = lambda {|k, v| "#{k}=#{v}"}
51
- end
52
-
53
- it "is identical to the parent for requests without a prefix" do
54
- hash = {:a => 2, :c => "3"}
55
- expect(@multipart.process_params(hash, &@block)).to eq(@parent.process_params(hash, &@block))
56
- end
57
-
58
- it "replaces encodes [ and ] if the request has a prefix" do
59
- hash = {:a => 2, :c => "3"}
60
- prefix = "foo"
61
- # process_params returns an array
62
- expect(@multipart.process_params(hash, prefix, &@block).join("&")).to eq(@parent.process_params(hash, prefix, &@block).join("&").gsub(/\[/, "%5B").gsub(/\]/, "%5D"))
63
- end
64
- end
65
- end