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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/test.yml +32 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +1 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +25 -0
  7. data/ISSUE_TEMPLATE +25 -0
  8. data/LICENSE +22 -0
  9. data/Manifest +32 -5
  10. data/PULL_REQUEST_TEMPLATE +11 -0
  11. data/Rakefile +12 -12
  12. data/changelog.md +781 -0
  13. data/code_of_conduct.md +74 -0
  14. data/koala.gemspec +28 -24
  15. data/lib/koala/api/batch_operation.rb +86 -0
  16. data/lib/koala/api/graph_api_methods.rb +504 -0
  17. data/lib/koala/api/graph_batch_api.rb +167 -0
  18. data/lib/koala/api/graph_collection.rb +129 -0
  19. data/lib/koala/api/graph_error_checker.rb +72 -0
  20. data/lib/koala/api.rb +159 -0
  21. data/lib/koala/configuration.rb +56 -0
  22. data/lib/koala/errors.rb +126 -0
  23. data/lib/koala/http_service/request.rb +133 -0
  24. data/lib/koala/http_service/response.rb +20 -0
  25. data/lib/koala/http_service/uploadable_io.rb +183 -0
  26. data/lib/koala/http_service.rb +108 -0
  27. data/lib/koala/oauth.rb +342 -0
  28. data/lib/koala/realtime_updates.rb +151 -0
  29. data/lib/koala/test_users.rb +189 -0
  30. data/lib/koala/utils.rb +41 -0
  31. data/lib/koala/version.rb +3 -0
  32. data/lib/koala.rb +51 -291
  33. data/readme.md +269 -21
  34. data/spec/cases/api_spec.rb +362 -0
  35. data/spec/cases/configuration_spec.rb +11 -0
  36. data/spec/cases/error_spec.rb +143 -0
  37. data/spec/cases/graph_api_batch_spec.rb +788 -0
  38. data/spec/cases/graph_api_spec.rb +76 -0
  39. data/spec/cases/graph_collection_spec.rb +192 -0
  40. data/spec/cases/graph_error_checker_spec.rb +147 -0
  41. data/spec/cases/http_service/request_spec.rb +250 -0
  42. data/spec/cases/http_service/response_spec.rb +24 -0
  43. data/spec/cases/http_service_spec.rb +280 -0
  44. data/spec/cases/koala_spec.rb +57 -0
  45. data/spec/cases/koala_test_spec.rb +5 -0
  46. data/spec/cases/oauth_spec.rb +647 -0
  47. data/spec/cases/realtime_updates_spec.rb +327 -0
  48. data/spec/cases/test_users_spec.rb +383 -0
  49. data/spec/cases/uploadable_io_spec.rb +266 -0
  50. data/spec/cases/utils_spec.rb +55 -0
  51. data/spec/fixtures/beach.jpg +0 -0
  52. data/spec/fixtures/cat.m4v +0 -0
  53. data/spec/fixtures/facebook_data.yml +63 -0
  54. data/spec/fixtures/mock_facebook_responses.yml +483 -0
  55. data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
  56. data/spec/fixtures/vcr_cassettes/friend_list_next_page.yml +121 -0
  57. data/spec/integration/graph_collection_spec.rb +24 -0
  58. data/spec/spec_helper.rb +25 -0
  59. data/spec/support/custom_matchers.rb +28 -0
  60. data/spec/support/graph_api_shared_examples.rb +534 -0
  61. data/spec/support/koala_test.rb +251 -0
  62. data/spec/support/mock_http_service.rb +140 -0
  63. data/spec/support/uploadable_io_shared_examples.rb +70 -0
  64. metadata +206 -62
  65. data/CHANGELOG +0 -24
  66. data/init.rb +0 -2
  67. data/lib/http_services.rb +0 -60
  68. data/test/facebook_data.yml +0 -5
  69. data/test/koala/facebook_no_access_token_tests.rb +0 -119
  70. data/test/koala/facebook_with_access_token_tests.rb +0 -106
  71. 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
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe KoalaTest do
4
+ pending "should have tests, because the test suite depends on it"
5
+ end