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.
- checksums.yaml +7 -0
- data/.github/workflows/test.yml +32 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +3 -0
- data/Gemfile +25 -0
- data/ISSUE_TEMPLATE +25 -0
- data/LICENSE +22 -0
- data/Manifest +32 -5
- data/PULL_REQUEST_TEMPLATE +11 -0
- data/Rakefile +12 -12
- data/changelog.md +781 -0
- data/code_of_conduct.md +74 -0
- data/koala.gemspec +28 -24
- data/lib/koala/api/batch_operation.rb +86 -0
- data/lib/koala/api/graph_api_methods.rb +504 -0
- data/lib/koala/api/graph_batch_api.rb +167 -0
- data/lib/koala/api/graph_collection.rb +129 -0
- data/lib/koala/api/graph_error_checker.rb +72 -0
- data/lib/koala/api.rb +159 -0
- data/lib/koala/configuration.rb +56 -0
- data/lib/koala/errors.rb +126 -0
- data/lib/koala/http_service/request.rb +133 -0
- data/lib/koala/http_service/response.rb +20 -0
- data/lib/koala/http_service/uploadable_io.rb +183 -0
- data/lib/koala/http_service.rb +108 -0
- data/lib/koala/oauth.rb +342 -0
- data/lib/koala/realtime_updates.rb +151 -0
- data/lib/koala/test_users.rb +189 -0
- data/lib/koala/utils.rb +41 -0
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +51 -291
- data/readme.md +269 -21
- data/spec/cases/api_spec.rb +362 -0
- data/spec/cases/configuration_spec.rb +11 -0
- data/spec/cases/error_spec.rb +143 -0
- data/spec/cases/graph_api_batch_spec.rb +788 -0
- data/spec/cases/graph_api_spec.rb +76 -0
- data/spec/cases/graph_collection_spec.rb +192 -0
- data/spec/cases/graph_error_checker_spec.rb +147 -0
- data/spec/cases/http_service/request_spec.rb +250 -0
- data/spec/cases/http_service/response_spec.rb +24 -0
- data/spec/cases/http_service_spec.rb +280 -0
- data/spec/cases/koala_spec.rb +57 -0
- data/spec/cases/koala_test_spec.rb +5 -0
- data/spec/cases/oauth_spec.rb +647 -0
- data/spec/cases/realtime_updates_spec.rb +327 -0
- data/spec/cases/test_users_spec.rb +383 -0
- data/spec/cases/uploadable_io_spec.rb +266 -0
- data/spec/cases/utils_spec.rb +55 -0
- data/spec/fixtures/beach.jpg +0 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +63 -0
- data/spec/fixtures/mock_facebook_responses.yml +483 -0
- data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
- data/spec/fixtures/vcr_cassettes/friend_list_next_page.yml +121 -0
- data/spec/integration/graph_collection_spec.rb +24 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/custom_matchers.rb +28 -0
- data/spec/support/graph_api_shared_examples.rb +534 -0
- data/spec/support/koala_test.rb +251 -0
- data/spec/support/mock_http_service.rb +140 -0
- data/spec/support/uploadable_io_shared_examples.rb +70 -0
- metadata +206 -62
- data/CHANGELOG +0 -24
- data/init.rb +0 -2
- data/lib/http_services.rb +0 -60
- data/test/facebook_data.yml +0 -5
- data/test/koala/facebook_no_access_token_tests.rb +0 -119
- data/test/koala/facebook_with_access_token_tests.rb +0 -106
- data/test/koala_tests.rb +0 -30
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Koala::Facebook::TestUsers" do
|
|
4
|
+
before :all do
|
|
5
|
+
# get oauth data
|
|
6
|
+
@app_id = KoalaTest.app_id
|
|
7
|
+
@secret = KoalaTest.secret
|
|
8
|
+
@app_access_token = KoalaTest.app_access_token
|
|
9
|
+
|
|
10
|
+
@test_users = Koala::Facebook::TestUsers.new({:app_access_token => @app_access_token, :app_id => @app_id})
|
|
11
|
+
|
|
12
|
+
# check OAuth data
|
|
13
|
+
unless @app_id && @secret && @app_access_token
|
|
14
|
+
raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
after :each do
|
|
19
|
+
# clean up any test users
|
|
20
|
+
# Facebook only allows us 500 test users per app, so we have to clean up
|
|
21
|
+
# This would be a good place to clean up and accumulate all of them for
|
|
22
|
+
# later deletion.
|
|
23
|
+
unless KoalaTest.mock_interface? || @stubbed
|
|
24
|
+
((@network || []) + [@user1, @user2]).each do |u|
|
|
25
|
+
puts "Unable to delete test user #{u.inspect}" if u && !(@test_users.delete(u) rescue false)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe "when initializing" do
|
|
31
|
+
# basic initialization
|
|
32
|
+
it "initializes properly with an app_id and an app_access_token" do
|
|
33
|
+
test_users = Koala::Facebook::TestUsers.new(:app_id => @app_id, :app_access_token => @app_access_token)
|
|
34
|
+
expect(test_users).to be_a(Koala::Facebook::TestUsers)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# init with secret / fetching the token
|
|
38
|
+
it "initializes properly with an app_id and a secret" do
|
|
39
|
+
test_users = Koala::Facebook::TestUsers.new(:app_id => @app_id, :secret => @secret)
|
|
40
|
+
expect(test_users).to be_a(Koala::Facebook::TestUsers)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "with global defaults" do
|
|
44
|
+
let(:app_id) { :app_id }
|
|
45
|
+
let(:app_secret) { :app_secret }
|
|
46
|
+
let(:app_access_token) { :app_access_token }
|
|
47
|
+
|
|
48
|
+
before :each do
|
|
49
|
+
Koala.configure do |config|
|
|
50
|
+
config.app_id = app_id
|
|
51
|
+
config.app_secret = app_secret
|
|
52
|
+
config.app_access_token = app_access_token
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "defaults to the configured data if not otherwise provided" do
|
|
57
|
+
test_users = Koala::Facebook::TestUsers.new
|
|
58
|
+
expect(test_users.app_id).to eq(app_id)
|
|
59
|
+
expect(test_users.secret).to eq(app_secret)
|
|
60
|
+
expect(test_users.app_access_token).to eq(app_access_token)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "lets you override app_id" do
|
|
64
|
+
other_value = :another_id
|
|
65
|
+
test_users = Koala::Facebook::TestUsers.new(app_id: other_value)
|
|
66
|
+
expect(test_users.app_id).to eq(other_value)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "lets you override secret" do
|
|
70
|
+
other_value = :another_secret
|
|
71
|
+
test_users = Koala::Facebook::TestUsers.new(secret: other_value)
|
|
72
|
+
expect(test_users.secret).to eq(other_value)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "lets you override app_id" do
|
|
76
|
+
other_value = :another_token
|
|
77
|
+
test_users = Koala::Facebook::TestUsers.new(app_access_token: other_value)
|
|
78
|
+
expect(test_users.app_access_token).to eq(other_value)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
it "uses the OAuth class to fetch a token when provided an app_id and a secret" do
|
|
84
|
+
oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
|
|
85
|
+
token = oauth.get_app_access_token
|
|
86
|
+
expect(oauth).to receive(:get_app_access_token).and_return(token)
|
|
87
|
+
expect(Koala::Facebook::OAuth).to receive(:new).with(@app_id, @secret).and_return(oauth)
|
|
88
|
+
Koala::Facebook::TestUsers.new(:app_id => @app_id, :secret => @secret)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# attributes
|
|
92
|
+
it "allows read access to app_id, app_access_token, and secret" do
|
|
93
|
+
# in Ruby 1.9, .method returns symbols
|
|
94
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).to include(:app_id)
|
|
95
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).not_to include(:app_id=)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "allows read access to app_access_token" do
|
|
99
|
+
# in Ruby 1.9, .method returns symbols
|
|
100
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).to include(:app_access_token)
|
|
101
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).not_to include(:app_access_token=)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "allows read access to secret" do
|
|
105
|
+
# in Ruby 1.9, .method returns symbols
|
|
106
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).to include(:secret)
|
|
107
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).not_to include(:secret=)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "allows read access to api" do
|
|
111
|
+
# in Ruby 1.9, .method returns symbols
|
|
112
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).to include(:api)
|
|
113
|
+
expect(Koala::Facebook::TestUsers.instance_methods.map(&:to_sym)).not_to include(:api=)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe "when used without network" do
|
|
118
|
+
# TEST USER MANAGEMENT
|
|
119
|
+
|
|
120
|
+
describe "#create" do
|
|
121
|
+
it "creates a test user when not given installed" do
|
|
122
|
+
result = @test_users.create(false)
|
|
123
|
+
@user1 = result["id"]
|
|
124
|
+
expect(result).to be_a(Hash)
|
|
125
|
+
expect(result["id"] && result["access_token"] && result["login_url"]).to be_truthy
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "creates a test user when not given installed, ignoring permissions" do
|
|
129
|
+
result = @test_users.create(false, "read_stream")
|
|
130
|
+
@user1 = result["id"]
|
|
131
|
+
expect(result).to be_a(Hash)
|
|
132
|
+
expect(result["id"] && result["access_token"] && result["login_url"]).to be_truthy
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "accepts permissions as a string" do
|
|
136
|
+
expect(@test_users.api).to receive(:graph_call).with(anything, hash_including("permissions" => "read_stream,publish_stream"), anything, anything)
|
|
137
|
+
result = @test_users.create(true, "read_stream,publish_stream")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "accepts permissions as an array" do
|
|
141
|
+
expect(@test_users.api).to receive(:graph_call).with(anything, hash_including("permissions" => "read_stream,publish_stream"), anything, anything)
|
|
142
|
+
result = @test_users.create(true, ["read_stream", "publish_stream"])
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "creates a test user when given installed and a permission" do
|
|
146
|
+
result = @test_users.create(true, "read_stream")
|
|
147
|
+
@user1 = result["id"]
|
|
148
|
+
expect(result).to be_a(Hash)
|
|
149
|
+
expect(result["id"] && result["access_token"] && result["login_url"]).to be_truthy
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "lets you specify other graph arguments, like uid and access token" do
|
|
153
|
+
args = {:uid => "some test user ID", :owner_access_token => "some owner access token"}
|
|
154
|
+
expect(@test_users.api).to receive(:graph_call).with(anything, hash_including(args), anything, anything)
|
|
155
|
+
@test_users.create(true, nil, args)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "lets you specify http options that get passed through to the graph call" do
|
|
159
|
+
options = {:some_http_option => true}
|
|
160
|
+
expect(@test_users.api).to receive(:graph_call).with(anything, anything, anything, options)
|
|
161
|
+
@test_users.create(true, nil, {}, options)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
describe "#list" do
|
|
166
|
+
before :each do
|
|
167
|
+
@user1 = @test_users.create(true, "read_stream")
|
|
168
|
+
@user2 = @test_users.create(true, "read_stream,user_interests")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "lists test users" do
|
|
172
|
+
result = @test_users.list
|
|
173
|
+
expect(result).to be_an(Array)
|
|
174
|
+
first_user, second_user = result[0], result[1]
|
|
175
|
+
expect(first_user["id"] && first_user["access_token"] && first_user["login_url"]).to be_truthy
|
|
176
|
+
expect(second_user["id"] && second_user["access_token"] && second_user["login_url"]).to be_truthy
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "accepts http options" do
|
|
180
|
+
@stubbed = true
|
|
181
|
+
options = {:some_http_option => true}
|
|
182
|
+
expect(@test_users.api).to receive(:graph_call).with(anything, anything, anything, options)
|
|
183
|
+
@test_users.list(options)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
describe "#delete" do
|
|
188
|
+
before :each do
|
|
189
|
+
@user1 = @test_users.create(true, "read_stream")
|
|
190
|
+
@user2 = @test_users.create(true, "read_stream,user_interests")
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "deletes a user by id" do
|
|
194
|
+
expect(@test_users.delete(@user1['id'])).to be_truthy
|
|
195
|
+
@user1 = nil
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "deletes a user by hash" do
|
|
199
|
+
expect(@test_users.delete(@user2)).to be_truthy
|
|
200
|
+
@user2 = nil
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "does not delete users when provided a false ID" do
|
|
204
|
+
expect { @test_users.delete("#{@user1['id']}1") }.to raise_exception(Koala::Facebook::APIError)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "lets you specify http options that get passed through to the graph call" do
|
|
208
|
+
options = {:some_http_option => true}
|
|
209
|
+
# technically this goes through delete_object, but this makes it less brittle
|
|
210
|
+
@stubbed = true
|
|
211
|
+
expect(@test_users.api).to receive(:graph_call).with(anything, anything, anything, options)
|
|
212
|
+
@test_users.delete("user", options)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
describe "#delete_all" do
|
|
217
|
+
it "deletes the batch API to deleten all users found by the list commnand" do
|
|
218
|
+
array = 200.times.collect { {"id" => rand}}
|
|
219
|
+
expect(@test_users).to receive(:list).and_return(array, [])
|
|
220
|
+
batch_api = double("batch API")
|
|
221
|
+
allow(@test_users.api).to receive(:batch).and_yield(batch_api)
|
|
222
|
+
array.each {|item| expect(batch_api).to receive(:delete_object).with(item["id"]) }
|
|
223
|
+
@test_users.delete_all
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "accepts http options that get passed to both list and the batch call" do
|
|
227
|
+
options = {:some_http_option => true}
|
|
228
|
+
expect(@test_users).to receive(:list).with(options).and_return([{"id" => rand}], [])
|
|
229
|
+
expect(@test_users.api).to receive(:batch).with(options)
|
|
230
|
+
@test_users.delete_all(options)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it "breaks if Facebook sends back the same list twice" do
|
|
234
|
+
list = [{"id" => rand}]
|
|
235
|
+
allow(@test_users).to receive(:list).and_return(list)
|
|
236
|
+
expect(@test_users.api).to receive(:batch).once
|
|
237
|
+
@test_users.delete_all
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "breaks if the same list comes back, even if the hashes differ" do
|
|
241
|
+
list1 = [{"id" => 123}]
|
|
242
|
+
list2 = [{"id" => 123, "name" => "foo"}]
|
|
243
|
+
allow(@test_users).to receive(:list).twice.and_return(list1, list2)
|
|
244
|
+
expect(@test_users.api).to receive(:batch).once
|
|
245
|
+
@test_users.delete_all
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
describe "#update" do
|
|
250
|
+
before :each do
|
|
251
|
+
@updates = {:name => "Foo Baz"}
|
|
252
|
+
# we stub out :graph_call, but still need to be able to delete the users
|
|
253
|
+
@test_users2 = Koala::Facebook::TestUsers.new(:app_id => @test_users.app_id, :app_access_token => @test_users.app_access_token)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "makes a POST with the test user Graph API " do
|
|
257
|
+
@user1 = @test_users2.create(true)
|
|
258
|
+
expect(@test_users2.api).to receive(:graph_call).with(anything, anything, "post", anything)
|
|
259
|
+
@test_users2.update(@user1, @updates)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it "makes a request to the test user with the update params " do
|
|
263
|
+
@user1 = @test_users2.create(true)
|
|
264
|
+
expect(@test_users2.api).to receive(:graph_call).with(@user1["id"], @updates, anything, anything)
|
|
265
|
+
@test_users2.update(@user1, @updates)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "accepts an options hash" do
|
|
269
|
+
options = {:some_http_option => true}
|
|
270
|
+
@stubbed = true
|
|
271
|
+
expect(@test_users2.api).to receive(:graph_call).with(anything, anything, anything, options)
|
|
272
|
+
@test_users2.update("foo", @updates, options)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
it "works" do
|
|
276
|
+
@user1 = @test_users.create(true)
|
|
277
|
+
@test_users.update(@user1, @updates)
|
|
278
|
+
user_info = Koala::Facebook::API.new(@user1["access_token"]).get_object(@user1["id"])
|
|
279
|
+
expect(user_info["name"]).to eq(@updates[:name])
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
describe "#befriend" do
|
|
284
|
+
before :each do
|
|
285
|
+
@user1 = @test_users.create(true, "read_stream")
|
|
286
|
+
@user2 = @test_users.create(true, "read_stream,user_interests")
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it "makes two users into friends with string hashes" do
|
|
290
|
+
result = @test_users.befriend(@user1, @user2)
|
|
291
|
+
expect(result).to be_truthy
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "makes two users into friends with symbol hashes" do
|
|
295
|
+
new_user_1 = {}
|
|
296
|
+
@user1.each_pair {|k, v| new_user_1[k.to_sym] = v}
|
|
297
|
+
new_user_2 = {}
|
|
298
|
+
@user2.each_pair {|k, v| new_user_2[k.to_sym] = v}
|
|
299
|
+
|
|
300
|
+
result = @test_users.befriend(new_user_1, new_user_2)
|
|
301
|
+
expect(result).to be_truthy
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it "accepts http options passed to both calls" do
|
|
305
|
+
options = {:some_http_option => true}
|
|
306
|
+
# should come twice, once for each user
|
|
307
|
+
@stubbed = true
|
|
308
|
+
expect(Koala.http_service).to receive(:make_request).twice do |request|
|
|
309
|
+
expect(request.raw_options).to eq(options)
|
|
310
|
+
Koala::HTTPService::Response.new(200, "{}", {})
|
|
311
|
+
end
|
|
312
|
+
@test_users.befriend(@user1, @user2, options)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it "includes the secret, generating the appsecret_proof in both calls if provided" do
|
|
316
|
+
# should come twice, once for each user
|
|
317
|
+
@stubbed = true
|
|
318
|
+
test_users = Koala::Facebook::TestUsers.new({:secret => @secret, :app_id => @app_id})
|
|
319
|
+
expect(Koala.http_service).to receive(:make_request).twice do |request|
|
|
320
|
+
expect(request.post_args).to include("appsecret_proof")
|
|
321
|
+
Koala::HTTPService::Response.new(200, "{}", {})
|
|
322
|
+
end
|
|
323
|
+
test_users.befriend(@user1, @user2)
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
end # when used without network
|
|
327
|
+
|
|
328
|
+
describe "#test_user_accounts_path" do
|
|
329
|
+
it "returns the app_id/accounts/test-users" do
|
|
330
|
+
expect(@test_users.test_user_accounts_path).to eq("/#{@app_id}/accounts/test-users")
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
describe "when creating a network of friends" do
|
|
335
|
+
before :each do
|
|
336
|
+
@network = []
|
|
337
|
+
|
|
338
|
+
if KoalaTest.mock_interface?
|
|
339
|
+
id_counter = 999999900
|
|
340
|
+
allow(@test_users).to receive(:create) do
|
|
341
|
+
id_counter += 1
|
|
342
|
+
{"id" => id_counter, "access_token" => @token, "login_url" => "https://www.facebook.com/platform/test_account.."}
|
|
343
|
+
end
|
|
344
|
+
allow(@test_users).to receive(:befriend).and_return(true)
|
|
345
|
+
allow(@test_users).to receive(:delete).and_return(true)
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
describe "tests that create users" do
|
|
350
|
+
it "creates a 5 person network" do
|
|
351
|
+
size = 5
|
|
352
|
+
@network = @test_users.create_network(size)
|
|
353
|
+
expect(@network).to be_a(Array)
|
|
354
|
+
expect(@network.size).to eq(size)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
it "has no built-in network size limit" do
|
|
359
|
+
times = 100
|
|
360
|
+
expect(@test_users).to receive(:create).exactly(times).times
|
|
361
|
+
allow(@test_users).to receive(:befriend)
|
|
362
|
+
@test_users.create_network(times)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
it "passes on the installed and permissions parameters to create" do
|
|
366
|
+
perms = ["read_stream", "offline_access"]
|
|
367
|
+
installed = false
|
|
368
|
+
count = 25
|
|
369
|
+
expect(@test_users).to receive(:create).exactly(count).times.with(installed, perms, anything, anything)
|
|
370
|
+
allow(@test_users).to receive(:befriend)
|
|
371
|
+
@test_users.create_network(count, installed, perms)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "accepts http options that are passed to both the create and befriend calls" do
|
|
375
|
+
count = 25
|
|
376
|
+
options = {:some_http_option => true}
|
|
377
|
+
expect(@test_users).to receive(:create).exactly(count).times.with(anything, anything, anything, options).and_return({})
|
|
378
|
+
# there are more befriends than creates, but we don't need to do the extra work to calculate out the exact #
|
|
379
|
+
expect(@test_users).to receive(:befriend).at_least(count).times.with(anything, anything, options)
|
|
380
|
+
@test_users.create_network(count, true, "", options)
|
|
381
|
+
end
|
|
382
|
+
end # when creating network
|
|
383
|
+
end # describe Koala TestUsers
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# fake MIME::Types
|
|
2
|
+
module Koala::MIME
|
|
3
|
+
module Types
|
|
4
|
+
def self.type_for(type)
|
|
5
|
+
# this should be faked out in tests
|
|
6
|
+
nil
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "Koala::HTTPService::UploadableIO" do
|
|
12
|
+
def rails_3_mocks
|
|
13
|
+
tempfile = double('Tempfile', :path => "foo")
|
|
14
|
+
uploaded_file = double('ActionDispatch::Http::UploadedFile',
|
|
15
|
+
:content_type => true,
|
|
16
|
+
:tempfile => tempfile,
|
|
17
|
+
:original_filename => "bar"
|
|
18
|
+
)
|
|
19
|
+
allow(tempfile).to receive(: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
|
+
|
|
28
|
+
describe "the constructor" do
|
|
29
|
+
describe "when given a file path" do
|
|
30
|
+
before(:each) do
|
|
31
|
+
@path = BEACH_BALL_PATH
|
|
32
|
+
@koala_io_params = [@path]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "and a content type" do
|
|
36
|
+
before :each do
|
|
37
|
+
@stub_type = double("image/jpg")
|
|
38
|
+
@koala_io_params.concat([@stub_type])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns an UploadIO with the same file path" do
|
|
42
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).io_or_path).to eq(@path)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "returns an UploadIO with the same content type" do
|
|
46
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).content_type).to eq(@stub_type)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "returns an UploadIO with the file's name" do
|
|
50
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).filename).to eq(File.basename(@path))
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "and no content type" do
|
|
55
|
+
it_should_behave_like "determining a mime type"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "when given a File object" do
|
|
60
|
+
before(:each) do
|
|
61
|
+
@file = File.open(BEACH_BALL_PATH)
|
|
62
|
+
@koala_io_params = [@file]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "and a content type" do
|
|
66
|
+
before :each do
|
|
67
|
+
@koala_io_params.concat(["image/jpg"])
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "returns an UploadIO with the same io" do
|
|
71
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).io_or_path).to eq(@koala_io_params[0])
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "returns an UploadableIO with the same content_type" do
|
|
75
|
+
content_stub = @koala_io_params[1] = double('Content Type')
|
|
76
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).content_type).to eq(content_stub)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "returns an UploadableIO with the right filename" do
|
|
80
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).filename).to eq(File.basename(@file.path))
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe "and no content type" do
|
|
85
|
+
it_should_behave_like "determining a mime type"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
describe "when given a Tempfile object" do
|
|
91
|
+
before(:each) do
|
|
92
|
+
@file = Tempfile.new('coucou')
|
|
93
|
+
@koala_io_params = [@file]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe "and a content type" do
|
|
97
|
+
before :each do
|
|
98
|
+
@koala_io_params.concat(["image/jpg"])
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "returns an UploadIO with the same io" do
|
|
102
|
+
#Problem comparing Tempfile in Ruby 1.8, REE and Rubinius mode 1.8
|
|
103
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).io_or_path.path).to eq(@koala_io_params[0].path)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "returns an UploadableIO with the same content_type" do
|
|
107
|
+
content_stub = @koala_io_params[1] = double('Content Type')
|
|
108
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).content_type).to eq(content_stub)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "returns an UploadableIO with the right filename" do
|
|
112
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).filename).to eq(File.basename(@file.path))
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "and no content type" do
|
|
117
|
+
it_should_behave_like "determining a mime type"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe "when given an IO object" do
|
|
122
|
+
before(:each) do
|
|
123
|
+
@io = StringIO.open("abcdefgh")
|
|
124
|
+
@koala_io_params = [@io]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "and a content type" do
|
|
128
|
+
before :each do
|
|
129
|
+
@koala_io_params.concat(["image/jpg"])
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "returns an UploadableIO with the same io" do
|
|
133
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).io_or_path).to eq(@koala_io_params[0])
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "returns an UploadableIO with the same content_type" do
|
|
137
|
+
content_stub = @koala_io_params[1] = double('Content Type')
|
|
138
|
+
expect(Koala::HTTPService::UploadableIO.new(*@koala_io_params).content_type).to eq(content_stub)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe "and no content type" do
|
|
143
|
+
it "raises an exception" do
|
|
144
|
+
expect { Koala::HTTPService::UploadableIO.new(*@koala_io_params) }.to raise_exception(Koala::KoalaError)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
describe "when given a Rails 3 ActionDispatch::Http::UploadedFile" do
|
|
150
|
+
before(:each) do
|
|
151
|
+
@tempfile, @uploaded_file = rails_3_mocks
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "gets the path from the tempfile associated with the UploadedFile" do
|
|
155
|
+
expected_path = double('Tempfile')
|
|
156
|
+
expect(@tempfile).to receive(:path).and_return(expected_path)
|
|
157
|
+
expect(Koala::HTTPService::UploadableIO.new(@uploaded_file).io_or_path).to eq(expected_path)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "gets the content type via the content_type method" do
|
|
161
|
+
expected_content_type = double('Content Type')
|
|
162
|
+
expect(@uploaded_file).to receive(:content_type).and_return(expected_content_type)
|
|
163
|
+
expect(Koala::HTTPService::UploadableIO.new(@uploaded_file).content_type).to eq(expected_content_type)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "gets the filename from the UploadedFile" do
|
|
167
|
+
expect(Koala::HTTPService::UploadableIO.new(@uploaded_file).filename).to eq(@uploaded_file.original_filename)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
describe "when given a Sinatra file parameter hash" do
|
|
172
|
+
before(:each) do
|
|
173
|
+
@file_hash = sinatra_mocks
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "gets the io_or_path from the :tempfile key" do
|
|
177
|
+
expected_file = double('File')
|
|
178
|
+
@file_hash[:tempfile] = expected_file
|
|
179
|
+
|
|
180
|
+
uploadable = Koala::HTTPService::UploadableIO.new(@file_hash)
|
|
181
|
+
expect(uploadable.io_or_path).to eq(expected_file)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "gets the content type from the :type key" do
|
|
185
|
+
expected_content_type = double('Content Type')
|
|
186
|
+
@file_hash[:type] = expected_content_type
|
|
187
|
+
|
|
188
|
+
uploadable = Koala::HTTPService::UploadableIO.new(@file_hash)
|
|
189
|
+
expect(uploadable.content_type).to eq(expected_content_type)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "gets the content type from the :type key" do
|
|
193
|
+
uploadable = Koala::HTTPService::UploadableIO.new(@file_hash)
|
|
194
|
+
expect(uploadable.filename).to eq(@file_hash[:filename])
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
describe "for files with with recognizable MIME types" do
|
|
199
|
+
# what that means is tested below
|
|
200
|
+
it "should accept a file object alone" do
|
|
201
|
+
params = [BEACH_BALL_PATH]
|
|
202
|
+
expect { Koala::HTTPService::UploadableIO.new(*params) }.not_to raise_exception
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "should accept a file path alone" do
|
|
206
|
+
params = [BEACH_BALL_PATH]
|
|
207
|
+
expect { Koala::HTTPService::UploadableIO.new(*params) }.not_to raise_exception
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
describe "getting an UploadableIO" do
|
|
213
|
+
before(:each) do
|
|
214
|
+
@upload_io = double("UploadIO")
|
|
215
|
+
allow(UploadIO).to receive(:new).with(anything, anything, anything).and_return(@upload_io)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
context "if no filename was provided" do
|
|
219
|
+
it "should call the constructor with the content type, file name, and a dummy file name" do
|
|
220
|
+
expect(UploadIO).to receive(:new).with(BEACH_BALL_PATH, "content/type", anything).and_return(@upload_io)
|
|
221
|
+
expect(Koala::HTTPService::UploadableIO.new(BEACH_BALL_PATH, "content/type").to_upload_io).to eq(@upload_io)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context "if a filename was provided" do
|
|
226
|
+
it "should call the constructor with the content type, file name, and the filename" do
|
|
227
|
+
filename = "file"
|
|
228
|
+
expect(UploadIO).to receive(:new).with(BEACH_BALL_PATH, "content/type", filename).and_return(@upload_io)
|
|
229
|
+
Koala::HTTPService::UploadableIO.new(BEACH_BALL_PATH, "content/type", filename).to_upload_io
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
describe "getting a file" do
|
|
235
|
+
it "returns the File if initialized with a file" do
|
|
236
|
+
f = File.new(BEACH_BALL_PATH)
|
|
237
|
+
expect(Koala::HTTPService::UploadableIO.new(f).to_file).to eq(f)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "should open up and return a file corresponding to the path if io_or_path is a path" do
|
|
241
|
+
result = double("File")
|
|
242
|
+
expect(File).to receive(:open).with(BEACH_BALL_PATH).and_return(result)
|
|
243
|
+
expect(Koala::HTTPService::UploadableIO.new(BEACH_BALL_PATH).to_file).to eq(result)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
describe ".binary_content?" do
|
|
248
|
+
it "returns true for Rails 3 file uploads" do
|
|
249
|
+
expect(Koala::HTTPService::UploadableIO.binary_content?(rails_3_mocks.last)).to be_truthy
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "returns true for Sinatra file uploads" do
|
|
253
|
+
expect(Koala::HTTPService::UploadableIO.binary_content?(rails_3_mocks.last)).to be_truthy
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "returns true for File objects" do
|
|
257
|
+
expect(Koala::HTTPService::UploadableIO.binary_content?(File.open(BEACH_BALL_PATH))).to be_truthy
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "returns false for everything else" do
|
|
261
|
+
expect(Koala::HTTPService::UploadableIO.binary_content?(StringIO.new)).to be_falsey
|
|
262
|
+
expect(Koala::HTTPService::UploadableIO.binary_content?(BEACH_BALL_PATH)).to be_falsey
|
|
263
|
+
expect(Koala::HTTPService::UploadableIO.binary_content?(nil)).to be_falsey
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end # describe UploadableIO
|