koala 2.4.0 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +32 -0
  3. data/Gemfile +5 -3
  4. data/ISSUE_TEMPLATE +25 -0
  5. data/PULL_REQUEST_TEMPLATE +11 -0
  6. data/changelog.md +161 -4
  7. data/code_of_conduct.md +64 -12
  8. data/koala.gemspec +5 -1
  9. data/lib/koala/api/batch_operation.rb +3 -6
  10. data/lib/koala/api/{graph_api.rb → graph_api_methods.rb} +29 -104
  11. data/lib/koala/api/graph_batch_api.rb +112 -65
  12. data/lib/koala/api/graph_collection.rb +19 -12
  13. data/lib/koala/api/graph_error_checker.rb +4 -3
  14. data/lib/koala/api.rb +65 -26
  15. data/lib/koala/configuration.rb +56 -0
  16. data/lib/koala/errors.rb +22 -2
  17. data/lib/koala/http_service/request.rb +133 -0
  18. data/lib/koala/http_service/response.rb +6 -4
  19. data/lib/koala/http_service/uploadable_io.rb +0 -5
  20. data/lib/koala/http_service.rb +29 -76
  21. data/lib/koala/oauth.rb +8 -8
  22. data/lib/koala/realtime_updates.rb +26 -21
  23. data/lib/koala/test_users.rb +9 -8
  24. data/lib/koala/version.rb +1 -1
  25. data/lib/koala.rb +7 -9
  26. data/readme.md +83 -109
  27. data/spec/cases/api_spec.rb +176 -69
  28. data/spec/cases/configuration_spec.rb +11 -0
  29. data/spec/cases/error_spec.rb +16 -3
  30. data/spec/cases/graph_api_batch_spec.rb +75 -44
  31. data/spec/cases/graph_api_spec.rb +15 -29
  32. data/spec/cases/graph_collection_spec.rb +47 -34
  33. data/spec/cases/graph_error_checker_spec.rb +31 -2
  34. data/spec/cases/http_service/request_spec.rb +250 -0
  35. data/spec/cases/http_service/response_spec.rb +24 -0
  36. data/spec/cases/http_service_spec.rb +126 -286
  37. data/spec/cases/koala_spec.rb +7 -5
  38. data/spec/cases/oauth_spec.rb +41 -2
  39. data/spec/cases/realtime_updates_spec.rb +51 -13
  40. data/spec/cases/test_users_spec.rb +56 -2
  41. data/spec/cases/uploadable_io_spec.rb +31 -31
  42. data/spec/fixtures/cat.m4v +0 -0
  43. data/spec/fixtures/facebook_data.yml +4 -6
  44. data/spec/fixtures/mock_facebook_responses.yml +41 -78
  45. data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
  46. data/spec/integration/graph_collection_spec.rb +8 -5
  47. data/spec/spec_helper.rb +2 -2
  48. data/spec/support/graph_api_shared_examples.rb +152 -337
  49. data/spec/support/koala_test.rb +11 -13
  50. data/spec/support/mock_http_service.rb +11 -14
  51. data/spec/support/uploadable_io_shared_examples.rb +4 -4
  52. metadata +47 -48
  53. data/.autotest +0 -12
  54. data/.travis.yml +0 -17
  55. data/Guardfile +0 -6
  56. data/autotest/discover.rb +0 -1
  57. data/lib/koala/api/rest_api.rb +0 -135
  58. data/lib/koala/http_service/multipart_request.rb +0 -41
  59. data/spec/cases/multipart_request_spec.rb +0 -65
  60. data/spec/support/rest_api_shared_examples.rb +0 -168
@@ -1,5 +1,6 @@
1
1
  shared_examples_for "Koala GraphAPI" do
2
2
  # all Graph API instances should pass these tests, regardless of configuration
3
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
3
4
 
4
5
  # API
5
6
  it "never uses the rest api server" do
@@ -13,80 +14,7 @@ shared_examples_for "Koala GraphAPI" do
13
14
  @api.api("anything")
14
15
  end
15
16
 
16
- # GRAPH CALL
17
- describe "graph_call" do
18
- it "passes all arguments to the api method" do
19
- user = KoalaTest.user1
20
- args = {}
21
- verb = 'get'
22
- opts = {:a => :b}
23
- expect(@api).to receive(:api).with(user, args, verb, opts)
24
- @api.graph_call(user, args, verb, opts)
25
- end
26
-
27
- it "throws an APIError if the result hash has an error key" do
28
- allow(Koala).to receive(:make_request).and_return(Koala::HTTPService::Response.new(500, '{"error": "An error occurred!"}', {}))
29
- expect { @api.graph_call(KoalaTest.user1, {}) }.to raise_exception(Koala::Facebook::APIError)
30
- end
31
-
32
- it "passes the results through GraphCollection.evaluate" do
33
- result = {}
34
- allow(@api).to receive(:api).and_return(result)
35
- expect(Koala::Facebook::GraphCollection).to receive(:evaluate).with(result, @api)
36
- @api.graph_call("/me")
37
- end
38
-
39
- it "returns the results of GraphCollection.evaluate" do
40
- expected = {}
41
- allow(@api).to receive(:api).and_return([])
42
- expect(Koala::Facebook::GraphCollection).to receive(:evaluate).and_return(expected)
43
- expect(@api.graph_call("/me")).to eq(expected)
44
- end
45
-
46
- it "returns the post_processing block's results if one is supplied" do
47
- other_result = [:a, 2, :three]
48
- block = Proc.new {|r| other_result}
49
- allow(@api).to receive(:api).and_return({})
50
- expect(@api.graph_call("/me", {}, "get", {}, &block)).to eq(other_result)
51
- end
52
- end
53
-
54
- # SEARCH
55
- it "can search" do
56
- result = @api.search("facebook")
57
- expect(result.length).to be_an(Integer)
58
- end
59
-
60
17
  # DATA
61
- # access public info
62
-
63
- # get_object
64
- it "gets public data about a user" do
65
- result = @api.get_object(KoalaTest.user1)
66
- # the results should have an ID and a name, among other things
67
- expect(result["id"] && result["name"]).not_to be_nil
68
- end
69
-
70
- it "gets public data about a Page" do
71
- result = @api.get_object(KoalaTest.page)
72
- # the results should have an ID and a name, among other things
73
- expect(result["id"] && result["name"]).to be_truthy
74
- end
75
-
76
- it "returns [] from get_objects if passed an empty array" do
77
- results = @api.get_objects([])
78
- expect(results).to eq([])
79
- end
80
-
81
- it "gets multiple objects" do
82
- results = @api.get_objects([KoalaTest.page, KoalaTest.user1])
83
- expect(results.size).to eq(2)
84
- end
85
-
86
- it "gets multiple objects if they're a string" do
87
- results = @api.get_objects("facebook,#{KoalaTest.user1}")
88
- expect(results.size).to eq(2)
89
- end
90
18
 
91
19
  describe "#get_picture" do
92
20
  it "can access a user's picture" do
@@ -123,27 +51,6 @@ shared_examples_for "Koala GraphAPI" do
123
51
  end
124
52
  end
125
53
 
126
- it "can access connections from public Pages" do
127
- result = @api.get_connections(KoalaTest.page, "photos")
128
- expect(result).to be_a(Array)
129
- end
130
-
131
- it "can access comments for a URL" do
132
- result = @api.get_comments_for_urls(["http://developers.facebook.com/blog/post/472"])
133
- expect(result["http://developers.facebook.com/blog/post/472"]).to be_truthy
134
- end
135
-
136
- it "can access comments for 2 URLs" do
137
- result = @api.get_comments_for_urls(["http://developers.facebook.com/blog/post/490", "http://developers.facebook.com/blog/post/472"])
138
- expect(result["http://developers.facebook.com/blog/post/490"] && result["http://developers.facebook.com/blog/post/472"]).to be_truthy
139
- end
140
-
141
- # SEARCH
142
- it "can search" do
143
- result = @api.search("facebook")
144
- expect(result.length).to be_an(Integer)
145
- end
146
-
147
54
  # PAGING THROUGH COLLECTIONS
148
55
  # see also graph_collection_tests
149
56
  it "makes a request for a page when provided a specific set of page params" do
@@ -151,74 +58,44 @@ shared_examples_for "Koala GraphAPI" do
151
58
  expect(@api).to receive(:graph_call).with(*query)
152
59
  @api.get_page(query)
153
60
  end
61
+ end
154
62
 
155
- # Beta tier
156
- it "can use the beta tier" do
157
- result = @api.get_object(KoalaTest.user1, {}, :beta => true)
158
- # the results should have an ID and a name, among other things
159
- expect(result["id"] && result["name"]).to be_truthy
160
- end
161
-
162
- # FQL
163
- describe "#fql_query" do
164
- it "makes a request to /fql" do
165
- expect(@api).to receive(:get_object).with("fql", anything, anything)
166
- @api.fql_query double('query string')
167
- end
168
63
 
169
- it "passes a query argument" do
170
- query = double('query string')
171
- expect(@api).to receive(:get_object).with(anything, hash_including(:q => query), anything)
172
- @api.fql_query(query)
173
- end
64
+ shared_examples_for "Koala GraphAPI with an access token" do
65
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
174
66
 
175
- it "passes on any other arguments provided" do
176
- args = {:a => 2}
177
- expect(@api).to receive(:get_object).with(anything, hash_including(args), anything)
178
- @api.fql_query("a query", args)
179
- end
67
+ it "gets public data about a user" do
68
+ result = @api.get_object(KoalaTest.user1)
69
+ # the results should have an ID and a name, among other things
70
+ expect(result["id"] && result["name"]).not_to be_nil
180
71
  end
181
72
 
182
- describe "#fql_multiquery" do
183
- it "makes a request to /fql" do
184
- expect(@api).to receive(:get_object).with("fql", anything, anything)
185
- @api.fql_multiquery 'query string'
186
- end
187
-
188
- it "passes a queries argument" do
189
- queries = double('query string')
190
- queries_json = "some JSON"
191
- allow(MultiJson).to receive(:dump).with(queries).and_return(queries_json)
192
-
193
- expect(@api).to receive(:get_object).with(anything, hash_including(:q => queries_json), anything)
194
- @api.fql_multiquery(queries)
73
+ it "gets public data about a Page" do
74
+ begin
75
+ Koala::Utils.level = 0
76
+ result = @api.get_object(KoalaTest.page)
77
+ # the results should have an ID and a name, among other things
78
+ expect(result["id"] && result["name"]).to be_truthy
79
+ ensure
80
+ Koala::Utils.level = Logger::ERROR
195
81
  end
82
+ end
196
83
 
197
- it "simplifies the response format" do
198
- raw_results = [
199
- {"name" => "query1", "fql_result_set" => [1, 2, 3]},
200
- {"name" => "query2", "fql_result_set" => [:a, :b, :c]}
201
- ]
202
- expected_results = {
203
- "query1" => [1, 2, 3],
204
- "query2" => [:a, :b, :c]
205
- }
206
-
207
- allow(@api).to receive(:get_object).and_return(raw_results)
208
- results = @api.fql_multiquery({:query => true})
209
- expect(results).to eq(expected_results)
210
- end
84
+ it "returns [] from get_objects if passed an empty array" do
85
+ results = @api.get_objects([])
86
+ expect(results).to eq([])
87
+ end
211
88
 
212
- it "passes on any other arguments provided" do
213
- args = {:a => 2}
214
- expect(@api).to receive(:get_object).with(anything, hash_including(args), anything)
215
- @api.fql_multiquery("a query", args)
216
- end
89
+ it "gets multiple objects" do
90
+ results = @api.get_objects([KoalaTest.page, KoalaTest.user1])
91
+ expect(results.size).to eq(2)
217
92
  end
218
- end
219
93
 
94
+ it "gets multiple objects if they're a string" do
95
+ results = @api.get_objects("facebook,#{KoalaTest.user1}")
96
+ expect(results.size).to eq(2)
97
+ end
220
98
 
221
- shared_examples_for "Koala GraphAPI with an access token" do
222
99
  it "gets private data about a user" do
223
100
  result = @api.get_object(KoalaTest.user1)
224
101
  # updated_time should be a pretty fixed test case
@@ -231,14 +108,38 @@ shared_examples_for "Koala GraphAPI with an access token" do
231
108
  end
232
109
 
233
110
  it "gets multiple objects" do
234
- result = @api.get_objects([KoalaTest.page, KoalaTest.user1])
235
- expect(result.length).to eq(2)
111
+ begin
112
+ Koala::Utils.level = 0
113
+ result = @api.get_objects([KoalaTest.page, KoalaTest.user1])
114
+ expect(result.length).to eq(2)
115
+ ensure
116
+ Koala::Utils.level = Logger::ERROR
117
+ end
118
+ end
119
+
120
+ it "can access connections from public Pages" do
121
+ result = @api.get_connections(KoalaTest.page, "events")
122
+ expect(result).to be_a(Array)
123
+ end
124
+
125
+ describe "#get_object_metadata" do
126
+ it "can access an object's metadata" do
127
+ result = @api.get_object_metadata(KoalaTest.user1)
128
+ expect(result["type"]).to eq("user")
129
+ end
236
130
  end
131
+
237
132
  it "can access connections from users" do
238
- result = @api.get_connections(KoalaTest.user2, "friends")
133
+ result = @api.get_connections(KoalaTest.user2, "likes")
239
134
  expect(result.length).to be > 0
240
135
  end
241
136
 
137
+ # SEARCH
138
+ it "can search" do
139
+ result = @api.search("facebook", type: "page")
140
+ expect(result.length).to be_an(Integer)
141
+ end
142
+
242
143
  # PUT
243
144
  it "can write an object to the graph" do
244
145
  result = @api.put_wall_post("Hello, world, from the test suite!")
@@ -251,7 +152,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
251
152
  result = @api.put_wall_post("Hello, world, from the test suite delete method!")
252
153
  object_id_to_delete = result["id"]
253
154
  delete_result = @api.delete_object(object_id_to_delete)
254
- expect(delete_result).to eq(true)
155
+ expect(delete_result).to eq("success" => true)
255
156
  end
256
157
 
257
158
  it "can delete likes" do
@@ -259,7 +160,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
259
160
  @temporary_object_id = result["id"]
260
161
  @api.put_like(@temporary_object_id)
261
162
  delete_like_result = @api.delete_like(@temporary_object_id)
262
- expect(delete_like_result).to eq(true)
163
+ expect(delete_like_result).to eq("success" => true)
263
164
  end
264
165
 
265
166
  # additional put tests
@@ -274,7 +175,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
274
175
  end
275
176
 
276
177
  it "can post a message with an attachment to a feed" do
277
- result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"})
178
+ result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "OAuth Playground", :link => "http://testdomain.koalatest.test/"})
278
179
  @temporary_object_id = result["id"]
279
180
  expect(@temporary_object_id).not_to be_nil
280
181
  end
@@ -302,52 +203,53 @@ shared_examples_for "Koala GraphAPI with an access token" do
302
203
  end
303
204
 
304
205
  describe "#put_picture" do
305
- it "can post photos to the user's wall with an open file object" do
306
- content_type = "image/jpg"
307
- file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
308
-
309
- result = @api.put_picture(file, content_type)
310
- @temporary_object_id = result["id"]
311
- expect(@temporary_object_id).not_to be_nil
312
- end
206
+ context "with a file object" do
207
+ let(:content_type) { "image/jpg" }
208
+ let(:file) { File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")) }
209
+ let(:file_path) { File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg") }
313
210
 
314
- it "can post photos to the user's wall without an open file object" do
315
- content_type = "image/jpg",
316
- file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
211
+ it "can post photos to the user's wall with an open file object" do
212
+ result = @api.put_picture(file, content_type)
213
+ @temporary_object_id = result["id"]
214
+ expect(@temporary_object_id).not_to be_nil
215
+ end
317
216
 
318
- result = @api.put_picture(file_path, content_type)
319
- @temporary_object_id = result["id"]
320
- expect(@temporary_object_id).not_to be_nil
321
- end
217
+ it "can post photos to the user's wall without an open file object" do
218
+ result = @api.put_picture(file_path, content_type)
219
+ @temporary_object_id = result["id"]
220
+ expect(@temporary_object_id).not_to be_nil
221
+ end
322
222
 
323
- it "can verify a photo posted to a user's wall" do
324
- content_type = "image/jpg",
325
- file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
223
+ it "can verify a photo posted to a user's wall" do
224
+ expected_message = "This is the test message"
326
225
 
327
- expected_message = "This is the test message"
226
+ result = @api.put_picture(file_path, content_type, :message => expected_message)
227
+ @temporary_object_id = result["id"]
228
+ expect(@temporary_object_id).not_to be_nil
328
229
 
329
- result = @api.put_picture(file_path, content_type, :message => expected_message)
330
- @temporary_object_id = result["id"]
331
- expect(@temporary_object_id).not_to be_nil
230
+ get_result = @api.get_object(@temporary_object_id)
231
+ expect(get_result["name"]).to eq(expected_message)
232
+ end
332
233
 
333
- get_result = @api.get_object(@temporary_object_id)
334
- expect(get_result["name"]).to eq(expected_message)
234
+ it "passes options and block through" do
235
+ opts = {a: 2}
236
+ block = Proc.new {}
237
+ expect(@api).to receive(:graph_call).with(anything, anything, anything, hash_including(opts), &block)
238
+ @api.put_picture(file_path, content_type, {:message => "my message"}, "target", opts, &block)
239
+ end
335
240
  end
336
241
 
337
-
338
242
  describe "using a URL instead of a file" do
339
- before :each do
340
- @url = "http://img.slate.com/images/redesign2008/slate_logo.gif"
341
- end
243
+ let(:url) { "http://img.slate.com/images/redesign2008/slate_logo.gif" }
342
244
 
343
245
  it "can post photo to the user's wall using a URL" do
344
- result = @api.put_picture(@url)
246
+ result = @api.put_picture(url)
345
247
  @temporary_object_id = result["id"]
346
248
  expect(@temporary_object_id).not_to be_nil
347
249
  end
348
250
 
349
- it "can post photo to the user's wall using a URL and an additional param" do
350
- result = @api.put_picture(@url, :message => "my message")
251
+ it "can post photo to the user's wall using aurl and an additional param" do
252
+ result = @api.put_picture(url, :message => "my message")
351
253
  @temporary_object_id = result["id"]
352
254
  expect(@temporary_object_id).not_to be_nil
353
255
  end
@@ -355,29 +257,35 @@ shared_examples_for "Koala GraphAPI with an access token" do
355
257
  end
356
258
 
357
259
  describe "#put_video" do
358
- before :each do
359
- @cat_movie = File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v")
360
- @content_type = "video/mpeg4"
361
- end
260
+ let(:cat_movie) { File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v") }
261
+ let(:content_type) { "video/mpeg4" }
362
262
 
363
263
  it "sets options[:video] to true" do
364
264
  source = double("UploadIO")
365
- allow(Koala::UploadableIO).to receive(:new).and_return(source)
265
+ allow(Koala::HTTPService::UploadableIO).to receive(:new).and_return(source)
366
266
  allow(source).to receive(:requires_base_http_service).and_return(false)
367
267
  expect(Koala).to receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::HTTPService::Response.new(200, "[]", {}))
368
268
  @api.put_video("foo")
369
269
  end
370
270
 
271
+ it "passes options and block through" do
272
+ opts = {a: 2}
273
+ block = Proc.new {}
274
+ expect(@api).to receive(:graph_call).with(anything, anything, anything, hash_including(opts), &block)
275
+ file = File.open(cat_movie)
276
+ @api.put_video(file, content_type, {}, "target", opts, &block)
277
+ end
278
+
371
279
  it "can post videos to the user's wall with an open file object" do
372
- file = File.open(@cat_movie)
280
+ file = File.open(cat_movie)
373
281
 
374
- result = @api.put_video(file, @content_type)
282
+ result = @api.put_video(file, content_type)
375
283
  @temporary_object_id = result["id"]
376
284
  expect(@temporary_object_id).not_to be_nil
377
285
  end
378
286
 
379
287
  it "can post videos to the user's wall without an open file object" do
380
- result = @api.put_video(@cat_movie, @content_type)
288
+ result = @api.put_video(cat_movie, content_type)
381
289
  @temporary_object_id = result["id"]
382
290
  expect(@temporary_object_id).not_to be_nil
383
291
  end
@@ -385,21 +293,17 @@ shared_examples_for "Koala GraphAPI with an access token" do
385
293
  # note: Facebook doesn't post videos immediately to the wall, due to processing time
386
294
  # during which get_object(video_id) will return false
387
295
  # hence we can't do the same verify test we do for photos
296
+ describe "using aurl instead of a file" do
297
+ let(:url) { "http://techslides.com/demos/sample-videos/small.mp4" }
388
298
 
389
-
390
- describe "using a URL instead of a file" do
391
- before :each do
392
- @url = "http://techslides.com/demos/sample-videos/small.mp4"
393
- end
394
-
395
- it "can post photo to the user's wall using a URL" do
396
- result = @api.put_video(@url)
299
+ it "can post photo to the user's wall using aurl" do
300
+ result = @api.put_video(url)
397
301
  @temporary_object_id = result["id"]
398
302
  expect(@temporary_object_id).not_to be_nil
399
303
  end
400
304
 
401
- it "can post photo to the user's wall using a URL and an additional param" do
402
- result = @api.put_video(@url, :description => "my message")
305
+ it "can post photo to the user's wall using aurl and an additional param" do
306
+ result = @api.put_video(url, :description => "my message")
403
307
  @temporary_object_id = result["id"]
404
308
  expect(@temporary_object_id).not_to be_nil
405
309
  end
@@ -407,14 +311,14 @@ shared_examples_for "Koala GraphAPI with an access token" do
407
311
  end
408
312
 
409
313
  it "can verify a message with an attachment posted to a feed" do
410
- attachment = {"name" => "OAuth Playground", "link" => "http://oauth.twoalex.com/"}
314
+ attachment = {"name" => "OAuth Playground", "link" => "http://testdomain.koalatest.test/"}
411
315
  result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
412
316
  @temporary_object_id = result["id"]
413
317
  get_result = @api.get_object(@temporary_object_id)
414
318
 
415
319
  # make sure the result we fetch includes all the parameters we sent
416
320
  it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
417
- expect(it_matches).to eq(true)
321
+ expect(it_matches).to be true
418
322
  end
419
323
 
420
324
  it "can comment on an object" do
@@ -443,7 +347,8 @@ shared_examples_for "Koala GraphAPI with an access token" do
443
347
  it "can like an object" do
444
348
  result = @api.put_wall_post("Hello, world, from the test suite, testing liking!")
445
349
  @temporary_object_id = result["id"]
446
- like_result = @api.put_like(@temporary_object_id)
350
+ app_api = Koala::Facebook::API.new(@app_access_token)
351
+ like_result = app_api.put_like(@temporary_object_id)
447
352
  expect(like_result).to be_truthy
448
353
  end
449
354
 
@@ -451,14 +356,14 @@ shared_examples_for "Koala GraphAPI with an access token" do
451
356
  describe "#get_page_access_token" do
452
357
  it "gets the page object with the access_token field" do
453
358
  # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
454
- expect(@api).to receive(:api).with("my_page", hash_including({:fields => "access_token"}), "get", anything)
359
+ expect(@api).to receive(:api).with("my_page", hash_including({:fields => "access_token"}), "get", anything).and_return(dummy_response)
455
360
  @api.get_page_access_token("my_page")
456
361
  end
457
362
 
458
363
  it "merges in any other arguments" do
459
364
  # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
460
365
  args = {:a => 3}
461
- expect(@api).to receive(:api).with("my_page", hash_including(args), "get", anything)
366
+ expect(@api).to receive(:api).with("my_page", hash_including(args), "get", anything).and_return(dummy_response)
462
367
  @api.get_page_access_token("my_page", args)
463
368
  end
464
369
  end
@@ -485,7 +390,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
485
390
  end
486
391
 
487
392
  it "JSON-encodes the restrictions" do
488
- expect(@app_api).to receive(:graph_call).with(anything, hash_including(:restrictions => MultiJson.dump(@restrictions)), anything, anything)
393
+ expect(@app_api).to receive(:graph_call).with(anything, hash_including(:restrictions => JSON.dump(@restrictions)), anything, anything)
489
394
  @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
490
395
  end
491
396
 
@@ -500,87 +405,26 @@ shared_examples_for "Koala GraphAPI with an access token" do
500
405
  end
501
406
  end
502
407
 
503
- it "can access public information via FQL" do
504
- result = @api.fql_query("select uid, first_name from user where uid = #{KoalaTest.user2_id}")
505
- expect(result.size).to eq(1)
506
- expect(result.first['first_name']).to eq(KoalaTest.user2_name)
507
- expect(result.first['uid']).to eq(KoalaTest.user2_id.to_i)
508
- end
509
-
510
- it "can access public information via FQL.multiquery" do
511
- result = @api.fql_multiquery(
512
- :query1 => "select uid, first_name from user where uid = #{KoalaTest.user2_id}",
513
- :query2 => "select uid, first_name from user where uid = #{KoalaTest.user1_id}"
514
- )
515
- expect(result.size).to eq(2)
516
- # this should check for first_name, but there's an FB bug currently
517
- expect(result["query1"].first['uid']).to eq(KoalaTest.user2_id.to_i)
518
- # result["query1"].first['first_name'].should == KoalaTest.user2_name
519
- expect(result["query2"].first['first_name']).to eq(KoalaTest.user1_name)
520
- end
521
-
522
- it "can access protected information via FQL" do
523
- # Tests agains the permissions fql table
524
-
525
- # get the current user's ID
526
- # we're sneakily using the Graph API, which should be okay since it has its own tests
527
- g = Koala::Facebook::API.new(@token)
528
- id = g.get_object("me", :fields => "id")["id"]
529
-
530
- # now send a query about your permissions
531
- result = @api.fql_query("select read_stream from permissions where uid = #{id}")
532
-
533
- expect(result.size).to eq(1)
534
- # we've verified that you have read_stream permissions, so we can test against that
535
- expect(result.first["read_stream"]).to eq(1)
536
- end
537
-
538
- it "can access protected information via FQL.multiquery" do
539
- result = @api.fql_multiquery(
540
- :query1 => "select post_id from stream where source_id = me()",
541
- :query2 => "select fromid from comment where post_id in (select post_id from #query1)",
542
- :query3 => "select uid, name from user where uid in (select fromid from #query2)"
543
- )
544
- expect(result.size).to eq(3)
545
- expect(result.keys).to include("query1", "query2", "query3")
546
- end
547
-
548
408
  # test all methods to make sure they pass data through to the API
549
409
  # we run the tests here (rather than in the common shared example group)
550
410
  # since some require access tokens
551
411
  describe "HTTP options" do
552
- # Each of the below methods should take an options hash as their last argument
553
- # ideally we'd use introspection to determine how many arguments a method has
554
- # but some methods require specially formatted arguments for processing
555
- # (and anyway, Ruby 1.8's arity method fails (for this) for methods w/ 2+ optional arguments)
556
- # (Ruby 1.9's parameters method is perfect, but only in 1.9)
557
- # so we have to double-document
558
- {
559
- :get_object => 3, :put_object => 4, :delete_object => 2,
560
- :get_connections => 4, :put_connections => 4, :delete_connections => 4,
561
- :put_wall_post => 4,
562
- :put_comment => 3,
563
- :put_like => 2, :delete_like => 2,
564
- :search => 3,
565
- :set_app_restrictions => 4,
566
- :get_page_access_token => 3,
567
- :fql_query => 3, :fql_multiquery => 3,
568
- # methods that have special arguments
569
- :get_comments_for_urls => [["url1", "url2"], {}],
570
- :put_picture => ["x.jpg", "image/jpg", {}, "me"],
571
- :put_video => ["x.mp4", "video/mpeg4", {}, "me"],
572
- :get_objects => [["x"], {}]
573
- }.each_pair do |method_name, params|
412
+ # Each of the below methods should take an options hash as their last argument.
413
+ [
414
+ :get_object,
415
+ :get_connections,
416
+ :put_wall_post,
417
+ :put_comment,
418
+ :put_like,
419
+ :search,
420
+ :set_app_restrictions,
421
+ :get_page_access_token,
422
+ :get_objects
423
+ ].each do |method_name|
574
424
  it "passes http options through for #{method_name}" do
575
- options = {:a => 2}
576
- # graph call should ultimately receive options as the fourth argument
577
- expect(@api).to receive(:graph_call).with(anything, anything, anything, options)
578
-
579
- # if we supply args, use them (since some methods process params)
580
- # the method should receive as args n-1 anythings and then options
581
- args = (params.is_a?(Integer) ? ([{}] * (params - 1)) : params) + [options]
582
-
583
- @api.send(method_name, *args)
425
+ params = @api.method(method_name).parameters
426
+ expect(params.last).to eq([:block, :block])
427
+ expect(params[-2]).to eq([:opt, :options])
584
428
  end
585
429
  end
586
430
 
@@ -592,16 +436,26 @@ shared_examples_for "Koala GraphAPI with an access token" do
592
436
  @api.send(:get_picture, "x", {}, options)
593
437
  end
594
438
  end
439
+
440
+ # Beta tier
441
+ # In theory this is usable by both but so few operations now allow access without a token
442
+ it "can use the beta tier" do
443
+ result = @api.get_object(KoalaTest.user1, {}, :beta => true)
444
+ # the results should have an ID and a name, among other things
445
+ expect(result["id"] && result["name"]).to be_truthy
446
+ end
595
447
  end
596
448
 
597
449
 
598
450
  # GraphCollection
599
451
  shared_examples_for "Koala GraphAPI with GraphCollection" do
452
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
453
+
600
454
  describe "when getting a collection" do
601
455
  # GraphCollection methods
602
456
  it "gets a GraphCollection when getting connections" do
603
- @result = @api.get_connections(KoalaTest.page, "photos")
604
- expect(@result).to be_a(Koala::Facebook::GraphCollection)
457
+ @result = @api.get_connections(KoalaTest.page, "events")
458
+ expect(@result).to be_a(Koala::Facebook::API::GraphCollection)
605
459
  end
606
460
 
607
461
  it "returns nil if the get_collections call fails with nil" do
@@ -611,43 +465,37 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
611
465
  end
612
466
 
613
467
  it "gets a GraphCollection when searching" do
614
- result = @api.search("facebook")
615
- expect(result).to be_a(Koala::Facebook::GraphCollection)
468
+ result = @api.search("facebook", type: "page")
469
+ expect(result).to be_a(Koala::Facebook::API::GraphCollection)
616
470
  end
617
471
 
618
472
  it "returns nil if the search call fails with nil" do
619
473
  # this happens sometimes
620
474
  expect(@api).to receive(:graph_call).and_return(nil)
621
- expect(@api.search("facebook")).to be_nil
475
+ expect(@api.search("facebook", type: "page")).to be_nil
622
476
  end
623
477
 
624
478
  it "gets a GraphCollection when paging through results" do
625
- @results = @api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=> KoalaTest.search_time}])
626
- expect(@results).to be_a(Koala::Facebook::GraphCollection)
479
+ @results = @api.get_page(["search", {"q"=>"facebook", "type" => "page", "limit"=>"25", "until"=> KoalaTest.search_time}])
480
+ expect(@results).to be_a(Koala::Facebook::API::GraphCollection)
627
481
  end
628
482
 
629
483
  it "returns nil if the page call fails with nil" do
630
484
  # this happens sometimes
631
485
  expect(@api).to receive(:graph_call).and_return(nil)
632
- expect(@api.get_page(["search", {"q"=>"facebook", "limit"=>"25", "until"=> KoalaTest.search_time}])).to be_nil
486
+ expect(@api.get_page(["search", {"q"=>"facebook", "type" => "page", "limit"=>"25", "until"=> KoalaTest.search_time}])).to be_nil
633
487
  end
634
488
  end
635
489
  end
636
490
 
637
491
 
638
492
  shared_examples_for "Koala GraphAPI without an access token" do
639
- it "can't get private data about a user" do
640
- result = @api.get_object(KoalaTest.user1)
641
- # updated_time should be a pretty fixed test case
642
- expect(result["updated_time"]).to be_nil
643
- end
644
-
645
493
  it "can't get data about 'me'" do
646
494
  expect { @api.get_object("me") }.to raise_error(Koala::Facebook::ClientError)
647
495
  end
648
496
 
649
497
  it "can't access connections from users" do
650
- expect { @api.get_connections(KoalaTest.user2, "friends") }.to raise_error(Koala::Facebook::ClientError)
498
+ expect { @api.get_connections(KoalaTest.user2, "likes") }.to raise_error(Koala::Facebook::ClientError)
651
499
  end
652
500
 
653
501
  it "can't put an object" do
@@ -660,7 +508,7 @@ shared_examples_for "Koala GraphAPI without an access token" do
660
508
  # but are here for completeness
661
509
  it "can't post to a feed" do
662
510
  expect(lambda do
663
- attachment = {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"}
511
+ attachment = {:name => "OAuth Playground", :link => "http://testdomain.koalatest.test/"}
664
512
  @result = @api.put_wall_post("Hello, world", attachment, "facebook")
665
513
  end).to raise_error(Koala::Facebook::AuthenticationError)
666
514
  end
@@ -683,37 +531,4 @@ shared_examples_for "Koala GraphAPI without an access token" do
683
531
  it "can't delete a like" do
684
532
  expect { @api.delete_like("7204941866_119776748033392") }.to raise_error(Koala::Facebook::AuthenticationError)
685
533
  end
686
-
687
- # FQL_QUERY
688
- describe "when making a FQL request" do
689
- it "can access public information via FQL" do
690
- result = @api.fql_query("select uid, first_name from user where uid = #{KoalaTest.user2_id}")
691
- expect(result.size).to eq(1)
692
- expect(result.first['first_name']).to eq(KoalaTest.user2_name)
693
- end
694
-
695
- it "can access public information via FQL.multiquery" do
696
- result = @api.fql_multiquery(
697
- :query1 => "select uid, first_name from user where uid = #{KoalaTest.user2_id}",
698
- :query2 => "select uid, first_name from user where uid = #{KoalaTest.user1_id}"
699
- )
700
- expect(result.size).to eq(2)
701
- expect(result["query1"].first['first_name']).to eq(KoalaTest.user2_name)
702
- expect(result["query2"].first['first_name']).to eq(KoalaTest.user1_name)
703
- end
704
-
705
- it "can't access protected information via FQL" do
706
- expect { @api.fql_query("select read_stream from permissions where uid = #{KoalaTest.user2_id}") }.to raise_error(Koala::Facebook::APIError)
707
- end
708
-
709
- it "can't access protected information via FQL.multiquery" do
710
- expect {
711
- @api.fql_multiquery(
712
- :query1 => "select post_id from stream where source_id = me()",
713
- :query2 => "select fromid from comment where post_id in (select post_id from #query1)",
714
- :query3 => "select uid, name from user where uid in (select fromid from #query2)"
715
- )
716
- }.to raise_error(Koala::Facebook::APIError)
717
- end
718
- end
719
534
  end