koala 0.4 → 3.7.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 +7 -0
- data/.github/workflows/test.yml +32 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +3 -0
- data/Gemfile +25 -0
- data/ISSUE_TEMPLATE +25 -0
- data/LICENSE +22 -0
- data/Manifest +32 -5
- data/PULL_REQUEST_TEMPLATE +11 -0
- data/Rakefile +12 -12
- data/changelog.md +781 -0
- data/code_of_conduct.md +74 -0
- data/koala.gemspec +28 -24
- data/lib/koala/api/batch_operation.rb +86 -0
- data/lib/koala/api/graph_api_methods.rb +504 -0
- data/lib/koala/api/graph_batch_api.rb +167 -0
- data/lib/koala/api/graph_collection.rb +129 -0
- data/lib/koala/api/graph_error_checker.rb +72 -0
- data/lib/koala/api.rb +159 -0
- data/lib/koala/configuration.rb +56 -0
- data/lib/koala/errors.rb +126 -0
- data/lib/koala/http_service/request.rb +133 -0
- data/lib/koala/http_service/response.rb +20 -0
- data/lib/koala/http_service/uploadable_io.rb +183 -0
- data/lib/koala/http_service.rb +108 -0
- data/lib/koala/oauth.rb +342 -0
- data/lib/koala/realtime_updates.rb +151 -0
- data/lib/koala/test_users.rb +189 -0
- data/lib/koala/utils.rb +41 -0
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +51 -291
- data/readme.md +269 -21
- data/spec/cases/api_spec.rb +362 -0
- data/spec/cases/configuration_spec.rb +11 -0
- data/spec/cases/error_spec.rb +143 -0
- data/spec/cases/graph_api_batch_spec.rb +788 -0
- data/spec/cases/graph_api_spec.rb +76 -0
- data/spec/cases/graph_collection_spec.rb +192 -0
- data/spec/cases/graph_error_checker_spec.rb +147 -0
- data/spec/cases/http_service/request_spec.rb +250 -0
- data/spec/cases/http_service/response_spec.rb +24 -0
- data/spec/cases/http_service_spec.rb +280 -0
- data/spec/cases/koala_spec.rb +57 -0
- data/spec/cases/koala_test_spec.rb +5 -0
- data/spec/cases/oauth_spec.rb +647 -0
- data/spec/cases/realtime_updates_spec.rb +327 -0
- data/spec/cases/test_users_spec.rb +383 -0
- data/spec/cases/uploadable_io_spec.rb +266 -0
- data/spec/cases/utils_spec.rb +55 -0
- data/spec/fixtures/beach.jpg +0 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +63 -0
- data/spec/fixtures/mock_facebook_responses.yml +483 -0
- data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
- data/spec/fixtures/vcr_cassettes/friend_list_next_page.yml +121 -0
- data/spec/integration/graph_collection_spec.rb +24 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/custom_matchers.rb +28 -0
- data/spec/support/graph_api_shared_examples.rb +534 -0
- data/spec/support/koala_test.rb +251 -0
- data/spec/support/mock_http_service.rb +140 -0
- data/spec/support/uploadable_io_shared_examples.rb +70 -0
- metadata +206 -62
- data/CHANGELOG +0 -24
- data/init.rb +0 -2
- data/lib/http_services.rb +0 -60
- data/test/facebook_data.yml +0 -5
- data/test/koala/facebook_no_access_token_tests.rb +0 -119
- data/test/koala/facebook_with_access_token_tests.rb +0 -106
- data/test/koala_tests.rb +0 -30
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Koala::HTTPService do
|
|
4
|
+
it "has a faraday_middleware accessor" do
|
|
5
|
+
expect(Koala::HTTPService.methods.map(&:to_sym)).to include(:faraday_middleware)
|
|
6
|
+
expect(Koala::HTTPService.methods.map(&:to_sym)).to include(:faraday_middleware=)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "has an http_options accessor" do
|
|
10
|
+
expect(Koala::HTTPService).to respond_to(:http_options)
|
|
11
|
+
expect(Koala::HTTPService).to respond_to(:http_options=)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "sets http_options to {} by default" do
|
|
15
|
+
expect(Koala::HTTPService.http_options).to eq({})
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "DEFAULT_MIDDLEWARE" do
|
|
19
|
+
class FakeBuilder
|
|
20
|
+
attr_reader :requests, :uses, :adapters
|
|
21
|
+
|
|
22
|
+
def use(arg)
|
|
23
|
+
@uses ||= []
|
|
24
|
+
@uses << arg
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def request(arg)
|
|
28
|
+
@requests ||= []
|
|
29
|
+
@requests << arg
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def adapter(arg)
|
|
33
|
+
@adapters ||= []
|
|
34
|
+
@adapters << arg
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
let(:builder) { FakeBuilder.new }
|
|
39
|
+
|
|
40
|
+
it "adds the right default middleware" do
|
|
41
|
+
Koala::HTTPService::DEFAULT_MIDDLEWARE.call(builder)
|
|
42
|
+
expect(builder.requests).to eq([:multipart, :url_encoded])
|
|
43
|
+
expect(builder.adapters).to eq([Faraday.default_adapter])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe Koala::HTTPService::DEFAULT_SERVERS do
|
|
48
|
+
let(:defaults) { Koala::HTTPService::DEFAULT_SERVERS }
|
|
49
|
+
|
|
50
|
+
it "defines the graph server" do
|
|
51
|
+
expect(defaults[:graph_server]).to eq("graph.facebook.com")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "defines the dialog host" do
|
|
55
|
+
expect(defaults[:dialog_host]).to eq("www.facebook.com")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "defines the path replacement regular expression" do
|
|
59
|
+
expect(defaults[:host_path_matcher]).to eq(/\.facebook/)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "defines the video server replacement for uploads" do
|
|
63
|
+
expect(defaults[:video_replace]).to eq("-video.facebook")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "defines the beta tier replacement" do
|
|
67
|
+
expect(defaults[:beta_replace]).to eq(".beta.facebook")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe ".encode_params" do
|
|
72
|
+
it "returns an empty string if param_hash evaluates to false" do
|
|
73
|
+
expect(Koala::HTTPService.encode_params(nil)).to eq('')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "converts values to JSON if the value is not a String" do
|
|
77
|
+
not_a_string = {not_a_string: 2}
|
|
78
|
+
|
|
79
|
+
args = {
|
|
80
|
+
:arg => not_a_string,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
result = Koala::HTTPService.encode_params(args)
|
|
84
|
+
expect(result.split('&').find do |key_and_val|
|
|
85
|
+
key_and_val.match("arg=#{CGI.escape not_a_string.to_json}")
|
|
86
|
+
end).to be_truthy
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "escapes all values" do
|
|
90
|
+
args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
|
|
91
|
+
|
|
92
|
+
result = Koala::HTTPService.encode_params(args)
|
|
93
|
+
result.split('&').each do |key_val|
|
|
94
|
+
key, val = key_val.split('=')
|
|
95
|
+
expect(val).to eq(CGI.escape(args[key]))
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "encodes parameters in alphabetical order" do
|
|
100
|
+
args = {:b => '2', 'a' => '1'}
|
|
101
|
+
|
|
102
|
+
result = Koala::HTTPService.encode_params(args)
|
|
103
|
+
expect(result.split('&').map{|key_val| key_val.split('=')[0]}).to eq(['a', 'b'])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "converts all keys to Strings" do
|
|
107
|
+
args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
|
|
108
|
+
|
|
109
|
+
result = Koala::HTTPService.encode_params(args)
|
|
110
|
+
result.split('&').each do |key_val|
|
|
111
|
+
key, val = key_val.split('=')
|
|
112
|
+
expect(key).to eq(args.find{|key_val_arr| key_val_arr.last == val}.first.to_s)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe ".make_request" do
|
|
118
|
+
let(:mock_body) { "a body" }
|
|
119
|
+
let(:mock_headers_hash) { double(value: "headers hash") }
|
|
120
|
+
let(:mock_http_response) { double("Faraday Response", status: 200, headers: mock_headers_hash, body: mock_body) }
|
|
121
|
+
|
|
122
|
+
let(:verb) { "get" }
|
|
123
|
+
let(:options) { {} }
|
|
124
|
+
let(:args) { {"an" => :arg } }
|
|
125
|
+
let(:request) { Koala::HTTPService::Request.new(path: "/foo", verb: verb, args: args, options: options) }
|
|
126
|
+
|
|
127
|
+
shared_examples_for :making_a_request do
|
|
128
|
+
before :each do
|
|
129
|
+
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(mock_http_response)
|
|
130
|
+
allow_any_instance_of(Faraday::Connection).to receive(:post).and_return(mock_http_response)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "makes a Faraday request appropriately" do
|
|
134
|
+
expect_any_instance_of(Faraday::Connection).to receive(verb) do |instance, path, post_params|
|
|
135
|
+
expect(path).to eq(request.path)
|
|
136
|
+
expect(post_params).to eq(request.post_args)
|
|
137
|
+
expect(instance.params).to eq(request.options[:params])
|
|
138
|
+
expect(instance.url_prefix).to eq(URI.parse(request.server))
|
|
139
|
+
|
|
140
|
+
mock_http_response
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
Koala::HTTPService.make_request(request)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "returns the right response" do
|
|
147
|
+
response = Koala::HTTPService.make_request(request)
|
|
148
|
+
expect(response.status).to eq(mock_http_response.status)
|
|
149
|
+
expect(response.headers).to eq(mock_http_response.headers)
|
|
150
|
+
expect(response.body).to eq(mock_http_response.body)
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "logs verb, url and params to debug" do
|
|
155
|
+
log_message = "#{verb.upcase}: #{request.path} params: #{request.raw_args.inspect}"
|
|
156
|
+
expect(Koala::Utils.logger).to receive(:debug).with("STARTED => #{log_message}")
|
|
157
|
+
expect(Koala::Utils.logger).to receive(:debug).with("FINISHED => #{log_message}")
|
|
158
|
+
|
|
159
|
+
Koala::HTTPService.make_request(request)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context "for gets" do
|
|
164
|
+
it_should_behave_like :making_a_request
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# we don't need to test delete and put since those are translated into posts
|
|
168
|
+
context "for posts" do
|
|
169
|
+
let(:verb) { "post" }
|
|
170
|
+
|
|
171
|
+
it_should_behave_like :making_a_request
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
context "for JSON requests" do
|
|
175
|
+
let(:verb) { "post" }
|
|
176
|
+
let(:options) { {format: :json} }
|
|
177
|
+
|
|
178
|
+
it "makes a Faraday request appropriately" do
|
|
179
|
+
expect_any_instance_of(Faraday::Connection).to receive(verb) do |instance, path, &block|
|
|
180
|
+
faraday_request = Faraday::Request.new
|
|
181
|
+
faraday_request.headers = {}
|
|
182
|
+
block.call(faraday_request)
|
|
183
|
+
expect(faraday_request.path).to eq(request.path)
|
|
184
|
+
expect(faraday_request.body).to eq(request.post_args.to_json)
|
|
185
|
+
expect(faraday_request.headers).to include("Content-Type" => "application/json")
|
|
186
|
+
|
|
187
|
+
mock_http_response
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
Koala::HTTPService.make_request(request)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "uses the default builder block if HTTPService.faraday_middleware block is not defined" do
|
|
195
|
+
block = Proc.new { |builder|
|
|
196
|
+
builder.request :multipart
|
|
197
|
+
builder.request :url_encoded
|
|
198
|
+
}
|
|
199
|
+
stub_const("Koala::HTTPService::DEFAULT_MIDDLEWARE", block)
|
|
200
|
+
allow(Koala::HTTPService).to receive(:faraday_middleware).and_return(nil)
|
|
201
|
+
|
|
202
|
+
expect_any_instance_of(Faraday::Connection).to receive(:get) do |instance|
|
|
203
|
+
expect(instance.builder.handlers).to eq([
|
|
204
|
+
Faraday::Multipart::Middleware,
|
|
205
|
+
Faraday::Request::UrlEncoded,
|
|
206
|
+
])
|
|
207
|
+
mock_http_response
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
Koala::HTTPService.make_request(request)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "uses the defined HTTPService.faraday_middleware block if defined" do
|
|
214
|
+
block = Proc.new { |builder|
|
|
215
|
+
builder.request :multipart
|
|
216
|
+
builder.request :url_encoded
|
|
217
|
+
}
|
|
218
|
+
expect(Koala::HTTPService).to receive(:faraday_middleware).and_return(block)
|
|
219
|
+
|
|
220
|
+
expect_any_instance_of(Faraday::Connection).to receive(:get) do |instance|
|
|
221
|
+
expect(instance.builder.handlers).to eq([
|
|
222
|
+
Faraday::Multipart::Middleware,
|
|
223
|
+
Faraday::Request::UrlEncoded,
|
|
224
|
+
])
|
|
225
|
+
mock_http_response
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
Koala::HTTPService.make_request(request)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
context 'log_tokens configuration' do
|
|
232
|
+
let(:args) { { "an" => :arg, "access_token" => "myvisbleaccesstoken" } }
|
|
233
|
+
|
|
234
|
+
before(:each) do
|
|
235
|
+
allow_any_instance_of(Faraday::Connection).to receive(:get) { double(status: '200', body: 'ok', headers: {}) }
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it 'logs tokens' do
|
|
239
|
+
allow(Koala.config).to receive(:mask_tokens) { false }
|
|
240
|
+
|
|
241
|
+
expect(Koala::Utils).to receive(:debug) do |log|
|
|
242
|
+
expect(log).to match(/STARTED => GET: \/foo params: {"an"\s?=>\s?:arg, "access_token"\s?=>\s?"myvisbleaccesstoken"}/)
|
|
243
|
+
end
|
|
244
|
+
expect(Koala::Utils).to receive(:debug) do |log|
|
|
245
|
+
expect(log).to match(/FINISHED => GET: \/foo params: {"an"\s?=>\s?:arg, "access_token"\s?=>\s?"myvisbleaccesstoken"}/)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
Koala::HTTPService.make_request(request)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it 'doesnt log tokens' do
|
|
252
|
+
allow(Koala.config).to receive(:mask_tokens) { true }
|
|
253
|
+
|
|
254
|
+
expect(Koala::Utils).to receive(:debug) do |log|
|
|
255
|
+
expect(log).to match(/STARTED => GET: \/foo params: {"an"\s?=>\s?:arg, "access_token"\s?=>\s?"myvisbleac[*]{5}token"}/)
|
|
256
|
+
end
|
|
257
|
+
expect(Koala::Utils).to receive(:debug) do |log|
|
|
258
|
+
expect(log).to match(/FINISHED => GET: \/foo params: {"an"\s?=>\s?:arg, "access_token"\s?=>\s?"myvisbleac[*]{5}token"}/)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
Koala::HTTPService.make_request(request)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'hides the token for the debug_token api endpoint' do
|
|
265
|
+
request = Koala::HTTPService::Request.new(path: "/debug_token", verb: verb, args: { input_token: 'myvisibleaccesstoken', 'access_token' => 'myvisibleaccesstoken' }, options: options)
|
|
266
|
+
|
|
267
|
+
allow(Koala.config).to receive(:mask_tokens) { true }
|
|
268
|
+
|
|
269
|
+
expect(Koala::Utils).to receive(:debug) do |log|
|
|
270
|
+
expect(log).to match(/STARTED => GET: \/debug_token params: {"input_token"\s?=>\s?"myvisiblea[*]{5}token", "access_token"\s?=>\s?"myvisiblea[*]{5}token"}/)
|
|
271
|
+
end
|
|
272
|
+
expect(Koala::Utils).to receive(:debug) do |log|
|
|
273
|
+
expect(log).to match(/FINISHED => GET: \/debug_token params: {"input_token"\s?=>\s?"myvisiblea[*]{5}token", "access_token"\s?=>\s?"myvisiblea[*]{5}token"}/)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
Koala::HTTPService.make_request(request)
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Koala do
|
|
4
|
+
it "has an http_service accessor" do
|
|
5
|
+
expect(Koala).to respond_to(:http_service)
|
|
6
|
+
expect(Koala).to respond_to(:http_service=)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe "constants" do
|
|
10
|
+
it "has a version" do
|
|
11
|
+
expect(Koala.const_defined?("VERSION")).to be_truthy
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "make_request" do
|
|
16
|
+
it "passes all its arguments to the http_service" do
|
|
17
|
+
path = "foo"
|
|
18
|
+
args = {:a => 2}
|
|
19
|
+
verb = "get"
|
|
20
|
+
options = {:c => :d}
|
|
21
|
+
|
|
22
|
+
expect(Koala.http_service).to receive(:make_request) do |request|
|
|
23
|
+
expect(request.raw_path).to eq(path)
|
|
24
|
+
expect(request.raw_args).to eq(args)
|
|
25
|
+
expect(request.raw_verb).to eq(verb)
|
|
26
|
+
expect(request.raw_options).to eq(options)
|
|
27
|
+
end
|
|
28
|
+
Koala.make_request(path, args, verb, options)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe ".configure" do
|
|
33
|
+
it "yields a configurable object" do
|
|
34
|
+
Koala.configure {|c| expect(c).to be_a(Koala::Configuration)}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "caches the config (singleton)" do
|
|
38
|
+
c = Koala.config
|
|
39
|
+
expect(c.object_id).to eq(Koala.config.object_id)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe ".config" do
|
|
44
|
+
it "exposes the basic configuration" do
|
|
45
|
+
Koala::HTTPService::DEFAULT_SERVERS.each_pair do |k, v|
|
|
46
|
+
expect(Koala.config.send(k)).to eq(v)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "exposes the values configured" do
|
|
51
|
+
Koala.configure do |config|
|
|
52
|
+
config.graph_server = "some-new.graph_server.com"
|
|
53
|
+
end
|
|
54
|
+
expect(Koala.config.graph_server).to eq("some-new.graph_server.com")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|