koala 1.0.0 → 1.2.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.
- data/.autotest +12 -0
- data/.gitignore +3 -1
- data/.travis.yml +9 -0
- data/CHANGELOG +62 -2
- data/Gemfile +8 -0
- data/Rakefile +0 -1
- data/autotest/discover.rb +1 -0
- data/koala.gemspec +13 -14
- data/lib/koala/batch_operation.rb +74 -0
- data/lib/koala/graph_api.rb +145 -132
- data/lib/koala/graph_batch_api.rb +97 -0
- data/lib/koala/graph_collection.rb +59 -0
- data/lib/koala/http_service.rb +176 -0
- data/lib/koala/oauth.rb +191 -0
- data/lib/koala/realtime_updates.rb +23 -29
- data/lib/koala/rest_api.rb +13 -8
- data/lib/koala/test_users.rb +33 -17
- data/lib/koala/uploadable_io.rb +153 -87
- data/lib/koala/utils.rb +11 -0
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +59 -217
- data/readme.md +92 -53
- data/spec/cases/{api_base_spec.rb → api_spec.rb} +31 -6
- data/spec/cases/error_spec.rb +32 -0
- data/spec/cases/graph_and_rest_api_spec.rb +12 -21
- data/spec/cases/graph_api_batch_spec.rb +582 -0
- data/spec/cases/graph_api_spec.rb +11 -14
- data/spec/cases/graph_collection_spec.rb +116 -0
- data/spec/cases/http_service_spec.rb +446 -0
- data/spec/cases/koala_spec.rb +54 -0
- data/spec/cases/oauth_spec.rb +319 -213
- 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 +123 -75
- data/spec/cases/uploadable_io_spec.rb +120 -37
- data/spec/cases/utils_spec.rb +10 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +26 -24
- data/spec/fixtures/mock_facebook_responses.yml +203 -78
- data/spec/spec_helper.rb +30 -5
- data/spec/support/graph_api_shared_examples.rb +149 -118
- data/spec/support/json_testing_fix.rb +42 -0
- data/spec/support/koala_test.rb +187 -0
- data/spec/support/mock_http_service.rb +62 -58
- data/spec/support/ordered_hash.rb +205 -0
- data/spec/support/rest_api_shared_examples.rb +139 -15
- data/spec/support/uploadable_io_shared_examples.rb +2 -8
- metadata +90 -114
- data/lib/koala/http_services.rb +0 -146
- data/spec/cases/http_services/http_service_spec.rb +0 -54
- data/spec/cases/http_services/net_http_service_spec.rb +0 -350
- data/spec/cases/http_services/typhoeus_service_spec.rb +0 -144
- data/spec/support/live_testing_data_helper.rb +0 -40
- data/spec/support/setup_mocks_or_live.rb +0 -52
|
@@ -9,25 +9,45 @@ module Koala::MIME
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe "Koala::UploadableIO" do
|
|
12
|
+
def rails_3_mocks
|
|
13
|
+
tempfile = stub('Tempfile', :path => "foo")
|
|
14
|
+
uploaded_file = stub('ActionDispatch::Http::UploadedFile',
|
|
15
|
+
:content_type => true,
|
|
16
|
+
:tempfile => tempfile,
|
|
17
|
+
:original_filename => "bar"
|
|
18
|
+
)
|
|
19
|
+
tempfile.stub!(:respond_to?).with(:path).and_return(true)
|
|
20
|
+
|
|
21
|
+
[tempfile, uploaded_file]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def sinatra_mocks
|
|
25
|
+
{:type => "type", :tempfile => "Tempfile", :filename => "foo.bar"}
|
|
26
|
+
end
|
|
27
|
+
|
|
12
28
|
describe "the constructor" do
|
|
13
29
|
describe "when given a file path" do
|
|
14
30
|
before(:each) do
|
|
15
|
-
@
|
|
31
|
+
@path = BEACH_BALL_PATH
|
|
32
|
+
@koala_io_params = [@path]
|
|
16
33
|
end
|
|
17
34
|
|
|
18
35
|
describe "and a content type" do
|
|
19
36
|
before :each do
|
|
20
|
-
@
|
|
37
|
+
@stub_type = stub("image/jpg")
|
|
38
|
+
@koala_io_params.concat([@stub_type])
|
|
21
39
|
end
|
|
22
40
|
|
|
23
|
-
it "
|
|
24
|
-
|
|
25
|
-
Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == stub_path
|
|
41
|
+
it "returns an UploadIO with the same file path" do
|
|
42
|
+
Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @path
|
|
26
43
|
end
|
|
27
44
|
|
|
28
|
-
it "
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
it "returns an UploadIO with the same content type" do
|
|
46
|
+
Koala::UploadableIO.new(*@koala_io_params).content_type.should == @stub_type
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "returns an UploadIO with the file's name" do
|
|
50
|
+
Koala::UploadableIO.new(*@koala_io_params).filename.should == File.basename(@path)
|
|
31
51
|
end
|
|
32
52
|
end
|
|
33
53
|
|
|
@@ -38,7 +58,8 @@ describe "Koala::UploadableIO" do
|
|
|
38
58
|
|
|
39
59
|
describe "when given a File object" do
|
|
40
60
|
before(:each) do
|
|
41
|
-
@
|
|
61
|
+
@file = File.open(BEACH_BALL_PATH)
|
|
62
|
+
@koala_io_params = [@file]
|
|
42
63
|
end
|
|
43
64
|
|
|
44
65
|
describe "and a content type" do
|
|
@@ -46,14 +67,18 @@ describe "Koala::UploadableIO" do
|
|
|
46
67
|
@koala_io_params.concat(["image/jpg"])
|
|
47
68
|
end
|
|
48
69
|
|
|
49
|
-
it "
|
|
70
|
+
it "returns an UploadIO with the same io" do
|
|
50
71
|
Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @koala_io_params[0]
|
|
51
72
|
end
|
|
52
73
|
|
|
53
|
-
it "
|
|
74
|
+
it "returns an UploadableIO with the same content_type" do
|
|
54
75
|
content_stub = @koala_io_params[1] = stub('Content Type')
|
|
55
76
|
Koala::UploadableIO.new(*@koala_io_params).content_type.should == content_stub
|
|
56
77
|
end
|
|
78
|
+
|
|
79
|
+
it "returns an UploadableIO with the right filename" do
|
|
80
|
+
Koala::UploadableIO.new(*@koala_io_params).filename.should == File.basename(@file.path)
|
|
81
|
+
end
|
|
57
82
|
end
|
|
58
83
|
|
|
59
84
|
describe "and no content type" do
|
|
@@ -61,39 +86,70 @@ describe "Koala::UploadableIO" do
|
|
|
61
86
|
end
|
|
62
87
|
end
|
|
63
88
|
|
|
89
|
+
describe "when given an IO object" do
|
|
90
|
+
before(:each) do
|
|
91
|
+
@io = StringIO.open("abcdefgh")
|
|
92
|
+
@koala_io_params = [@io]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "and a content type" do
|
|
96
|
+
before :each do
|
|
97
|
+
@koala_io_params.concat(["image/jpg"])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "returns an UploadableIO with the same io" do
|
|
101
|
+
Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @koala_io_params[0]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "returns an UploadableIO with the same content_type" do
|
|
105
|
+
content_stub = @koala_io_params[1] = stub('Content Type')
|
|
106
|
+
Koala::UploadableIO.new(*@koala_io_params).content_type.should == content_stub
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe "and no content type" do
|
|
111
|
+
it "raises an exception" do
|
|
112
|
+
lambda { Koala::UploadableIO.new(*@koala_io_params) }.should raise_exception(Koala::KoalaError)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
64
117
|
describe "when given a Rails 3 ActionDispatch::Http::UploadedFile" do
|
|
65
118
|
before(:each) do
|
|
66
|
-
@tempfile
|
|
67
|
-
|
|
68
|
-
:content_type => true,
|
|
69
|
-
:tempfile => @tempfile
|
|
70
|
-
)
|
|
119
|
+
@tempfile, @uploaded_file = rails_3_mocks
|
|
120
|
+
end
|
|
71
121
|
|
|
72
|
-
|
|
122
|
+
it "gets the path from the tempfile associated with the UploadedFile" do
|
|
123
|
+
expected_path = stub('Tempfile')
|
|
124
|
+
@tempfile.should_receive(:path).and_return(expected_path)
|
|
125
|
+
Koala::UploadableIO.new(@uploaded_file).io_or_path.should == expected_path
|
|
73
126
|
end
|
|
74
127
|
|
|
75
|
-
it "
|
|
128
|
+
it "gets the content type via the content_type method" do
|
|
76
129
|
expected_content_type = stub('Content Type')
|
|
77
130
|
@uploaded_file.should_receive(:content_type).and_return(expected_content_type)
|
|
78
131
|
Koala::UploadableIO.new(@uploaded_file).content_type.should == expected_content_type
|
|
79
132
|
end
|
|
80
133
|
|
|
81
|
-
it "
|
|
82
|
-
|
|
83
|
-
@tempfile.should_receive(:path).and_return(expected_path)
|
|
84
|
-
Koala::UploadableIO.new(@uploaded_file).io_or_path.should == expected_path
|
|
134
|
+
it "gets the filename from the UploadedFile" do
|
|
135
|
+
Koala::UploadableIO.new(@uploaded_file).filename.should == @uploaded_file.original_filename
|
|
85
136
|
end
|
|
86
137
|
end
|
|
87
138
|
|
|
88
139
|
describe "when given a Sinatra file parameter hash" do
|
|
89
140
|
before(:each) do
|
|
90
|
-
@file_hash =
|
|
91
|
-
:type => "type",
|
|
92
|
-
:tempfile => "Tempfile"
|
|
93
|
-
}
|
|
141
|
+
@file_hash = sinatra_mocks
|
|
94
142
|
end
|
|
95
143
|
|
|
96
|
-
it "
|
|
144
|
+
it "gets the io_or_path from the :tempfile key" do
|
|
145
|
+
expected_file = stub('File')
|
|
146
|
+
@file_hash[:tempfile] = expected_file
|
|
147
|
+
|
|
148
|
+
uploadable = Koala::UploadableIO.new(@file_hash)
|
|
149
|
+
uploadable.io_or_path.should == expected_file
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "gets the content type from the :type key" do
|
|
97
153
|
expected_content_type = stub('Content Type')
|
|
98
154
|
@file_hash[:type] = expected_content_type
|
|
99
155
|
|
|
@@ -101,12 +157,9 @@ describe "Koala::UploadableIO" do
|
|
|
101
157
|
uploadable.content_type.should == expected_content_type
|
|
102
158
|
end
|
|
103
159
|
|
|
104
|
-
it "
|
|
105
|
-
expected_file = stub('File')
|
|
106
|
-
@file_hash[:tempfile] = expected_file
|
|
107
|
-
|
|
160
|
+
it "gets the content type from the :type key" do
|
|
108
161
|
uploadable = Koala::UploadableIO.new(@file_hash)
|
|
109
|
-
uploadable.
|
|
162
|
+
uploadable.filename.should == @file_hash[:filename]
|
|
110
163
|
end
|
|
111
164
|
end
|
|
112
165
|
|
|
@@ -130,14 +183,24 @@ describe "Koala::UploadableIO" do
|
|
|
130
183
|
UploadIO.stub!(:new).with(anything, anything, anything).and_return(@upload_io)
|
|
131
184
|
end
|
|
132
185
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
186
|
+
context "if no filename was provided" do
|
|
187
|
+
it "should call the constructor with the content type, file name, and a dummy file name" do
|
|
188
|
+
UploadIO.should_receive(:new).with(BEACH_BALL_PATH, "content/type", anything).and_return(@upload_io)
|
|
189
|
+
Koala::UploadableIO.new(BEACH_BALL_PATH, "content/type").to_upload_io.should == @upload_io
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context "if a filename was provided" do
|
|
194
|
+
it "should call the constructor with the content type, file name, and the filename" do
|
|
195
|
+
filename = "file"
|
|
196
|
+
UploadIO.should_receive(:new).with(BEACH_BALL_PATH, "content/type", filename).and_return(@upload_io)
|
|
197
|
+
Koala::UploadableIO.new(BEACH_BALL_PATH, "content/type", filename).to_upload_io
|
|
198
|
+
end
|
|
136
199
|
end
|
|
137
200
|
end
|
|
138
201
|
|
|
139
202
|
describe "getting a file" do
|
|
140
|
-
it "
|
|
203
|
+
it "returns the File if initialized with a file" do
|
|
141
204
|
f = File.new(BEACH_BALL_PATH)
|
|
142
205
|
Koala::UploadableIO.new(f).to_file.should == f
|
|
143
206
|
end
|
|
@@ -148,4 +211,24 @@ describe "Koala::UploadableIO" do
|
|
|
148
211
|
Koala::UploadableIO.new(BEACH_BALL_PATH).to_file.should == result
|
|
149
212
|
end
|
|
150
213
|
end
|
|
151
|
-
|
|
214
|
+
|
|
215
|
+
describe "#binary_content?" do
|
|
216
|
+
it "returns true for Rails 3 file uploads" do
|
|
217
|
+
Koala::UploadableIO.binary_content?(rails_3_mocks.last).should be_true
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it "returns true for Sinatra file uploads" do
|
|
221
|
+
Koala::UploadableIO.binary_content?(rails_3_mocks.last).should be_true
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "returns true for File objects" do
|
|
225
|
+
Koala::UploadableIO.binary_content?(File.open(BEACH_BALL_PATH)).should be_true
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "returns false for everything else" do
|
|
229
|
+
Koala::UploadableIO.binary_content?(StringIO.new).should be_false
|
|
230
|
+
Koala::UploadableIO.binary_content?(BEACH_BALL_PATH).should be_false
|
|
231
|
+
Koala::UploadableIO.binary_content?(nil).should be_false
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end # describe UploadableIO
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Koala::Utils do
|
|
4
|
+
it "has a deprecate method" do
|
|
5
|
+
Koala::Utils.should respond_to(:deprecate)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# AFAIK there's no way to test that (Kernel.)warn receives the text
|
|
9
|
+
# Kernel.should_receive(:warn) doesn't seem to work, even though the text gets printed
|
|
10
|
+
end
|
|
Binary file
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# Testing data
|
|
2
|
+
|
|
3
|
+
# IMPORTANT NOTE: live tests will run against a test users automatically
|
|
4
|
+
# If you want to run them against a real user or test users on a different account, you can
|
|
5
|
+
# by enter an OAuth token, code, and session_key (for real users) or changing the app_id and secret (for test users)
|
|
6
|
+
# (note for real users: this will leave some photos and videos posted to your wall, since they can't be deleted through the API)
|
|
7
|
+
|
|
8
|
+
# These values are configured to work with the OAuth Playground app by default
|
|
3
9
|
# Of course, you can change this to work with your own app.
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
# You must supply this value yourself to test the GraphAPI class.
|
|
7
|
-
# Your OAuth token should have publish_stream, read_stream, and user_photos permissions.
|
|
8
|
-
oauth_token:
|
|
10
|
+
# Check out http://oauth.twoalex.com/ to easily generate tokens, cookies, etc.
|
|
9
11
|
|
|
10
|
-
#
|
|
12
|
+
# Your OAuth token should have the read_stream, publish_stream, user_photos, user_videos, and read_insights permissions.
|
|
13
|
+
oauth_token:
|
|
14
|
+
|
|
15
|
+
# for testing the OAuth class
|
|
11
16
|
# baseline app
|
|
12
|
-
oauth_test_data:
|
|
13
|
-
#
|
|
14
|
-
code:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
multiple_session_keys:
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
17
|
+
oauth_test_data:
|
|
18
|
+
# the following two values are not needed for most of the test suite, but the relevant tests will not run if they're not present
|
|
19
|
+
code:
|
|
20
|
+
session_key:
|
|
21
|
+
|
|
21
22
|
# These values will work out of the box
|
|
22
23
|
app_id: 119908831367602
|
|
23
24
|
secret: e45e55a333eec232d4206d2703de1307
|
|
@@ -25,15 +26,16 @@ oauth_test_data:
|
|
|
25
26
|
app_access_token: 119908831367602|o3wswWQ88LYjEC9-ukR_gjRIOMw.
|
|
26
27
|
raw_token_string: "access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.&expires=6621"
|
|
27
28
|
raw_offline_access_token_string: access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.
|
|
28
|
-
valid_cookies:
|
|
29
|
+
valid_cookies:
|
|
29
30
|
# note: the tests stub the time class so these default cookies are always valid (if you're using the default app)
|
|
30
31
|
# if not you may want to remove the stubbing to test expiration
|
|
31
32
|
fbs_119908831367602: '"access_token=119908831367602|2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623|CMpi0AYbn03Oukzv94AUha2qbO4.&expires=1273363200&secret=lT_9zm5r5IbJ6Aa5O54nFw__&session_key=2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623&sig=9515e93113921f9476a4efbdd4a3c746&uid=2905623"'
|
|
32
|
-
|
|
33
|
-
fbs_119908831367602: '"access_token=119908831367602|2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623|yVt5WH_S6J5p3gFa5_5lBzckhws.&expires=1273287600&secret=V_E79ovQnXqxGctFuC_n5A__&session_key=2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623&sig=eeef60838c0c800258d89b7e6ddddddb&uid=2905623"'
|
|
34
|
-
offline_access_cookies:
|
|
33
|
+
offline_access_cookies:
|
|
35
34
|
# note: I've revoked the offline access for security reasons, so you can't make calls against this :)
|
|
36
35
|
fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
|
|
36
|
+
valid_signed_cookies:
|
|
37
|
+
"fbsr_119908831367602": "f1--LHwjHVCxfs97hRHL-4cF-0jNxZRc6MGzo1qHLb0.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiIyLkFRQm90a0pBWlhVY1l3RkMuMzYwMC4xMzE0ODEzNjAwLjEtMjkwNTYyM3x4V2xya0d0UmJIZlpIclRnVWwxQmxJcVhRbjQiLCJpc3N1ZWRfYXQiOjEzMTQ4MDY2NTUsInVzZXJfaWQiOiIyOTA1NjIzIn0"
|
|
38
|
+
|
|
37
39
|
|
|
38
40
|
# These values from the OAuth Playground (see above) will work out of the box
|
|
39
41
|
# You can update this to live data if desired
|
|
@@ -44,17 +46,17 @@ oauth_test_data:
|
|
|
44
46
|
algorithm: HMAC-SHA256
|
|
45
47
|
user_id: "2905623"
|
|
46
48
|
oauth_token: 119908831367602|2.zVF_6NrMELHuJa4gIU9tKw__.3600.1301922000-2905623|zgqPsr2BG9LoOK9kekGgRURZx0k
|
|
47
|
-
user:
|
|
49
|
+
user:
|
|
48
50
|
country: de
|
|
49
51
|
locale: de_DE
|
|
50
|
-
age:
|
|
52
|
+
age:
|
|
51
53
|
min: 21
|
|
52
54
|
issued_at: 1301917299
|
|
53
55
|
|
|
54
56
|
subscription_test_data:
|
|
55
57
|
subscription_path: http://oauth.twoalex.com/subscriptions
|
|
56
58
|
verify_token: "myverificationtoken|1f54545d5f722733e17faae15377928f"
|
|
57
|
-
challenge_data:
|
|
59
|
+
challenge_data:
|
|
58
60
|
"hub.challenge": "1290024882"
|
|
59
61
|
"hub.verify_token": "myverificationtoken|1f54545d5f722733e17faae15377928f"
|
|
60
62
|
"hub.mode": "subscribe"
|