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,534 @@
1
+ shared_examples_for "Koala GraphAPI" do
2
+ # all Graph API instances should pass these tests, regardless of configuration
3
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
4
+
5
+ # API
6
+ it "never uses the rest api server" do
7
+ expect(Koala).to receive(:make_request).with(
8
+ anything,
9
+ anything,
10
+ anything,
11
+ hash_not_including(:rest_api => true)
12
+ ).and_return(Koala::HTTPService::Response.new(200, "", {}))
13
+
14
+ @api.api("anything")
15
+ end
16
+
17
+ # DATA
18
+
19
+ describe "#get_picture" do
20
+ it "can access a user's picture" do
21
+ expect(@api.get_picture(KoalaTest.user2)).to match(/https?\:\/\//)
22
+ end
23
+
24
+ it "can access a user's picture, given a picture type" do
25
+ expect(@api.get_picture(KoalaTest.user2, {:type => 'large'})).to match(/^https?\:\/\//)
26
+ end
27
+
28
+ it "works even if Facebook returns nil" do
29
+ allow(@api).to receive(:graph_call).and_return(nil)
30
+ expect(@api.get_picture(KoalaTest.user2, {:type => 'large'})).to be_nil
31
+ end
32
+ end
33
+
34
+ describe "#get_picture_data" do
35
+ it "can access a user's picture data" do
36
+ result = @api.get_picture_data(KoalaTest.user2)
37
+ expect(result).to be_kind_of(Hash)
38
+ expect(result["data"]).to be_kind_of(Hash)
39
+ expect(result['data']).to be_truthy
40
+ expect(result['data'].keys).to include('is_silhouette', 'url')
41
+ end
42
+ end
43
+
44
+ describe "#get_user_picture_data" do
45
+ it "can access a user's picture data" do
46
+ result = @api.get_picture_data(KoalaTest.user2)
47
+ expect(result).to be_kind_of(Hash)
48
+ expect(result["data"]).to be_kind_of(Hash)
49
+ expect(result['data']).to be_truthy
50
+ expect(result['data'].keys).to include('is_silhouette', 'url')
51
+ end
52
+ end
53
+
54
+ # PAGING THROUGH COLLECTIONS
55
+ # see also graph_collection_tests
56
+ it "makes a request for a page when provided a specific set of page params" do
57
+ query = [1, 2]
58
+ expect(@api).to receive(:graph_call).with(*query)
59
+ @api.get_page(query)
60
+ end
61
+ end
62
+
63
+
64
+ shared_examples_for "Koala GraphAPI with an access token" do
65
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
66
+
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
71
+ end
72
+
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
81
+ end
82
+ end
83
+
84
+ it "returns [] from get_objects if passed an empty array" do
85
+ results = @api.get_objects([])
86
+ expect(results).to eq([])
87
+ end
88
+
89
+ it "gets multiple objects" do
90
+ results = @api.get_objects([KoalaTest.page, KoalaTest.user1])
91
+ expect(results.size).to eq(2)
92
+ end
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
98
+
99
+ it "gets private data about a user" do
100
+ result = @api.get_object(KoalaTest.user1)
101
+ # updated_time should be a pretty fixed test case
102
+ expect(result["updated_time"]).not_to be_nil
103
+ end
104
+
105
+ it "gets data about 'me'" do
106
+ result = @api.get_object("me")
107
+ expect(result["updated_time"]).to be_truthy
108
+ end
109
+
110
+ it "gets multiple objects" do
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
130
+ end
131
+
132
+ it "can access connections from users" do
133
+ result = @api.get_connections(KoalaTest.user2, "likes")
134
+ expect(result.length).to be > 0
135
+ end
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
+
143
+ # PUT
144
+ it "can write an object to the graph" do
145
+ result = @api.put_wall_post("Hello, world, from the test suite!")
146
+ @temporary_object_id = result["id"]
147
+ expect(@temporary_object_id).not_to be_nil
148
+ end
149
+
150
+ # DELETE
151
+ it "can delete posts" do
152
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
153
+ object_id_to_delete = result["id"]
154
+ delete_result = @api.delete_object(object_id_to_delete)
155
+ expect(delete_result).to eq("success" => true)
156
+ end
157
+
158
+ it "can delete likes" do
159
+ result = @api.put_wall_post("Hello, world, from the test suite delete like method!")
160
+ @temporary_object_id = result["id"]
161
+ @api.put_like(@temporary_object_id)
162
+ delete_like_result = @api.delete_like(@temporary_object_id)
163
+ expect(delete_like_result).to eq("success" => true)
164
+ end
165
+
166
+ # additional put tests
167
+ it "can verify messages posted to a wall" do
168
+ message = "the cats are asleep"
169
+ put_result = @api.put_wall_post(message)
170
+ @temporary_object_id = put_result["id"]
171
+ get_result = @api.get_object(@temporary_object_id)
172
+
173
+ # make sure the message we sent is the message that got posted
174
+ expect(get_result["message"]).to eq(message)
175
+ end
176
+
177
+ it "can post a message with an attachment to a feed" do
178
+ result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "OAuth Playground", :link => "http://testdomain.koalatest.test/"})
179
+ @temporary_object_id = result["id"]
180
+ expect(@temporary_object_id).not_to be_nil
181
+ end
182
+
183
+ it "can post a message whose attachment has a properties dictionary" do
184
+ url = KoalaTest.oauth_test_data["callback_url"]
185
+ args = {
186
+ "picture" => "#{KoalaTest.oauth_test_data["callback_url"]}/images/logo.png",
187
+ "name" => "It's a big question",
188
+ "type" => "link",
189
+ "link" => KoalaTest.oauth_test_data["callback_url"],
190
+ "properties" => {
191
+ "Link1" => {"text" => "Left", "href" => url},
192
+ "other" => {"text" => "Straight ahead", "href" => url + "?"}
193
+ }
194
+ }
195
+
196
+ result = @api.put_wall_post("body", args)
197
+ @temporary_object_id = result["id"]
198
+ expect(@temporary_object_id).not_to be_nil
199
+
200
+ # ensure the properties dictionary is there
201
+ api_data = @api.get_object(@temporary_object_id)
202
+ expect(api_data["properties"]).not_to be_nil
203
+ end
204
+
205
+ describe "#put_picture" do
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") }
210
+
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
216
+
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
222
+
223
+ it "can verify a photo posted to a user's wall" do
224
+ expected_message = "This is the test message"
225
+
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
229
+
230
+ get_result = @api.get_object(@temporary_object_id)
231
+ expect(get_result["name"]).to eq(expected_message)
232
+ end
233
+
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
240
+ end
241
+
242
+ describe "using a URL instead of a file" do
243
+ let(:url) { "http://img.slate.com/images/redesign2008/slate_logo.gif" }
244
+
245
+ it "can post photo to the user's wall using a URL" do
246
+ result = @api.put_picture(url)
247
+ @temporary_object_id = result["id"]
248
+ expect(@temporary_object_id).not_to be_nil
249
+ end
250
+
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")
253
+ @temporary_object_id = result["id"]
254
+ expect(@temporary_object_id).not_to be_nil
255
+ end
256
+ end
257
+ end
258
+
259
+ describe "#put_video" do
260
+ let(:cat_movie) { File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v") }
261
+ let(:content_type) { "video/mpeg4" }
262
+
263
+ it "sets options[:video] to true" do
264
+ source = double("UploadIO")
265
+ allow(Koala::HTTPService::UploadableIO).to receive(:new).and_return(source)
266
+ allow(source).to receive(:requires_base_http_service).and_return(false)
267
+ expect(Koala).to receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::HTTPService::Response.new(200, "[]", {}))
268
+ @api.put_video("foo")
269
+ end
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
+
279
+ it "can post videos to the user's wall with an open file object" do
280
+ file = File.open(cat_movie)
281
+
282
+ result = @api.put_video(file, content_type)
283
+ @temporary_object_id = result["id"]
284
+ expect(@temporary_object_id).not_to be_nil
285
+ end
286
+
287
+ it "can post videos to the user's wall without an open file object" do
288
+ result = @api.put_video(cat_movie, content_type)
289
+ @temporary_object_id = result["id"]
290
+ expect(@temporary_object_id).not_to be_nil
291
+ end
292
+
293
+ # note: Facebook doesn't post videos immediately to the wall, due to processing time
294
+ # during which get_object(video_id) will return false
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" }
298
+
299
+ it "can post photo to the user's wall using aurl" do
300
+ result = @api.put_video(url)
301
+ @temporary_object_id = result["id"]
302
+ expect(@temporary_object_id).not_to be_nil
303
+ end
304
+
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")
307
+ @temporary_object_id = result["id"]
308
+ expect(@temporary_object_id).not_to be_nil
309
+ end
310
+ end
311
+ end
312
+
313
+ it "can verify a message with an attachment posted to a feed" do
314
+ attachment = {"name" => "OAuth Playground", "link" => "http://testdomain.koalatest.test/"}
315
+ result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
316
+ @temporary_object_id = result["id"]
317
+ get_result = @api.get_object(@temporary_object_id)
318
+
319
+ # make sure the result we fetch includes all the parameters we sent
320
+ it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
321
+ expect(it_matches).to be true
322
+ end
323
+
324
+ it "can comment on an object" do
325
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
326
+ @temporary_object_id = result["id"]
327
+
328
+ # this will be deleted when the post gets deleted
329
+ comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
330
+ expect(comment_result).not_to be_nil
331
+ end
332
+
333
+ it "can verify a comment posted about an object" do
334
+ message_text = "Hello, world, from the test suite, testing comments again!"
335
+ result = @api.put_wall_post(message_text)
336
+ @temporary_object_id = result["id"]
337
+
338
+ # this will be deleted when the post gets deleted
339
+ comment_text = "it's my comment!"
340
+ comment_result = @api.put_comment(@temporary_object_id, comment_text)
341
+ get_result = @api.get_object(comment_result["id"])
342
+
343
+ # make sure the text of the comment matches what we sent
344
+ expect(get_result["message"]).to eq(comment_text)
345
+ end
346
+
347
+ it "can like an object" do
348
+ result = @api.put_wall_post("Hello, world, from the test suite, testing liking!")
349
+ @temporary_object_id = result["id"]
350
+ app_api = Koala::Facebook::API.new(@app_access_token)
351
+ like_result = app_api.put_like(@temporary_object_id)
352
+ expect(like_result).to be_truthy
353
+ end
354
+
355
+ # Page Access Token Support
356
+ describe "#get_page_access_token" do
357
+ it "gets the page object with the access_token field" do
358
+ # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
359
+ expect(@api).to receive(:api).with("my_page", hash_including({:fields => "access_token"}), "get", anything).and_return(dummy_response)
360
+ @api.get_page_access_token("my_page")
361
+ end
362
+
363
+ it "merges in any other arguments" do
364
+ # we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
365
+ args = {:a => 3}
366
+ expect(@api).to receive(:api).with("my_page", hash_including(args), "get", anything).and_return(dummy_response)
367
+ @api.get_page_access_token("my_page", args)
368
+ end
369
+ end
370
+
371
+ it "can get information about an access token" do
372
+ result = @api.debug_token(KoalaTest.app_access_token)
373
+ expect(result).to be_kind_of(Hash)
374
+ expect(result["data"]).to be_kind_of(Hash)
375
+ expect(result["data"]["app_id"].to_s).to eq(KoalaTest.app_id.to_s)
376
+ expect(result["data"]["application"]).not_to be_nil
377
+ end
378
+
379
+ describe "#set_app_restrictions" do
380
+ before :all do
381
+ oauth = Koala::Facebook::OAuth.new(KoalaTest.app_id, KoalaTest.secret)
382
+ app_token = oauth.get_app_access_token
383
+ @app_api = Koala::Facebook::API.new(app_token)
384
+ @restrictions = {"age_distr" => "13+"}
385
+ end
386
+
387
+ it "makes a POST to /app_id" do
388
+ expect(@app_api).to receive(:graph_call).with(KoalaTest.app_id, anything, "post", anything)
389
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
390
+ end
391
+
392
+ it "JSON-encodes the restrictions" do
393
+ expect(@app_api).to receive(:graph_call).with(anything, hash_including(:restrictions => JSON.dump(@restrictions)), anything, anything)
394
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
395
+ end
396
+
397
+ it "includes the other arguments" do
398
+ args = {:a => 2}
399
+ expect(@app_api).to receive(:graph_call).with(anything, hash_including(args), anything, anything)
400
+ @app_api.set_app_restrictions(KoalaTest.app_id, @restrictions, args)
401
+ end
402
+
403
+ it "works" do
404
+ expect(@app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)).to be_truthy
405
+ end
406
+ end
407
+
408
+ # test all methods to make sure they pass data through to the API
409
+ # we run the tests here (rather than in the common shared example group)
410
+ # since some require access tokens
411
+ describe "HTTP options" do
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|
424
+ it "passes http options through for #{method_name}" do
425
+ params = @api.method(method_name).parameters
426
+ expect(params.last).to eq([:block, :block])
427
+ expect(params[-2]).to eq([:opt, :options])
428
+ end
429
+ end
430
+
431
+ # also test get_picture, which merges a parameter into options
432
+ it "passes http options through for get_picture" do
433
+ options = {:a => 2}
434
+ # graph call should ultimately receive options as the fourth argument
435
+ expect(@api).to receive(:graph_call).with(anything, anything, anything, hash_including(options)).and_return({})
436
+ @api.send(:get_picture, "x", {}, options)
437
+ end
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
447
+ end
448
+
449
+
450
+ # GraphCollection
451
+ shared_examples_for "Koala GraphAPI with GraphCollection" do
452
+ let(:dummy_response) { double("fake response", data: {}, status: 200, body: "", headers: {}) }
453
+
454
+ describe "when getting a collection" do
455
+ # GraphCollection methods
456
+ it "gets a GraphCollection when getting connections" do
457
+ @result = @api.get_connections(KoalaTest.page, "events")
458
+ expect(@result).to be_a(Koala::Facebook::API::GraphCollection)
459
+ end
460
+
461
+ it "returns nil if the get_collections call fails with nil" do
462
+ # this happens sometimes
463
+ expect(@api).to receive(:graph_call).and_return(nil)
464
+ expect(@api.get_connections(KoalaTest.page, "photos")).to be_nil
465
+ end
466
+
467
+ it "gets a GraphCollection when searching" do
468
+ result = @api.search("facebook", type: "page")
469
+ expect(result).to be_a(Koala::Facebook::API::GraphCollection)
470
+ end
471
+
472
+ it "returns nil if the search call fails with nil" do
473
+ # this happens sometimes
474
+ expect(@api).to receive(:graph_call).and_return(nil)
475
+ expect(@api.search("facebook", type: "page")).to be_nil
476
+ end
477
+
478
+ it "gets a GraphCollection when paging through results" do
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)
481
+ end
482
+
483
+ it "returns nil if the page call fails with nil" do
484
+ # this happens sometimes
485
+ expect(@api).to receive(:graph_call).and_return(nil)
486
+ expect(@api.get_page(["search", {"q"=>"facebook", "type" => "page", "limit"=>"25", "until"=> KoalaTest.search_time}])).to be_nil
487
+ end
488
+ end
489
+ end
490
+
491
+
492
+ shared_examples_for "Koala GraphAPI without an access token" do
493
+ it "can't get data about 'me'" do
494
+ expect { @api.get_object("me") }.to raise_error(Koala::Facebook::ClientError)
495
+ end
496
+
497
+ it "can't access connections from users" do
498
+ expect { @api.get_connections(KoalaTest.user2, "likes") }.to raise_error(Koala::Facebook::ClientError)
499
+ end
500
+
501
+ it "can't put an object" do
502
+ expect { @result = @api.put_connections(KoalaTest.user2, "feed", :message => "Hello, world") }.to raise_error(Koala::Facebook::AuthenticationError)
503
+ # legacy put_object syntax
504
+ expect { @result = @api.put_object(KoalaTest.user2, "feed", :message => "Hello, world") }.to raise_error(Koala::Facebook::AuthenticationError)
505
+ end
506
+
507
+ # these are not strictly necessary as the other put methods resolve to put_connections,
508
+ # but are here for completeness
509
+ it "can't post to a feed" do
510
+ expect(lambda do
511
+ attachment = {:name => "OAuth Playground", :link => "http://testdomain.koalatest.test/"}
512
+ @result = @api.put_wall_post("Hello, world", attachment, "facebook")
513
+ end).to raise_error(Koala::Facebook::AuthenticationError)
514
+ end
515
+
516
+ it "can't comment on an object" do
517
+ # random public post on the facebook wall
518
+ expect { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.to raise_error(Koala::Facebook::AuthenticationError)
519
+ end
520
+
521
+ it "can't like an object" do
522
+ expect { @api.put_like("7204941866_119776748033392") }.to raise_error(Koala::Facebook::AuthenticationError)
523
+ end
524
+
525
+ # DELETE
526
+ it "can't delete posts" do
527
+ # test post on the Ruby SDK Test application
528
+ expect { @result = @api.delete_object("115349521819193_113815981982767") }.to raise_error(Koala::Facebook::AuthenticationError)
529
+ end
530
+
531
+ it "can't delete a like" do
532
+ expect { @api.delete_like("7204941866_119776748033392") }.to raise_error(Koala::Facebook::AuthenticationError)
533
+ end
534
+ end