koala 1.1.0 → 1.2.0beta1

Sign up to get free protection for your applications and to get access to all the features.
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