koala 3.0.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/test.yml +32 -0
- data/Gemfile +4 -3
- data/changelog.md +50 -0
- data/koala.gemspec +2 -1
- data/lib/koala/api/graph_error_checker.rb +1 -1
- data/lib/koala/api.rb +17 -3
- data/lib/koala/configuration.rb +7 -0
- data/lib/koala/errors.rb +21 -1
- data/lib/koala/http_service.rb +13 -2
- data/lib/koala/version.rb +1 -1
- data/readme.md +33 -2
- data/spec/cases/api_spec.rb +77 -0
- data/spec/cases/error_spec.rb +16 -3
- data/spec/cases/graph_api_batch_spec.rb +1 -1
- data/spec/cases/graph_error_checker_spec.rb +19 -1
- data/spec/cases/http_service_spec.rb +41 -2
- data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +1 -1
- data/spec/support/mock_http_service.rb +2 -2
- metadata +26 -45
- data/.travis.yml +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9f879bff1a0797804e8a89a2d8d34366ba21fafedd5317b4649326169dc9b7ed
|
4
|
+
data.tar.gz: 8f77e5f1d2f3eebcf5e08983ba4f2af69b64566d7d2d4dac6185a8b5c3222ba6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 704dee302c62d906fd9f065abc86ea0e9268a4b160460ccfb455f8a7dbd3d41631bacf75e155953e5fd9d54e01fa81abc39f7730db4ea1023893b80dd378aa22
|
7
|
+
data.tar.gz: 38c9e731f1a76e3d441c3e783032a8f306168723e1552e00167dcd0bd5ad696833afffd2797ff4f4e0ed97e986578f08533b58f5064fa0610819fb409d10ddd3
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
name: on ruby ${{matrix.ruby}}
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: [2.5, 2.6, 2.7, "3.0", 3.1, head]
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- name: Checkout repository
|
17
|
+
uses: actions/checkout@v2
|
18
|
+
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{matrix.ruby}}
|
23
|
+
|
24
|
+
- name: Install dependencies
|
25
|
+
run: bundle install --jobs 4 --retry 3
|
26
|
+
|
27
|
+
- name: Specs & Coverage
|
28
|
+
uses: paambaati/codeclimate-action@v3.0.0
|
29
|
+
env:
|
30
|
+
CC_TEST_REPORTER_ID: 7af99d9225b4c14640f9ec3cb2e24d2f7103ac49417b0bd989188fb6c25f2909
|
31
|
+
with:
|
32
|
+
coverageCommand: bundle exec rspec
|
data/Gemfile
CHANGED
@@ -7,15 +7,16 @@ group :development do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
group :development, :test do
|
10
|
+
gem "psych", '< 4.0.0' # safe_load signature not compatible with older rubies
|
10
11
|
gem "rake"
|
11
12
|
gem "typhoeus" unless defined? JRUBY_VERSION
|
12
13
|
end
|
13
14
|
|
14
15
|
group :test do
|
15
|
-
gem "rspec",
|
16
|
-
gem "vcr"
|
16
|
+
gem "rspec", "~> 3.0", "< 3.10" # resrict rspec version until https://github.com/rspec/rspec-support/pull/537 gets merged
|
17
|
+
gem "vcr", github: 'vcr/vcr', ref: '8ced6c96e01737a418cd270e0382a8c2c6d85f7f' # needs https://github.com/vcr/vcr/pull/907 for ruby 3.1
|
17
18
|
gem "webmock"
|
18
|
-
gem "
|
19
|
+
gem "simplecov"
|
19
20
|
end
|
20
21
|
|
21
22
|
gem "jruby-openssl" if defined? JRUBY_VERSION
|
data/changelog.md
CHANGED
@@ -1,3 +1,53 @@
|
|
1
|
+
Unreleased
|
2
|
+
==========
|
3
|
+
|
4
|
+
**Key breaking changes:**
|
5
|
+
|
6
|
+
New features:
|
7
|
+
|
8
|
+
Updated features:
|
9
|
+
|
10
|
+
Removed features:
|
11
|
+
|
12
|
+
Internal improvements:
|
13
|
+
|
14
|
+
Testing improvements:
|
15
|
+
|
16
|
+
Others:
|
17
|
+
|
18
|
+
v3.2.0 (2022-05-27)
|
19
|
+
======
|
20
|
+
|
21
|
+
New features:
|
22
|
+
|
23
|
+
* 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))
|
24
|
+
* 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))
|
25
|
+
|
26
|
+
Testing improvements:
|
27
|
+
|
28
|
+
* Fix builds for ruby 3.x
|
29
|
+
|
30
|
+
v3.1.0 (2022-01-18)
|
31
|
+
======
|
32
|
+
|
33
|
+
New features:
|
34
|
+
|
35
|
+
* mask_tokens config (default: true) to mask tokens in logs
|
36
|
+
|
37
|
+
Updated features:
|
38
|
+
|
39
|
+
* Log before and after sending request
|
40
|
+
|
41
|
+
Internal improvements:
|
42
|
+
|
43
|
+
* Lock Faraday to < 2
|
44
|
+
* Compatibility with ruby 3.x
|
45
|
+
|
46
|
+
Testing improvements:
|
47
|
+
|
48
|
+
* Use Github actions for CI
|
49
|
+
* Run CI on latest rubies
|
50
|
+
|
1
51
|
v3.0.0 (2017-03-17)
|
2
52
|
======
|
3
53
|
|
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")
|
26
|
+
gem.add_runtime_dependency("faraday", "< 2")
|
27
27
|
gem.add_runtime_dependency("addressable")
|
28
28
|
gem.add_runtime_dependency("json", ">= 1.8")
|
29
|
+
gem.add_runtime_dependency("rexml")
|
29
30
|
end
|
@@ -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 = [
|
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
|
@@ -102,7 +116,7 @@ module Koala
|
|
102
116
|
args = sanitize_request_parameters(args) unless preserve_form_arguments?(options)
|
103
117
|
|
104
118
|
# add a leading / if needed...
|
105
|
-
path = "/#{path}" unless path =~ /^\//
|
119
|
+
path = "/#{path}" unless path.to_s =~ /^\//
|
106
120
|
|
107
121
|
# make the request via the provided service
|
108
122
|
result = Koala.make_request(path, args, verb, options)
|
data/lib/koala/configuration.rb
CHANGED
@@ -28,6 +28,12 @@ class Koala::Configuration
|
|
28
28
|
# The server to use when constructing dialog URLs.
|
29
29
|
attr_accessor :dialog_host
|
30
30
|
|
31
|
+
# Whether or not to mask tokens
|
32
|
+
attr_accessor :mask_tokens
|
33
|
+
|
34
|
+
# Called with the info for the rate limits in the response header
|
35
|
+
attr_accessor :rate_limit_hook
|
36
|
+
|
31
37
|
# Certain Facebook services (beta, video) require you to access different
|
32
38
|
# servers. If you're using your own servers, for instance, for a proxy,
|
33
39
|
# you can change both the matcher (what value to change when updating the URL) and the
|
@@ -45,5 +51,6 @@ class Koala::Configuration
|
|
45
51
|
Koala::HTTPService::DEFAULT_SERVERS.each_pair do |key, value|
|
46
52
|
self.public_send("#{key}=", value)
|
47
53
|
end
|
54
|
+
self.mask_tokens = true
|
48
55
|
end
|
49
56
|
end
|
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
|
data/lib/koala/http_service.rb
CHANGED
@@ -49,6 +49,18 @@ module Koala
|
|
49
49
|
# set up our Faraday connection
|
50
50
|
conn = Faraday.new(request.server, faraday_options(request.options), &(faraday_middleware || DEFAULT_MIDDLEWARE))
|
51
51
|
|
52
|
+
filtered_args = request.raw_args.dup.transform_keys(&:to_s)
|
53
|
+
|
54
|
+
if Koala.config.mask_tokens
|
55
|
+
%w(access_token input_token).each do |arg_token|
|
56
|
+
if (token = filtered_args[arg_token])
|
57
|
+
filtered_args[arg_token] = token[0, 10] + '*****' + token[-5, 5]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Koala::Utils.debug "STARTED => #{request.verb.upcase}: #{request.path} params: #{filtered_args.inspect}"
|
63
|
+
|
52
64
|
if request.verb == "post" && request.json?
|
53
65
|
# JSON requires a bit more handling
|
54
66
|
# remember, all non-GET requests are turned into POSTs, so this covers everything but GETs
|
@@ -62,8 +74,7 @@ module Koala
|
|
62
74
|
response = conn.send(request.verb, request.path, request.post_args)
|
63
75
|
end
|
64
76
|
|
65
|
-
#
|
66
|
-
Koala::Utils.debug "#{request.verb.upcase}: #{request.path} params: #{request.raw_args.inspect}"
|
77
|
+
Koala::Utils.debug "FINISHED => #{request.verb.upcase}: #{request.path} params: #{filtered_args.inspect}"
|
67
78
|
Koala::HTTPService::Response.new(response.status.to_i, response.body, response.headers)
|
68
79
|
end
|
69
80
|
|
data/lib/koala/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
Koala [![Version](https://img.shields.io/gem/v/koala.svg)](https://rubygems.org/gems/koala) [![
|
1
|
+
Koala [![Version](https://img.shields.io/gem/v/koala.svg)](https://rubygems.org/gems/koala) [![Build Status](https://img.shields.io/travis/arsduo/koala.svg)](http://travis-ci.org/arsduo/koala) [![Code Climate](https://img.shields.io/codeclimate/coverage-letter/arsduo/koala.svg)](https://codeclimate.com/github/arsduo/koala) [![Code Coverage](https://img.shields.io/codeclimate/coverage/arsduo/koala.svg)](https://codeclimate.com/github/arsduo/koala)
|
2
2
|
====
|
3
|
-
[Koala](http://github.com/arsduo/koala) is a Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads), realtime updates, test users, and OAuth validation. We wrote Koala with four goals:
|
3
|
+
[Koala](http://github.com/arsduo/koala) is a Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads), the Marketing API, the Atlas API, realtime updates, test users, and OAuth validation. We wrote Koala with four goals:
|
4
4
|
|
5
5
|
* Lightweight: Koala should be as light and simple as Facebook’s own libraries, providing API accessors and returning simple JSON.
|
6
6
|
* Fast: Koala should, out of the box, be quick. Out of the box, we use Facebook's faster read-only servers when possible and if available, the Typhoeus gem to make snappy Facebook requests. Of course, that brings us to our next topic:
|
@@ -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
|
|
data/spec/cases/api_spec.rb
CHANGED
@@ -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: 859: 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
|
data/spec/cases/error_spec.rb
CHANGED
@@ -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: 859: 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
|
@@ -122,7 +122,8 @@ describe Koala::HTTPService do
|
|
122
122
|
|
123
123
|
let(:verb) { "get" }
|
124
124
|
let(:options) { {} }
|
125
|
-
let(:
|
125
|
+
let(:args) { {"an" => :arg } }
|
126
|
+
let(:request) { Koala::HTTPService::Request.new(path: "/foo", verb: verb, args: args, options: options) }
|
126
127
|
|
127
128
|
shared_examples_for :making_a_request do
|
128
129
|
before :each do
|
@@ -153,7 +154,8 @@ describe Koala::HTTPService do
|
|
153
154
|
|
154
155
|
it "logs verb, url and params to debug" do
|
155
156
|
log_message = "#{verb.upcase}: #{request.path} params: #{request.raw_args.inspect}"
|
156
|
-
expect(Koala::Utils.logger).to receive(:debug).with(log_message)
|
157
|
+
expect(Koala::Utils.logger).to receive(:debug).with("STARTED => #{log_message}")
|
158
|
+
expect(Koala::Utils.logger).to receive(:debug).with("FINISHED => #{log_message}")
|
157
159
|
|
158
160
|
Koala::HTTPService.make_request(request)
|
159
161
|
end
|
@@ -230,5 +232,42 @@ describe Koala::HTTPService do
|
|
230
232
|
|
231
233
|
Koala::HTTPService.make_request(request)
|
232
234
|
end
|
235
|
+
|
236
|
+
context 'log_tokens configuration' do
|
237
|
+
let(:args) { { "an" => :arg, "access_token" => "myvisbleaccesstoken" } }
|
238
|
+
|
239
|
+
before(:each) do
|
240
|
+
allow_any_instance_of(Faraday::Connection).to receive(:get) { double(status: '200', body: 'ok', headers: {}) }
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'logs tokens' do
|
244
|
+
allow(Koala.config).to receive(:mask_tokens) { false }
|
245
|
+
|
246
|
+
expect(Koala::Utils).to receive(:debug).with('STARTED => GET: /foo params: {"an"=>:arg, "access_token"=>"myvisbleaccesstoken"}')
|
247
|
+
expect(Koala::Utils).to receive(:debug).with('FINISHED => GET: /foo params: {"an"=>:arg, "access_token"=>"myvisbleaccesstoken"}')
|
248
|
+
|
249
|
+
Koala::HTTPService.make_request(request)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'doesnt log tokens' do
|
253
|
+
allow(Koala.config).to receive(:mask_tokens) { true }
|
254
|
+
|
255
|
+
expect(Koala::Utils).to receive(:debug).with('STARTED => GET: /foo params: {"an"=>:arg, "access_token"=>"myvisbleac*****token"}')
|
256
|
+
expect(Koala::Utils).to receive(:debug).with('FINISHED => GET: /foo params: {"an"=>:arg, "access_token"=>"myvisbleac*****token"}')
|
257
|
+
|
258
|
+
Koala::HTTPService.make_request(request)
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'hides the token for the debug_token api endpoint' do
|
262
|
+
request = Koala::HTTPService::Request.new(path: "/debug_token", verb: verb, args: { input_token: 'myvisibleaccesstoken', 'access_token' => 'myvisibleaccesstoken' }, options: options)
|
263
|
+
|
264
|
+
allow(Koala.config).to receive(:mask_tokens) { true }
|
265
|
+
|
266
|
+
expect(Koala::Utils).to receive(:debug).with('STARTED => GET: /debug_token params: {"input_token"=>"myvisiblea*****token", "access_token"=>"myvisiblea*****token"}')
|
267
|
+
expect(Koala::Utils).to receive(:debug).with('FINISHED => GET: /debug_token params: {"input_token"=>"myvisiblea*****token", "access_token"=>"myvisiblea*****token"}')
|
268
|
+
|
269
|
+
Koala::HTTPService.make_request(request)
|
270
|
+
end
|
271
|
+
end
|
233
272
|
end
|
234
273
|
end
|
@@ -8,7 +8,7 @@ module Koala
|
|
8
8
|
# Mocks all HTTP requests for with koala_spec_with_mocks.rb
|
9
9
|
# Mocked values to be included in TEST_DATA used in specs
|
10
10
|
ACCESS_TOKEN = '*'
|
11
|
-
APP_ACCESS_TOKEN = "
|
11
|
+
APP_ACCESS_TOKEN = "********************"
|
12
12
|
OAUTH_CODE = 'OAUTHCODE'
|
13
13
|
|
14
14
|
# Loads testing data
|
@@ -30,7 +30,7 @@ module Koala
|
|
30
30
|
|
31
31
|
# Loads the mock response data via ERB to substitue values for TEST_DATA (see oauth/access_token)
|
32
32
|
mock_response_file_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'mock_facebook_responses.yml')
|
33
|
-
RESPONSES = YAML.
|
33
|
+
RESPONSES = YAML.safe_load(ERB.new(IO.read(mock_response_file_path)).result(binding), [], [], true)
|
34
34
|
|
35
35
|
def self.make_request(request)
|
36
36
|
if response = match_response(request.raw_path, request.raw_args, request.raw_verb, request.raw_options)
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: koala
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Koppel
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-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: '
|
19
|
+
version: '2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "<"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: addressable
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rexml
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write
|
56
70
|
access to the social graph via the Graph and REST APIs, as well as support for realtime
|
57
71
|
updates and OAuth and Facebook Connect authentication. Koala is fully tested and
|
@@ -64,9 +78,9 @@ extra_rdoc_files:
|
|
64
78
|
- readme.md
|
65
79
|
- changelog.md
|
66
80
|
files:
|
81
|
+
- ".github/workflows/test.yml"
|
67
82
|
- ".gitignore"
|
68
83
|
- ".rspec"
|
69
|
-
- ".travis.yml"
|
70
84
|
- ".yardopts"
|
71
85
|
- Gemfile
|
72
86
|
- ISSUE_TEMPLATE
|
@@ -132,7 +146,7 @@ homepage: http://github.com/arsduo/koala
|
|
132
146
|
licenses:
|
133
147
|
- MIT
|
134
148
|
metadata: {}
|
135
|
-
post_install_message:
|
149
|
+
post_install_message:
|
136
150
|
rdoc_options:
|
137
151
|
- "--line-numbers"
|
138
152
|
- "--inline-source"
|
@@ -151,42 +165,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0'
|
153
167
|
requirements: []
|
154
|
-
|
155
|
-
|
156
|
-
signing_key:
|
168
|
+
rubygems_version: 3.0.0
|
169
|
+
signing_key:
|
157
170
|
specification_version: 4
|
158
171
|
summary: A lightweight, flexible library for Facebook with support for the Graph API,
|
159
172
|
the REST API, realtime updates, and OAuth authentication.
|
160
|
-
test_files:
|
161
|
-
- spec/cases/api_spec.rb
|
162
|
-
- spec/cases/configuration_spec.rb
|
163
|
-
- spec/cases/error_spec.rb
|
164
|
-
- spec/cases/graph_api_batch_spec.rb
|
165
|
-
- spec/cases/graph_api_spec.rb
|
166
|
-
- spec/cases/graph_collection_spec.rb
|
167
|
-
- spec/cases/graph_error_checker_spec.rb
|
168
|
-
- spec/cases/http_service/request_spec.rb
|
169
|
-
- spec/cases/http_service/response_spec.rb
|
170
|
-
- spec/cases/http_service_spec.rb
|
171
|
-
- spec/cases/koala_spec.rb
|
172
|
-
- spec/cases/koala_test_spec.rb
|
173
|
-
- spec/cases/multipart_request_spec.rb
|
174
|
-
- spec/cases/oauth_spec.rb
|
175
|
-
- spec/cases/realtime_updates_spec.rb
|
176
|
-
- spec/cases/test_users_spec.rb
|
177
|
-
- spec/cases/uploadable_io_spec.rb
|
178
|
-
- spec/cases/utils_spec.rb
|
179
|
-
- spec/fixtures/beach.jpg
|
180
|
-
- spec/fixtures/cat.m4v
|
181
|
-
- spec/fixtures/facebook_data.yml
|
182
|
-
- spec/fixtures/mock_facebook_responses.yml
|
183
|
-
- spec/fixtures/vcr_cassettes/app_test_accounts.yml
|
184
|
-
- spec/fixtures/vcr_cassettes/friend_list_next_page.yml
|
185
|
-
- spec/integration/graph_collection_spec.rb
|
186
|
-
- spec/spec_helper.rb
|
187
|
-
- spec/support/custom_matchers.rb
|
188
|
-
- spec/support/graph_api_shared_examples.rb
|
189
|
-
- spec/support/koala_test.rb
|
190
|
-
- spec/support/mock_http_service.rb
|
191
|
-
- spec/support/uploadable_io_shared_examples.rb
|
192
|
-
has_rdoc:
|
173
|
+
test_files: []
|
data/.travis.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
sudo: false
|
3
|
-
cache: bundler
|
4
|
-
rvm:
|
5
|
-
# MRI
|
6
|
-
- 2.1
|
7
|
-
- 2.2
|
8
|
-
- 2.3.1
|
9
|
-
- 2.4.0
|
10
|
-
# Rubinius is failing due to segfaults on Travis (and takes significantly longer to run)
|
11
|
-
# those builds will be restored later
|
12
|
-
# jruby
|
13
|
-
# - jruby-19mode
|
14
|
-
bundler_args: --without development
|
15
|
-
addons:
|
16
|
-
code_climate:
|
17
|
-
repo_token: 7af99d9225b4c14640f9ec3cb2e24d2f7103ac49417b0bd989188fb6c25f2909
|
18
|
-
after_success:
|
19
|
-
- bundle exec codeclimate-test-reporter
|