koala 1.1.0 → 1.2.0beta1

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 (50) hide show
  1. data/.travis.yml +2 -1
  2. data/CHANGELOG +26 -0
  3. data/Gemfile +6 -2
  4. data/Rakefile +0 -1
  5. data/koala.gemspec +8 -8
  6. data/lib/koala.rb +42 -45
  7. data/lib/koala/batch_operation.rb +15 -15
  8. data/lib/koala/graph_api.rb +81 -58
  9. data/lib/koala/graph_batch_api.rb +10 -10
  10. data/lib/koala/graph_collection.rb +6 -6
  11. data/lib/koala/http_service.rb +177 -0
  12. data/lib/koala/oauth.rb +2 -2
  13. data/lib/koala/realtime_updates.rb +20 -17
  14. data/lib/koala/rest_api.rb +1 -1
  15. data/lib/koala/test_users.rb +33 -16
  16. data/lib/koala/uploadable_io.rb +47 -42
  17. data/lib/koala/utils.rb +11 -0
  18. data/readme.md +38 -38
  19. data/spec/cases/api_base_spec.rb +2 -2
  20. data/spec/cases/error_spec.rb +32 -0
  21. data/spec/cases/graph_and_rest_api_spec.rb +20 -3
  22. data/spec/cases/graph_api_batch_spec.rb +88 -97
  23. data/spec/cases/graph_api_spec.rb +21 -4
  24. data/spec/cases/http_service_spec.rb +446 -0
  25. data/spec/cases/koala_spec.rb +33 -38
  26. data/spec/cases/oauth_spec.rb +219 -200
  27. data/spec/cases/realtime_updates_spec.rb +45 -31
  28. data/spec/cases/rest_api_spec.rb +23 -7
  29. data/spec/cases/test_users_spec.rb +112 -52
  30. data/spec/cases/uploadable_io_spec.rb +49 -36
  31. data/spec/cases/utils_spec.rb +10 -0
  32. data/spec/fixtures/facebook_data.yml +23 -22
  33. data/spec/fixtures/mock_facebook_responses.yml +126 -96
  34. data/spec/spec_helper.rb +29 -5
  35. data/spec/support/graph_api_shared_examples.rb +59 -52
  36. data/spec/support/json_testing_fix.rb +35 -11
  37. data/spec/support/koala_test.rb +163 -0
  38. data/spec/support/mock_http_service.rb +6 -4
  39. data/spec/support/ordered_hash.rb +205 -0
  40. data/spec/support/rest_api_shared_examples.rb +37 -37
  41. data/spec/support/uploadable_io_shared_examples.rb +2 -8
  42. metadata +78 -79
  43. data/lib/koala/http_services.rb +0 -46
  44. data/lib/koala/http_services/net_http_service.rb +0 -92
  45. data/lib/koala/http_services/typhoeus_service.rb +0 -37
  46. data/spec/cases/http_services/http_service_spec.rb +0 -129
  47. data/spec/cases/http_services/net_http_service_spec.rb +0 -532
  48. data/spec/cases/http_services/typhoeus_service_spec.rb +0 -152
  49. data/spec/support/live_testing_data_helper.rb +0 -40
  50. data/spec/support/setup_mocks_or_live.rb +0 -51
@@ -1,11 +1,28 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Koala::Facebook::GraphAPI" do
4
- include LiveTestingDataHelper
5
-
4
+ describe "class consolidation" do
5
+ before :each do
6
+ Koala::Utils.stub(:deprecate) # avoid actual messages to stderr
7
+ end
8
+
9
+ it "still allows you to instantiate a GraphAndRestAPI object" do
10
+ api = Koala::Facebook::GraphAPI.new("token").should be_a(Koala::Facebook::GraphAPI)
11
+ end
12
+
13
+ it "ultimately creates an API object" do
14
+ api = Koala::Facebook::GraphAPI.new("token").should be_a(Koala::Facebook::API)
15
+ end
16
+
17
+ it "fires a depreciation warning" do
18
+ Koala::Utils.should_receive(:deprecate)
19
+ api = Koala::Facebook::GraphAPI.new("token")
20
+ end
21
+ end
22
+
6
23
  context "with an access token" do
7
24
  before :each do
8
- @api = Koala::Facebook::GraphAPI.new(@token)
25
+ @api = Koala::Facebook::API.new(@token)
9
26
  end
10
27
 
11
28
  it_should_behave_like "Koala GraphAPI"
@@ -15,7 +32,7 @@ describe "Koala::Facebook::GraphAPI" do
15
32
 
16
33
  context "without an access token" do
17
34
  before :each do
18
- @api = Koala::Facebook::GraphAPI.new
35
+ @api = Koala::Facebook::API.new
19
36
  end
20
37
 
21
38
  it_should_behave_like "Koala GraphAPI"
@@ -0,0 +1,446 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Koala::HTTPService" do
4
+ it "has a faraday_middleware accessor" do
5
+ Koala::HTTPService.methods.map(&:to_sym).should include(:faraday_middleware)
6
+ Koala::HTTPService.methods.map(&:to_sym).should include(:faraday_middleware=)
7
+ end
8
+
9
+ it "has an http_options accessor" do
10
+ Koala::HTTPService.should respond_to(:http_options)
11
+ Koala::HTTPService.should respond_to(:http_options=)
12
+ end
13
+
14
+ it "sets http_options to {} by default" do
15
+ Koala::HTTPService.http_options.should == {}
16
+ end
17
+
18
+ describe "DEFAULT_MIDDLEWARE" do
19
+ before :each do
20
+ @builder = stub("Faraday connection builder")
21
+ @builder.stub(:request)
22
+ @builder.stub(:adapter)
23
+ end
24
+
25
+ it "is defined" do
26
+ Koala::HTTPService.const_defined?("DEFAULT_MIDDLEWARE").should be_true
27
+ end
28
+
29
+ it "adds multipart" do
30
+ @builder.should_receive(:request).with(:multipart)
31
+ Koala::HTTPService::DEFAULT_MIDDLEWARE.call(@builder)
32
+ end
33
+
34
+ it "adds url_encoded" do
35
+ @builder.should_receive(:request).with(:url_encoded)
36
+ Koala::HTTPService::DEFAULT_MIDDLEWARE.call(@builder)
37
+ end
38
+
39
+ it "uses the default adapter" do
40
+ adapter = :testing_now
41
+ Faraday.stub(:default_adapter).and_return(adapter)
42
+ @builder.should_receive(:adapter).with(adapter)
43
+ Koala::HTTPService::DEFAULT_MIDDLEWARE.call(@builder)
44
+ end
45
+ end
46
+
47
+ describe "server" do
48
+ describe "with no options" do
49
+ it "returns the REST server if options[:rest_api]" do
50
+ Koala::HTTPService.server(:rest_api => true).should =~ Regexp.new(Koala::Facebook::REST_SERVER)
51
+ end
52
+
53
+ it "returns the graph server if !options[:rest_api]" do
54
+ Koala::HTTPService.server(:rest_api => false).should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER)
55
+ Koala::HTTPService.server({}).should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER)
56
+ end
57
+ end
58
+
59
+ describe "with options[:beta]" do
60
+ before :each do
61
+ @options = {:beta => true}
62
+ end
63
+
64
+ it "returns the beta REST server if options[:rest_api]" do
65
+ server = Koala::HTTPService.server(@options.merge(:rest_api => true))
66
+ server.should =~ Regexp.new("beta.#{Koala::Facebook::REST_SERVER}")
67
+ end
68
+
69
+ it "returns the beta rest server if !options[:rest_api]" do
70
+ server = Koala::HTTPService.server(@options)
71
+ server.should =~ Regexp.new("beta.#{Koala::Facebook::GRAPH_SERVER}")
72
+ end
73
+ end
74
+
75
+ describe "with options[:video]" do
76
+ before :each do
77
+ @options = {:video => true}
78
+ end
79
+
80
+ it "should return the REST video server if options[:rest_api]" do
81
+ server = Koala::HTTPService.server(@options.merge(:rest_api => true))
82
+ server.should =~ Regexp.new(Koala::Facebook::REST_SERVER.gsub(/\.facebook/, "-video.facebook"))
83
+ end
84
+
85
+ it "should return the graph video server if !options[:rest_api]" do
86
+ server = Koala::HTTPService.server(@options)
87
+ server.should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER.gsub(/\.facebook/, "-video.facebook"))
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#encode_params" do
93
+ it "should return an empty string if param_hash evaluates to false" do
94
+ Koala::HTTPService.encode_params(nil).should == ''
95
+ end
96
+
97
+ it "should convert values to JSON if the value is not a String" do
98
+ val = 'json_value'
99
+ not_a_string = 'not_a_string'
100
+ not_a_string.stub(:is_a?).and_return(false)
101
+ MultiJson.should_receive(:encode).with(not_a_string).and_return(val)
102
+
103
+ string = "hi"
104
+
105
+ args = {
106
+ not_a_string => not_a_string,
107
+ string => string
108
+ }
109
+
110
+ result = Koala::HTTPService.encode_params(args)
111
+ result.split('&').find do |key_and_val|
112
+ key_and_val.match("#{not_a_string}=#{val}")
113
+ end.should be_true
114
+ end
115
+
116
+ it "should escape all values" do
117
+ args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
118
+
119
+ result = Koala::HTTPService.encode_params(args)
120
+ result.split('&').each do |key_val|
121
+ key, val = key_val.split('=')
122
+ val.should == CGI.escape(args[key])
123
+ end
124
+ end
125
+
126
+ it "should convert all keys to Strings" do
127
+ args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
128
+
129
+ result = Koala::HTTPService.encode_params(args)
130
+ result.split('&').each do |key_val|
131
+ key, val = key_val.split('=')
132
+ key.should == args.find{|key_val_arr| key_val_arr.last == val}.first.to_s
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "#make_request" do
138
+ before :each do
139
+ # Setup stubs for make_request to execute without exceptions
140
+ @mock_body = stub('Typhoeus response body')
141
+ @mock_headers_hash = stub({:value => "headers hash"})
142
+ @mock_http_response = stub("Faraday Response", :status => 200, :headers => @mock_headers_hash, :body => @mock_body)
143
+
144
+ @mock_connection = stub("Faraday connection")
145
+ @mock_connection.stub(:get).and_return(@mock_http_response)
146
+ @mock_connection.stub(:post).and_return(@mock_http_response)
147
+ Faraday.stub(:new).and_return(@mock_connection)
148
+ end
149
+
150
+ describe "creating the Faraday connection" do
151
+ it "creates a Faraday connection using the server" do
152
+ server = "foo"
153
+ Koala::HTTPService.stub(:server).and_return(server)
154
+ Faraday.should_receive(:new).with(server, anything).and_return(@mock_connection)
155
+ Koala::HTTPService.make_request("anything", {}, "anything")
156
+ end
157
+
158
+ it "merges Koala::HTTPService.http_options into the request params" do
159
+ http_options = {:a => 2, :c => "3"}
160
+ Koala::HTTPService.http_options = http_options
161
+ Faraday.should_receive(:new).with(anything, hash_including(http_options)).and_return(@mock_connection)
162
+ Koala::HTTPService.make_request("anything", {}, "get")
163
+ end
164
+
165
+ it "merges any provided options into the request params" do
166
+ options = {:a => 2, :c => "3"}
167
+ Faraday.should_receive(:new).with(anything, hash_including(options)).and_return(@mock_connection)
168
+ Koala::HTTPService.make_request("anything", {}, "get", options)
169
+ end
170
+
171
+ it "overrides Koala::HTTPService.http_options with any provided options for the request params" do
172
+ options = {:a => 2, :c => "3"}
173
+ http_options = {:a => :a}
174
+ Koala::HTTPService.stub(:http_options).and_return(http_options)
175
+
176
+ Faraday.should_receive(:new).with(anything, hash_including(http_options.merge(options))).and_return(@mock_connection)
177
+ Koala::HTTPService.make_request("anything", {}, "get", options)
178
+ end
179
+
180
+ it "forces use_ssl to true if an access token is present" do
181
+ options = {:use_ssl => false}
182
+ Koala::HTTPService.stub(:http_options).and_return(:use_ssl => false)
183
+ Faraday.should_receive(:new).with(anything, hash_including(:use_ssl => true)).and_return(@mock_connection)
184
+ Koala::HTTPService.make_request("anything", {"access_token" => "foo"}, "get", options)
185
+ end
186
+
187
+ it "calls server with the composite options" do
188
+ options = {:a => 2, :c => "3"}
189
+ http_options = {:a => :a}
190
+ Koala::HTTPService.stub(:http_options).and_return(http_options)
191
+ Koala::HTTPService.should_receive(:server).with(hash_including(http_options.merge(options))).and_return("foo")
192
+ Koala::HTTPService.make_request("anything", {}, "get", options)
193
+ end
194
+
195
+ it "uses the default builder block if HTTPService.faraday_middleware block is not defined" do
196
+ Koala::HTTPService.stub(:faraday_middleware).and_return(nil)
197
+ Faraday.should_receive(:new).with(anything, anything, &Koala::HTTPService::DEFAULT_MIDDLEWARE).and_return(@mock_connection)
198
+ Koala::HTTPService.make_request("anything", {}, "get")
199
+ end
200
+
201
+ it "uses the defined HTTPService.faraday_middleware block if defined" do
202
+ block = Proc.new { }
203
+ Koala::HTTPService.should_receive(:faraday_middleware).and_return(block)
204
+ Faraday.should_receive(:new).with(anything, anything, &block).and_return(@mock_connection)
205
+ Koala::HTTPService.make_request("anything", {}, "get")
206
+ end
207
+ end
208
+
209
+ it "makes a POST request if the verb isn't get" do
210
+ @mock_connection.should_receive(:post).and_return(@mock_http_response)
211
+ Koala::HTTPService.make_request("anything", {}, "anything")
212
+ end
213
+
214
+ it "includes the verb in the body if the verb isn't get" do
215
+ verb = "eat"
216
+ @mock_connection.should_receive(:post).with(anything, hash_including("method" => verb)).and_return(@mock_http_response)
217
+ Koala::HTTPService.make_request("anything", {}, verb)
218
+ end
219
+
220
+ it "makes a GET request if the verb is get" do
221
+ @mock_connection.should_receive(:get).and_return(@mock_http_response)
222
+ Koala::HTTPService.make_request("anything", {}, "get")
223
+ end
224
+
225
+ describe "for GETs" do
226
+ it "submits the arguments in the body" do
227
+ # technically this is done for all requests, but you don't send GET requests with files
228
+ args = {"a" => :b, "c" => 3}
229
+ Faraday.should_receive(:new).with(anything, hash_including(:params => args)).and_return(@mock_connection)
230
+ Koala::HTTPService.make_request("anything", args, "get")
231
+ end
232
+
233
+ it "submits nothing to the body" do
234
+ # technically this is done for all requests, but you don't send GET requests with files
235
+ args = {"a" => :b, "c" => 3}
236
+ @mock_connection.should_receive(:get).with(anything, {}).and_return(@mock_http_response)
237
+ Koala::HTTPService.make_request("anything", args, "get")
238
+ end
239
+ end
240
+
241
+ describe "for POSTs" do
242
+ it "submits the arguments in the body" do
243
+ # technically this is done for all requests, but you don't send GET requests with files
244
+ args = {"a" => :b, "c" => 3}
245
+ @mock_connection.should_receive(:post).with(anything, hash_including(args)).and_return(@mock_http_response)
246
+ Koala::HTTPService.make_request("anything", args, "post")
247
+ end
248
+
249
+ it "turns any UploadableIOs to UploadIOs" do
250
+ # technically this is done for all requests, but you don't send GET requests with files
251
+ upload_io = stub("UploadIO")
252
+ u = Koala::UploadableIO.new("/path/to/stuff", "img/jpg")
253
+ u.stub(:to_upload_io).and_return(upload_io)
254
+ @mock_connection.should_receive(:post).with(anything, hash_including("source" => upload_io)).and_return(@mock_http_response)
255
+ Koala::HTTPService.make_request("anything", {:source => u}, "post")
256
+ end
257
+ end
258
+ end
259
+
260
+ describe "deprecated options" do
261
+ before :each do
262
+ Koala::HTTPService.stub(:http_options).and_return({})
263
+ @service = Koala.http_service
264
+ end
265
+
266
+ after :each do
267
+ Koala.http_service = @service
268
+ end
269
+
270
+ {
271
+ :timeout => :timeout,
272
+ :always_use_ssl => :use_ssl,
273
+ :proxy => :proxy
274
+ }.each_pair do |deprecated_method, parameter|
275
+ describe "##{deprecated_method}" do
276
+ context "read" do
277
+ it "reads http_options[:#{parameter}]" do
278
+ value = "foo"
279
+ Koala::HTTPService.http_options[parameter] = value
280
+ Koala::HTTPService.send(deprecated_method).should == value
281
+ end
282
+
283
+ it "generates a deprecation warning" do
284
+ Koala::Utils.should_receive(:deprecate)
285
+ Koala::HTTPService.send(deprecated_method)
286
+ end
287
+ end
288
+
289
+ context "write" do
290
+ it "writes to http_options[:#{parameter}]" do
291
+ Koala::HTTPService.http_options[parameter] = nil
292
+ value = "foo"
293
+ Koala::HTTPService.send(:"#{deprecated_method}=", value)
294
+ Koala::HTTPService.http_options[parameter].should == value
295
+ end
296
+
297
+ it "generates a deprecation warning" do
298
+ Koala::Utils.should_receive(:deprecate)
299
+ Koala::HTTPService.send(:"#{deprecated_method}=", 2)
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ # ssl options
306
+ [:ca_path, :ca_file, :verify_mode].each do |deprecated_method|
307
+ describe "##{deprecated_method}" do
308
+ context "read" do
309
+ it "reads http_options[:ssl][:#{deprecated_method}] if http_options[:ssl]" do
310
+ value = "foo"
311
+ Koala::HTTPService.http_options[:ssl] = {deprecated_method => value}
312
+ Koala::HTTPService.send(deprecated_method).should == value
313
+ end
314
+
315
+ it "returns nil if http_options[:ssl] is not defined" do
316
+ Koala::HTTPService.send(deprecated_method).should be_nil
317
+ end
318
+
319
+ it "generates a deprecation warning" do
320
+ Koala::Utils.should_receive(:deprecate)
321
+ Koala::HTTPService.send(deprecated_method)
322
+ end
323
+ end
324
+
325
+ context "write" do
326
+ it "defines http_options[:ssl] if not defined" do
327
+ Koala::HTTPService.http_options[:ssl] = nil
328
+ value = "foo"
329
+ Koala::HTTPService.send(:"#{deprecated_method}=", value)
330
+ Koala::HTTPService.http_options[:ssl].should
331
+ end
332
+
333
+ it "writes to http_options[:ssl][:#{deprecated_method}]" do
334
+ value = "foo"
335
+ Koala::HTTPService.send(:"#{deprecated_method}=", value)
336
+ Koala::HTTPService.http_options[:ssl].should
337
+ Koala::HTTPService.http_options[:ssl][deprecated_method].should == value
338
+ end
339
+
340
+ it "does not redefine http_options[:ssl] if already defined" do
341
+ hash = {:a => 2}
342
+ Koala::HTTPService.http_options[:ssl] = hash
343
+ Koala::HTTPService.send(:"#{deprecated_method}=", 3)
344
+ Koala::HTTPService.http_options[:ssl].should include(hash)
345
+ end
346
+
347
+ it "generates a deprecation warning" do
348
+ Koala::Utils.should_receive(:deprecate)
349
+ Koala::HTTPService.send(:"#{deprecated_method}=", 2)
350
+ end
351
+ end
352
+ end
353
+ end
354
+
355
+ describe "per-request options" do
356
+ before :each do
357
+ # Setup stubs for make_request to execute without exceptions
358
+ @mock_body = stub('Typhoeus response body')
359
+ @mock_headers_hash = stub({:value => "headers hash"})
360
+ @mock_http_response = stub("Faraday Response", :status => 200, :headers => @mock_headers_hash, :body => @mock_body)
361
+
362
+ @mock_connection = stub("Faraday connection")
363
+ @mock_connection.stub(:get).and_return(@mock_http_response)
364
+ @mock_connection.stub(:post).and_return(@mock_http_response)
365
+ Faraday.stub(:new).and_return(@mock_connection)
366
+ end
367
+
368
+ describe ":typhoeus_options" do
369
+ it "merges any typhoeus_options into options" do
370
+ typhoeus_options = {:a => 2}
371
+ Faraday.should_receive(:new).with(anything, hash_including(typhoeus_options)).and_return(@mock_connection)
372
+ Koala::HTTPService.make_request("anything", {}, "get", :typhoeus_options => typhoeus_options)
373
+ end
374
+
375
+ it "deletes the typhoeus_options key" do
376
+ typhoeus_options = {:a => 2}
377
+ Faraday.should_receive(:new).with(anything, hash_not_including(:typhoeus_options => typhoeus_options)).and_return(@mock_connection)
378
+ Koala::HTTPService.make_request("anything", {}, "get", :typhoeus_options => typhoeus_options)
379
+ end
380
+ end
381
+
382
+ describe ":ca_path" do
383
+ it "sets any ca_path into options[:ssl]" do
384
+ ca_path = :foo
385
+ Faraday.should_receive(:new).with(anything, hash_including(:ssl => hash_including(:ca_path => ca_path))).and_return(@mock_connection)
386
+ Koala::HTTPService.make_request("anything", {}, "get", :ca_path => ca_path)
387
+ end
388
+
389
+ it "deletes the ca_path key" do
390
+ ca_path = :foo
391
+ Faraday.should_receive(:new).with(anything, hash_not_including(:ca_path => ca_path)).and_return(@mock_connection)
392
+ Koala::HTTPService.make_request("anything", {}, "get", :ca_path => ca_path)
393
+ end
394
+ end
395
+
396
+ describe ":ca_file" do
397
+ it "sets any ca_file into options[:ssl]" do
398
+ ca_file = :foo
399
+ Faraday.should_receive(:new).with(anything, hash_including(:ssl => hash_including(:ca_file => ca_file))).and_return(@mock_connection)
400
+ Koala::HTTPService.make_request("anything", {}, "get", :ca_file => ca_file)
401
+ end
402
+
403
+ it "deletes the ca_file key" do
404
+ ca_file = :foo
405
+ Faraday.should_receive(:new).with(anything, hash_not_including(:ca_file => ca_file)).and_return(@mock_connection)
406
+ Koala::HTTPService.make_request("anything", {}, "get", :ca_file => ca_file)
407
+ end
408
+ end
409
+
410
+ describe ":verify_mode" do
411
+ it "sets any verify_mode into options[:ssl]" do
412
+ verify_mode = :foo
413
+ Faraday.should_receive(:new).with(anything, hash_including(:ssl => hash_including(:verify_mode => verify_mode))).and_return(@mock_connection)
414
+ Koala::HTTPService.make_request("anything", {}, "get", :verify_mode => verify_mode)
415
+ end
416
+
417
+ it "deletes the verify_mode key" do
418
+ verify_mode = :foo
419
+ Faraday.should_receive(:new).with(anything, hash_not_including(:verify_mode => verify_mode)).and_return(@mock_connection)
420
+ Koala::HTTPService.make_request("anything", {}, "get", :verify_mode => verify_mode)
421
+ end
422
+ end
423
+ end
424
+
425
+ {
426
+ :typhoeus => Koala::TyphoeusService,
427
+ :net_http => Koala::NetHTTPService
428
+ }.each_pair do |adapter, module_class|
429
+ describe module_class.to_s do
430
+ it "should respond to deprecated_interface" do
431
+ module_class.should respond_to(:deprecated_interface)
432
+ end
433
+
434
+ it "should issue a deprecation warning" do
435
+ Koala::Utils.should_receive(:deprecate)
436
+ module_class.deprecated_interface
437
+ end
438
+
439
+ it "should set the default adapter to #{adapter}" do
440
+ module_class.deprecated_interface
441
+ Faraday.default_adapter.should == adapter
442
+ end
443
+ end
444
+ end
445
+ end
446
+ end