koala 1.1.0 → 1.2.0beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -1
- data/CHANGELOG +26 -0
- data/Gemfile +6 -2
- data/Rakefile +0 -1
- data/koala.gemspec +8 -8
- data/lib/koala.rb +42 -45
- data/lib/koala/batch_operation.rb +15 -15
- data/lib/koala/graph_api.rb +81 -58
- data/lib/koala/graph_batch_api.rb +10 -10
- data/lib/koala/graph_collection.rb +6 -6
- data/lib/koala/http_service.rb +177 -0
- data/lib/koala/oauth.rb +2 -2
- data/lib/koala/realtime_updates.rb +20 -17
- data/lib/koala/rest_api.rb +1 -1
- data/lib/koala/test_users.rb +33 -16
- data/lib/koala/uploadable_io.rb +47 -42
- data/lib/koala/utils.rb +11 -0
- data/readme.md +38 -38
- data/spec/cases/api_base_spec.rb +2 -2
- data/spec/cases/error_spec.rb +32 -0
- data/spec/cases/graph_and_rest_api_spec.rb +20 -3
- data/spec/cases/graph_api_batch_spec.rb +88 -97
- data/spec/cases/graph_api_spec.rb +21 -4
- data/spec/cases/http_service_spec.rb +446 -0
- data/spec/cases/koala_spec.rb +33 -38
- data/spec/cases/oauth_spec.rb +219 -200
- data/spec/cases/realtime_updates_spec.rb +45 -31
- data/spec/cases/rest_api_spec.rb +23 -7
- data/spec/cases/test_users_spec.rb +112 -52
- data/spec/cases/uploadable_io_spec.rb +49 -36
- data/spec/cases/utils_spec.rb +10 -0
- data/spec/fixtures/facebook_data.yml +23 -22
- data/spec/fixtures/mock_facebook_responses.yml +126 -96
- data/spec/spec_helper.rb +29 -5
- data/spec/support/graph_api_shared_examples.rb +59 -52
- data/spec/support/json_testing_fix.rb +35 -11
- data/spec/support/koala_test.rb +163 -0
- data/spec/support/mock_http_service.rb +6 -4
- data/spec/support/ordered_hash.rb +205 -0
- data/spec/support/rest_api_shared_examples.rb +37 -37
- data/spec/support/uploadable_io_shared_examples.rb +2 -8
- metadata +78 -79
- data/lib/koala/http_services.rb +0 -46
- data/lib/koala/http_services/net_http_service.rb +0 -92
- data/lib/koala/http_services/typhoeus_service.rb +0 -37
- data/spec/cases/http_services/http_service_spec.rb +0 -129
- data/spec/cases/http_services/net_http_service_spec.rb +0 -532
- data/spec/cases/http_services/typhoeus_service_spec.rb +0 -152
- data/spec/support/live_testing_data_helper.rb +0 -40
- data/spec/support/setup_mocks_or_live.rb +0 -51
data/spec/spec_helper.rb
CHANGED
@@ -4,16 +4,40 @@ rescue LoadError
|
|
4
4
|
puts 'Although not required, bundler is recommended for running the tests.'
|
5
5
|
end
|
6
6
|
|
7
|
-
#
|
7
|
+
# In Ruby 1.9.2 versions before patchlevel 290, the default Psych
|
8
|
+
# parser has an issue with YAML merge keys, which
|
9
|
+
# fixtures/mock_facebook_responses.yml relies heavily on.
|
10
|
+
#
|
11
|
+
# Anyone using an earlier version will see missing mock response
|
12
|
+
# errors when running the test suite similar to this:
|
13
|
+
#
|
14
|
+
# RuntimeError:
|
15
|
+
# Missing a mock response for graph_api: /me/videos: source=[FILE]: post: with_token
|
16
|
+
# API PATH: /me/videos?source=[FILE]&format=json&access_token=*
|
17
|
+
#
|
18
|
+
# For now, it seems the best fix is to just downgrade to the old syck YAML parser
|
19
|
+
# for these troubled versions.
|
20
|
+
#
|
21
|
+
# See https://github.com/tenderlove/psych/issues/8 for more details
|
22
|
+
YAML::ENGINE.yamler = 'syck' if RUBY_VERSION == '1.9.2' && RUBY_PATCHLEVEL < 290
|
23
|
+
|
24
|
+
# load the library
|
8
25
|
require 'koala'
|
9
26
|
|
10
|
-
#
|
11
|
-
|
12
|
-
require 'support/
|
27
|
+
# ensure consistent to_json behavior
|
28
|
+
# this must be required first so mock_http_service loads the YAML as expected
|
29
|
+
require 'support/ordered_hash'
|
30
|
+
require 'support/json_testing_fix'
|
31
|
+
|
32
|
+
# set up our testing environment
|
13
33
|
require 'support/mock_http_service'
|
34
|
+
require 'support/koala_test'
|
35
|
+
# load testing data and (if needed) create test users or validate real users
|
36
|
+
KoalaTest.setup_test_environment!
|
37
|
+
|
38
|
+
# load supporting files for our tests
|
14
39
|
require 'support/rest_api_shared_examples'
|
15
40
|
require 'support/graph_api_shared_examples'
|
16
41
|
require 'support/uploadable_io_shared_examples'
|
17
|
-
require 'support/setup_mocks_or_live'
|
18
42
|
|
19
43
|
BEACH_BALL_PATH = File.join(File.dirname(__FILE__), "fixtures", "beach.jpg")
|
@@ -16,7 +16,7 @@ shared_examples_for "Koala GraphAPI" do
|
|
16
16
|
# GRAPH CALL
|
17
17
|
describe "graph_call" do
|
18
18
|
it "should pass all arguments to the api method" do
|
19
|
-
args = [
|
19
|
+
args = [KoalaTest.user1, {}, "get", {:a => :b}]
|
20
20
|
|
21
21
|
@api.should_receive(:api).with(*args)
|
22
22
|
|
@@ -25,7 +25,7 @@ shared_examples_for "Koala GraphAPI" do
|
|
25
25
|
|
26
26
|
it "should throw an APIError if the result hash has an error key" do
|
27
27
|
Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
|
28
|
-
lambda { @api.graph_call(
|
28
|
+
lambda { @api.graph_call(KoalaTest.user1, {}) }.should raise_exception(Koala::Facebook::APIError)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -40,13 +40,13 @@ shared_examples_for "Koala GraphAPI" do
|
|
40
40
|
|
41
41
|
# get_object
|
42
42
|
it "should get public data about a user" do
|
43
|
-
result = @api.get_object(
|
43
|
+
result = @api.get_object(KoalaTest.user1)
|
44
44
|
# the results should have an ID and a name, among other things
|
45
45
|
(result["id"] && result["name"]).should_not be_nil
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should get public data about a Page" do
|
49
|
-
result = @api.get_object(
|
49
|
+
result = @api.get_object(KoalaTest.page)
|
50
50
|
# the results should have an ID and a name, among other things
|
51
51
|
(result["id"] && result["name"]).should
|
52
52
|
end
|
@@ -55,14 +55,14 @@ shared_examples_for "Koala GraphAPI" do
|
|
55
55
|
results = @api.get_objects([])
|
56
56
|
results.should == []
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
it "should be able to get multiple objects" do
|
60
|
-
results = @api.get_objects([
|
60
|
+
results = @api.get_objects([KoalaTest.page, KoalaTest.user1])
|
61
61
|
results.should have(2).items
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should be able to get multiple objects if they're a string" do
|
65
|
-
results = @api.get_objects("contextoptional
|
65
|
+
results = @api.get_objects("contextoptional,#{KoalaTest.user1}")
|
66
66
|
results.should have(2).items
|
67
67
|
end
|
68
68
|
|
@@ -71,11 +71,11 @@ shared_examples_for "Koala GraphAPI" do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should be able to access a user's picture, given a picture type" do
|
74
|
-
@api.get_picture(
|
74
|
+
@api.get_picture(KoalaTest.user2, {:type => 'large'}).should =~ /^http[s]*\:\/\//
|
75
75
|
end
|
76
76
|
|
77
77
|
it "should be able to access connections from public Pages" do
|
78
|
-
result = @api.get_connections(
|
78
|
+
result = @api.get_connections(KoalaTest.page, "photos")
|
79
79
|
result.should be_a(Array)
|
80
80
|
end
|
81
81
|
|
@@ -107,7 +107,7 @@ end
|
|
107
107
|
|
108
108
|
shared_examples_for "Koala GraphAPI with an access token" do
|
109
109
|
it "should get private data about a user" do
|
110
|
-
result = @api.get_object(
|
110
|
+
result = @api.get_object(KoalaTest.user1)
|
111
111
|
# updated_time should be a pretty fixed test case
|
112
112
|
result["updated_time"].should_not be_nil
|
113
113
|
end
|
@@ -118,11 +118,11 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
118
118
|
end
|
119
119
|
|
120
120
|
it "should be able to get multiple objects" do
|
121
|
-
result = @api.get_objects([
|
121
|
+
result = @api.get_objects([KoalaTest.page, KoalaTest.user1])
|
122
122
|
result.length.should == 2
|
123
123
|
end
|
124
124
|
it "should be able to access connections from users" do
|
125
|
-
result = @api.get_connections(
|
125
|
+
result = @api.get_connections(KoalaTest.user2, "friends")
|
126
126
|
result.length.should > 0
|
127
127
|
end
|
128
128
|
|
@@ -168,52 +168,63 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
168
168
|
|
169
169
|
describe ".put_picture" do
|
170
170
|
it "should be able to post photos to the user's wall with an open file object" do
|
171
|
-
content_type = "image/jpg"
|
171
|
+
content_type = "image/jpg"
|
172
172
|
file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
|
173
|
-
|
173
|
+
|
174
174
|
result = @api.put_picture(file, content_type)
|
175
|
-
@temporary_object_id = result["id"]
|
175
|
+
@temporary_object_id = result["id"]
|
176
176
|
@temporary_object_id.should_not be_nil
|
177
177
|
end
|
178
178
|
|
179
|
-
it "uses the base HTTP service if the upload is a StringIO or similar" do
|
180
|
-
source = stub("UploadIO")
|
181
|
-
Koala::UploadableIO.stub(:new).and_return(source)
|
182
|
-
source.stub(:requires_base_http_service).and_return(true)
|
183
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:http_service => Koala.base_http_service)).and_return(Koala::Response.new(200, "[]", {}))
|
184
|
-
@api.put_picture(StringIO.new)
|
185
|
-
end
|
186
|
-
|
187
179
|
it "should be able to post photos to the user's wall without an open file object" do
|
188
180
|
content_type = "image/jpg",
|
189
181
|
file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
|
190
|
-
|
182
|
+
|
191
183
|
result = @api.put_picture(file_path, content_type)
|
192
|
-
@temporary_object_id = result["id"]
|
184
|
+
@temporary_object_id = result["id"]
|
193
185
|
@temporary_object_id.should_not be_nil
|
194
186
|
end
|
195
|
-
|
187
|
+
|
196
188
|
it "should be able to verify a photo posted to a user's wall" do
|
197
189
|
content_type = "image/jpg",
|
198
190
|
file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
|
199
|
-
|
191
|
+
|
200
192
|
expected_message = "This is the test message"
|
201
|
-
|
193
|
+
|
202
194
|
result = @api.put_picture(file_path, content_type, :message => expected_message)
|
203
|
-
@temporary_object_id = result["id"]
|
195
|
+
@temporary_object_id = result["id"]
|
204
196
|
@temporary_object_id.should_not be_nil
|
205
|
-
|
197
|
+
|
206
198
|
get_result = @api.get_object(@temporary_object_id)
|
207
199
|
get_result["name"].should == expected_message
|
208
200
|
end
|
201
|
+
|
202
|
+
|
203
|
+
describe "using a URL instead of a file" do
|
204
|
+
before :each do
|
205
|
+
@url = "http://img.slate.com/images/redesign2008/slate_logo.gif"
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should be able to post photo to the user's wall using a URL" do
|
209
|
+
result = @api.put_picture(@url)
|
210
|
+
@temporary_object_id = result["id"]
|
211
|
+
@temporary_object_id.should_not be_nil
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should be able to post photo to the user's wall using a URL and an additional param" do
|
215
|
+
result = @api.put_picture(@url, :message => "my message")
|
216
|
+
@temporary_object_id = result["id"]
|
217
|
+
@temporary_object_id.should_not be_nil
|
218
|
+
end
|
219
|
+
end
|
209
220
|
end
|
210
|
-
|
221
|
+
|
211
222
|
describe ".put_video" do
|
212
223
|
before :each do
|
213
|
-
@cat_movie = File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v")
|
214
|
-
@content_type = "video/mpeg4"
|
224
|
+
@cat_movie = File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v")
|
225
|
+
@content_type = "video/mpeg4"
|
215
226
|
end
|
216
|
-
|
227
|
+
|
217
228
|
it "should set options[:video] to true" do
|
218
229
|
source = stub("UploadIO")
|
219
230
|
Koala::UploadableIO.stub(:new).and_return(source)
|
@@ -221,26 +232,19 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
221
232
|
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::Response.new(200, "[]", {}))
|
222
233
|
@api.put_video("foo")
|
223
234
|
end
|
224
|
-
|
235
|
+
|
225
236
|
it "should be able to post videos to the user's wall with an open file object" do
|
226
237
|
file = File.open(@cat_movie)
|
227
238
|
|
228
239
|
result = @api.put_video(file, @content_type)
|
229
|
-
@temporary_object_id = result["id"]
|
240
|
+
@temporary_object_id = result["id"]
|
230
241
|
@temporary_object_id.should_not be_nil
|
231
242
|
end
|
232
243
|
|
233
|
-
it "uses the base HTTP service if the upload is a StringIO or similar" do
|
234
|
-
source = stub("UploadIO")
|
235
|
-
Koala::UploadableIO.stub(:new).and_return(source)
|
236
|
-
source.stub(:requires_base_http_service).and_return(true)
|
237
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:http_service => Koala.base_http_service)).and_return(Koala::Response.new(200, "[]", {}))
|
238
|
-
@api.put_video(StringIO.new)
|
239
|
-
end
|
240
244
|
|
241
245
|
it "should be able to post videos to the user's wall without an open file object" do
|
242
246
|
result = @api.put_video(@cat_movie, @content_type)
|
243
|
-
@temporary_object_id = result["id"]
|
247
|
+
@temporary_object_id = result["id"]
|
244
248
|
@temporary_object_id.should_not be_nil
|
245
249
|
end
|
246
250
|
|
@@ -290,6 +294,12 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
290
294
|
like_result.should be_true
|
291
295
|
end
|
292
296
|
|
297
|
+
# Page Access Token Support
|
298
|
+
it "gets a page's access token" do
|
299
|
+
# we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
|
300
|
+
@api.should_receive(:api).with("my_page", {:fields => "access_token"}, "get", anything)
|
301
|
+
@api.get_page_access_token("my_page")
|
302
|
+
end
|
293
303
|
|
294
304
|
# test all methods to make sure they pass data through to the API
|
295
305
|
# we run the tests here (rather than in the common shared example group)
|
@@ -348,14 +358,14 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
|
|
348
358
|
describe "when getting a collection" do
|
349
359
|
# GraphCollection methods
|
350
360
|
it "should get a GraphCollection when getting connections" do
|
351
|
-
@result = @api.get_connections(
|
361
|
+
@result = @api.get_connections(KoalaTest.page, "photos")
|
352
362
|
@result.should be_a(Koala::Facebook::GraphCollection)
|
353
363
|
end
|
354
364
|
|
355
365
|
it "should return nil if the get_collections call fails with nil" do
|
356
366
|
# this happens sometimes
|
357
367
|
@api.should_receive(:graph_call).and_return(nil)
|
358
|
-
@api.get_connections(
|
368
|
+
@api.get_connections(KoalaTest.page, "photos").should be_nil
|
359
369
|
end
|
360
370
|
|
361
371
|
it "should get a GraphCollection when searching" do
|
@@ -383,7 +393,7 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
|
|
383
393
|
# GraphCollection attributes
|
384
394
|
describe "the GraphCollection" do
|
385
395
|
before(:each) do
|
386
|
-
@result = @api.get_connections(
|
396
|
+
@result = @api.get_connections(KoalaTest.page, "photos")
|
387
397
|
end
|
388
398
|
|
389
399
|
it "should have a read-only paging attribute" do
|
@@ -425,7 +435,7 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
|
|
425
435
|
|
426
436
|
describe "when parsing page paramters" do
|
427
437
|
before(:each) do
|
428
|
-
@graph_collection = Koala::Facebook::GraphCollection.new({"data" => []}, Koala::Facebook::
|
438
|
+
@graph_collection = Koala::Facebook::GraphCollection.new({"data" => []}, Koala::Facebook::API.new)
|
429
439
|
end
|
430
440
|
|
431
441
|
it "should return the base as the first array entry" do
|
@@ -456,12 +466,11 @@ shared_examples_for "Koala GraphAPI without an access token" do
|
|
456
466
|
end
|
457
467
|
|
458
468
|
it "shouldn't be able to access connections from users" do
|
459
|
-
lambda { @api.get_connections("lukeshepard", "
|
469
|
+
lambda { @api.get_connections("lukeshepard", "friends") }.should raise_error(Koala::Facebook::APIError)
|
460
470
|
end
|
461
471
|
|
462
472
|
it "should not be able to put an object" do
|
463
473
|
lambda { @result = @api.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
|
464
|
-
puts "Error! Object #{@result.inspect} somehow put onto Luke Shepard's wall!" if @result
|
465
474
|
end
|
466
475
|
|
467
476
|
# these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
|
@@ -470,13 +479,11 @@ shared_examples_for "Koala GraphAPI without an access token" do
|
|
470
479
|
attachment = {:name => "OAuth Playground", :link => "http://oauth.twoalex.com/"}
|
471
480
|
@result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
|
472
481
|
end).should raise_error(Koala::Facebook::APIError)
|
473
|
-
puts "Error! Object #{@result.inspect} somehow put onto Context Optional's wall!" if @result
|
474
482
|
end
|
475
483
|
|
476
484
|
it "should not be able to comment on an object" do
|
477
485
|
# random public post on the ContextOptional wall
|
478
486
|
lambda { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
|
479
|
-
puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
|
480
487
|
end
|
481
488
|
|
482
489
|
it "should not be able to like an object" do
|
@@ -1,18 +1,42 @@
|
|
1
1
|
# when testing across Ruby versions, we found that JSON string creation inconsistently ordered keys
|
2
2
|
# which is a problem because our mock testing service ultimately matches strings to see if requests are mocked
|
3
3
|
# this fix solves that problem by ensuring all hashes are created with a consistent key order every time
|
4
|
-
|
5
4
|
module MultiJson
|
6
5
|
self.engine = :ok_json
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def encode_with_ordering(object)
|
9
|
+
# if it's a hash, recreate it with k/v pairs inserted in sorted-by-key order
|
10
|
+
# (for some reason, REE fails if we don't assign the ternary result as a local variable
|
11
|
+
# separately from calling encode_original)
|
12
|
+
encode_original(sort_object(object))
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :encode_original, :encode
|
16
|
+
alias_method :encode, :encode_with_ordering
|
7
17
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
def decode_with_ordering(string)
|
19
|
+
sort_object(decode_original(string))
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :decode_original, :decode
|
23
|
+
alias_method :decode, :decode_with_ordering
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def sort_object(object)
|
28
|
+
if object.is_a?(Hash)
|
29
|
+
sort_hash(object)
|
30
|
+
elsif object.is_a?(Array)
|
31
|
+
object.collect {|item| item.is_a?(Hash) ? sort_hash(item) : item}
|
32
|
+
else
|
33
|
+
object
|
34
|
+
end
|
35
|
+
end
|
15
36
|
|
16
|
-
|
17
|
-
|
18
|
-
|
37
|
+
def sort_hash(unsorted_hash)
|
38
|
+
sorted_hash = KoalaTest::OrderedHash.new(sorted_hash)
|
39
|
+
unsorted_hash.keys.sort {|a, b| a.to_s <=> b.to_s}.inject(sorted_hash) {|hash, k| hash[k] = unsorted_hash[k]; hash}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# small helper method for live testing
|
2
|
+
module KoalaTest
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :oauth_token, :app_id, :secret, :app_access_token, :code, :session_key
|
6
|
+
attr_accessor :oauth_test_data, :subscription_test_data
|
7
|
+
end
|
8
|
+
|
9
|
+
# Test setup
|
10
|
+
|
11
|
+
def self.setup_test_environment!
|
12
|
+
setup_rspec
|
13
|
+
|
14
|
+
unless ENV['LIVE']
|
15
|
+
# By default the Koala specs are run using stubs for HTTP requests,
|
16
|
+
# so they won't fail due to Facebook-imposed rate limits or server timeouts.
|
17
|
+
#
|
18
|
+
# However as a result they are more brittle since
|
19
|
+
# we are not testing the latest responses from the Facebook servers.
|
20
|
+
# To be certain all specs pass with the current Facebook services,
|
21
|
+
# run LIVE=true bundle exec rake spec.
|
22
|
+
Koala.http_service = Koala::MockHTTPService
|
23
|
+
KoalaTest.setup_test_data(Koala::MockHTTPService::TEST_DATA)
|
24
|
+
else
|
25
|
+
# Runs Koala specs through the Facebook servers
|
26
|
+
# using data for a real app
|
27
|
+
live_data = YAML.load_file(File.join(File.dirname(__FILE__), '../fixtures/facebook_data.yml'))
|
28
|
+
KoalaTest.setup_test_data(live_data)
|
29
|
+
|
30
|
+
# allow live tests with different adapters
|
31
|
+
adapter = ENV['ADAPTER'] || "typhoeus"# use Typhoeus by default if available
|
32
|
+
begin
|
33
|
+
require adapter
|
34
|
+
Faraday.default_adapter = adapter.to_sym
|
35
|
+
rescue LoadError
|
36
|
+
puts "Unable to load adapter #{adapter}, using Net::HTTP."
|
37
|
+
end
|
38
|
+
|
39
|
+
# use a test user unless the developer wants to test against a real profile
|
40
|
+
unless token = KoalaTest.oauth_token
|
41
|
+
KoalaTest.setup_test_users
|
42
|
+
else
|
43
|
+
KoalaTest.validate_user_info(token)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.setup_rspec
|
49
|
+
# set up a global before block to set the token for tests
|
50
|
+
# set the token up for
|
51
|
+
RSpec.configure do |config|
|
52
|
+
config.before :each do
|
53
|
+
@token = KoalaTest.oauth_token
|
54
|
+
Koala::Utils.stub(:deprecate) # never fire deprecation warnings
|
55
|
+
end
|
56
|
+
|
57
|
+
config.after :each do
|
58
|
+
# clean up any objects posted to Facebook
|
59
|
+
if @temporary_object_id && !KoalaTest.mock_interface?
|
60
|
+
api = @api || (@test_users ? @test_users.graph_api : nil)
|
61
|
+
raise "Unable to locate API when passed temporary object to delete!" unless api
|
62
|
+
|
63
|
+
# wait 10ms to allow Facebook to propagate data so we can delete it
|
64
|
+
sleep(0.01)
|
65
|
+
|
66
|
+
# clean up any objects we've posted
|
67
|
+
result = (api.delete_object(@temporary_object_id) rescue false)
|
68
|
+
# if we errored out or Facebook returned false, track that
|
69
|
+
puts "Unable to delete #{@temporary_object_id}: #{result} (probably a photo or video, which can't be deleted through the API)" unless result
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.setup_test_data(data)
|
76
|
+
# make data accessible to all our tests
|
77
|
+
self.oauth_test_data = data["oauth_test_data"]
|
78
|
+
self.subscription_test_data = data["subscription_test_data"]
|
79
|
+
self.oauth_token = data["oauth_token"]
|
80
|
+
self.app_id = data["oauth_test_data"]["app_id"]
|
81
|
+
self.app_access_token = data["oauth_test_data"]["app_access_token"]
|
82
|
+
self.secret = data["oauth_test_data"]["secret"]
|
83
|
+
self.code = data["oauth_test_data"]["code"]
|
84
|
+
self.session_key = data["oauth_test_data"]["session_key"]
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.testing_permissions
|
88
|
+
"read_stream, publish_stream, user_photos, user_videos, read_insights"
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.setup_test_users
|
92
|
+
# note: we don't have to delete the two test users explicitly, since the test user specs do that for us
|
93
|
+
# technically, this is a point of brittleness and would break if the tests were run out of order
|
94
|
+
# however, for now we can live with it since it would slow tests way too much to constantly recreate our test users
|
95
|
+
print "Setting up test users..."
|
96
|
+
@test_user_api = Koala::Facebook::TestUsers.new(:app_id => self.app_id, :secret => self.secret)
|
97
|
+
|
98
|
+
# create two test users with specific names and befriend them
|
99
|
+
@live_testing_user = @test_user_api.create(true, testing_permissions, :name => user1_name)
|
100
|
+
@live_testing_friend = @test_user_api.create(true, testing_permissions, :name => user2_name)
|
101
|
+
@test_user_api.befriend(@live_testing_user, @live_testing_friend)
|
102
|
+
self.oauth_token = @live_testing_user["access_token"]
|
103
|
+
|
104
|
+
puts "done."
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.validate_user_info(token)
|
108
|
+
print "Validating permissions for live testing..."
|
109
|
+
# make sure we have the necessary permissions
|
110
|
+
api = Koala::Facebook::API.new(token)
|
111
|
+
perms = api.fql_query("select #{testing_permissions} from permissions where uid = me()")[0]
|
112
|
+
perms.each_pair do |perm, value|
|
113
|
+
if value == (perm == "read_insights" ? 1 : 0) # live testing depends on insights calls failing
|
114
|
+
puts "failed!\n" # put a new line after the print above
|
115
|
+
raise ArgumentError, "Your access token must have the read_stream, publish_stream, and user_photos permissions, and lack read_insights. You have: #{perms.inspect}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
puts "done!"
|
119
|
+
end
|
120
|
+
|
121
|
+
# Info about the testing environment
|
122
|
+
def self.real_user?
|
123
|
+
!(mock_interface? || @test_user)
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.test_user?
|
127
|
+
!!@test_user_api
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.mock_interface?
|
131
|
+
Koala.http_service == Koala::MockHTTPService
|
132
|
+
end
|
133
|
+
|
134
|
+
# Data for testing
|
135
|
+
def self.user1
|
136
|
+
test_user? ? @live_testing_user["id"] : "koppel"
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.user1_id
|
140
|
+
test_user? ? @live_testing_user["id"] : 2905623
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.user1_name
|
144
|
+
"Alex"
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.user2
|
148
|
+
test_user? ? @live_testing_friend["id"] : "lukeshepard"
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.user2_id
|
152
|
+
test_user? ? @live_testing_friend["id"] : 2901279
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.user2_name
|
156
|
+
"Luke"
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.page
|
160
|
+
"contextoptional"
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|