koala 0.10.0 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,86 @@
1
+ shared_examples_for "Koala GraphAPI" do
2
+ # all Graph API instances should pass these tests, regardless of configuration
3
+
4
+ # API
5
+ it "should never use the rest api server" do
6
+ Koala.should_receive(:make_request).with(
7
+ anything,
8
+ anything,
9
+ anything,
10
+ hash_not_including(:rest_api => true)
11
+ ).and_return(Koala::Response.new(200, "", {}))
12
+
13
+ @api.api("anything")
14
+ end
15
+
16
+ # GRAPH CALL
17
+ describe "graph_call" do
18
+ it "should pass all arguments to the api method" do
19
+ args = ["koppel", {}, "get", {:a => :b}]
20
+
21
+ @api.should_receive(:api).with(*args)
22
+
23
+ @api.graph_call(*args)
24
+ end
25
+
26
+ it "should throw an APIError if the result hash has an error key" do
27
+ Koala.stub(:make_request).and_return(Koala::Response.new(500, {"error" => "An error occurred!"}, {}))
28
+ lambda { @api.graph_call("koppel", {}) }.should raise_exception(Koala::Facebook::APIError)
29
+ end
30
+ end
31
+
32
+ # SEARCH
33
+ it "should be able to search" do
34
+ result = @api.search("facebook")
35
+ result.length.should be_an(Integer)
36
+ end
37
+
38
+ # DATA
39
+ # access public info
40
+
41
+ it "should get public data about a user" do
42
+ result = @api.get_object("koppel")
43
+ # the results should have an ID and a name, among other things
44
+ (result["id"] && result["name"]).should_not be_nil
45
+ end
46
+
47
+ it "should get public data about a Page" do
48
+ result = @api.get_object("contextoptional")
49
+ # the results should have an ID and a name, among other things
50
+ (result["id"] && result["name"]).should
51
+ end
52
+
53
+ it "should be able to get multiple objects" do
54
+ results = @api.get_objects(["contextoptional", "naitik"])
55
+ results.length.should == 2
56
+ end
57
+
58
+ it "should be able to access a user's picture" do
59
+ @api.get_picture("chris.baclig").should =~ /http\:\/\//
60
+ end
61
+
62
+ it "should be able to access a user's picture, given a picture type" do
63
+ @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
64
+ end
65
+
66
+ it "should be able to access connections from public Pages" do
67
+ result = @api.get_connections("contextoptional", "photos")
68
+ result.should be_a(Array)
69
+ end
70
+
71
+ # SEARCH
72
+ it "should be able to search" do
73
+ result = @api.search("facebook")
74
+ result.length.should be_an(Integer)
75
+ end
76
+
77
+ # PAGING THROUGH COLLECTIONS
78
+ # see also graph_collection_tests
79
+ it "should make a request for a page when provided a specific set of page params" do
80
+ query = [1, 2]
81
+ @api.should_receive(:graph_call).with(*query)
82
+ @api.get_page(query)
83
+ end
84
+
85
+
86
+ end
@@ -1,150 +1,154 @@
1
1
  shared_examples_for "Koala GraphAPI with an access token" do
2
- it "should get public data about a user" do
3
- result = @api.get_object("koppel")
4
- # the results should have an ID and a name, among other things
5
- (result["id"] && result["name"]).should_not be_nil
6
- end
7
2
 
8
- it "should get private data about a user" do
9
- result = @api.get_object("koppel")
10
- # updated_time should be a pretty fixed test case
11
- result["updated_time"].should_not be_nil
12
- end
3
+ it "should get private data about a user" do
4
+ result = @api.get_object("koppel")
5
+ # updated_time should be a pretty fixed test case
6
+ result["updated_time"].should_not be_nil
7
+ end
13
8
 
14
- it "should get public data about a Page" do
15
- result = @api.get_object("contextoptional")
16
- # the results should have an ID and a name, among other things
17
- (result["id"] && result["name"]).should
18
- end
19
-
20
- it "should get data about 'me'" do
21
- result = @api.get_object("me")
22
- result["updated_time"].should
23
- end
24
-
25
- it "should be able to get multiple objects" do
26
- result = @api.get_objects(["contextoptional", "naitik"])
27
- result.length.should == 2
28
- end
29
-
30
- it "should be able to access a user's picture" do
31
- @api.get_picture("chris.baclig").should =~ /http\:\/\//
32
- end
33
-
34
- it "should be able to access a user's picture, given a picture type" do
35
- @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
36
- end
9
+ it "should get data about 'me'" do
10
+ result = @api.get_object("me")
11
+ result["updated_time"].should
12
+ end
13
+
14
+ it "should be able to get multiple objects" do
15
+ result = @api.get_objects(["contextoptional", "naitik"])
16
+ result.length.should == 2
17
+ end
18
+ it "should be able to access connections from users" do
19
+ result = @api.get_connections("lukeshepard", "likes")
20
+ result.length.should > 0
21
+ end
22
+
23
+ # PUT
24
+ it "should be able to write an object to the graph" do
25
+ result = @api.put_wall_post("Hello, world, from the test suite!")
26
+ @temporary_object_id = result["id"]
27
+ @temporary_object_id.should_not be_nil
28
+ end
29
+
30
+ # DELETE
31
+ it "should be able to delete posts" do
32
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
33
+ object_id_to_delete = result["id"]
34
+ delete_result = @api.delete_object(object_id_to_delete)
35
+ delete_result.should == true
36
+ end
37
37
 
38
- it "should be able to access connections from users" do
39
- result = @api.get_connections("lukeshepard", "likes")
40
- result.length.should > 0
41
- end
38
+ it "should be able to delete likes" do
39
+ result = @api.put_wall_post("Hello, world, from the test suite delete method!")
40
+ @temporary_object_id = result["id"]
41
+ @api.put_like(@temporary_object_id)
42
+ delete_like_result = @api.delete_like(@temporary_object_id)
43
+ delete_like_result.should == true
44
+ end
42
45
 
43
- it "should be able to access connections from public Pages" do
44
- result = @api.get_connections("contextoptional", "photos")
45
- result.should be_a(Array)
46
- end
46
+ # additional put tests
47
+ it "should be able to verify messages posted to a wall" do
48
+ message = "the cats are asleep"
49
+ put_result = @api.put_wall_post(message)
50
+ @temporary_object_id = put_result["id"]
51
+ get_result = @api.get_object(@temporary_object_id)
52
+
53
+ # make sure the message we sent is the message that got posted
54
+ get_result["message"].should == message
55
+ end
56
+
57
+ it "should be able to post a message with an attachment to a feed" do
58
+ result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "Context Optional", :link => "http://www.contextoptional.com/"})
59
+ @temporary_object_id = result["id"]
60
+ @temporary_object_id.should_not be_nil
61
+ end
62
+
63
+ it "should be able to post photos to the user's wall with an open file object" do
64
+ file_hash = {
65
+ "content_type" => "image/jpg",
66
+ "path" => File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg"),
67
+ "file" => File.open(File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg"))
68
+ }
69
+ result = @api.put_picture(file_hash)
70
+ @temporary_object_id = result["id"]
71
+ @temporary_object_id.should_not be_nil
72
+ end
73
+
74
+ it "should be able to post photos to the user's wall without an open file object" do
75
+ file_hash = {
76
+ "content_type" => "image/jpg",
77
+ "path" => File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg")
78
+ }
79
+ result = @api.put_picture(file_hash)
80
+ @temporary_object_id = result["id"]
81
+ @temporary_object_id.should_not be_nil
82
+ end
47
83
 
48
- # paging
49
- # see also graph_collection_tests
50
- it "should make a request for a page when provided a specific set of page params" do
51
- query = [1, 2]
52
- @api.should_receive(:graph_call).with(*query)
53
- @api.get_page(query)
54
- end
84
+ it "should be able to verify a photo posted to a user's wall" do
85
+ file_hash = {
86
+ "content_type" => "image/jpg",
87
+ "path" => File.join(File.dirname(__FILE__), "..", "assets", "beach.jpg")
88
+ }
89
+ expected_message = "This is the test message"
55
90
 
91
+ result = @api.put_picture(file_hash, :message => expected_message)
92
+ @temporary_object_id = result["id"]
93
+ @temporary_object_id.should_not be_nil
56
94
 
57
- # PUT
58
- it "should be able to write an object to the graph" do
59
- result = @api.put_wall_post("Hello, world, from the test suite!")
60
- @temporary_object_id = result["id"]
61
- @temporary_object_id.should_not be_nil
62
- end
63
-
64
- # DELETE
65
- it "should be able to delete posts" do
66
- result = @api.put_wall_post("Hello, world, from the test suite delete method!")
67
- object_id_to_delete = result["id"]
68
- delete_result = @api.delete_object(object_id_to_delete)
69
- delete_result.should == true
70
- end
95
+ get_result = @api.get_object(@temporary_object_id)
96
+ get_result["name"].should == expected_message
97
+ end
98
+
99
+ it "should be able to verify a message with an attachment posted to a feed" do
100
+ attachment = {"name" => "Context Optional", "link" => "http://www.contextoptional.com/"}
101
+ result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
102
+ @temporary_object_id = result["id"]
103
+ get_result = @api.get_object(@temporary_object_id)
71
104
 
72
- # additional put tests
73
- it "should be able to verify messages posted to a wall" do
74
- message = "the cats are asleep"
75
- put_result = @api.put_wall_post(message)
76
- @temporary_object_id = put_result["id"]
77
- get_result = @api.get_object(@temporary_object_id)
78
-
79
- # make sure the message we sent is the message that got posted
80
- get_result["message"].should == message
81
- end
105
+ # make sure the result we fetch includes all the parameters we sent
106
+ it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
107
+ it_matches.should == true
108
+ end
82
109
 
83
- it "should be able to post a message with an attachment to a feed" do
84
- result = @api.put_wall_post("Hello, world, from the test suite again!", {:name => "Context Optional", :link => "http://www.contextoptional.com/"})
85
- @temporary_object_id = result["id"]
86
- @temporary_object_id.should_not be_nil
87
- end
88
-
89
- it "should be able to verify a message with an attachment posted to a feed" do
90
- attachment = {"name" => "Context Optional", "link" => "http://www.contextoptional.com/"}
91
- result = @api.put_wall_post("Hello, world, from the test suite again!", attachment)
92
- @temporary_object_id = result["id"]
93
- get_result = @api.get_object(@temporary_object_id)
94
-
95
- # make sure the result we fetch includes all the parameters we sent
96
- it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
97
- it_matches.should == true
98
- end
110
+ it "should be able to comment on an object" do
111
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
112
+ @temporary_object_id = result["id"]
99
113
 
100
- it "should be able to comment on an object" do
101
- result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
102
- @temporary_object_id = result["id"]
103
-
104
- # this will be deleted when the post gets deleted
105
- comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
106
- comment_result.should_not be_nil
107
- end
108
-
109
- it "should be able to verify a comment posted about an object" do
110
- message_text = "Hello, world, from the test suite, testing comments!"
111
- result = @api.put_wall_post(message_text)
112
- @temporary_object_id = result["id"]
113
-
114
- # this will be deleted when the post gets deleted
115
- comment_text = "it's my comment!"
116
- comment_result = @api.put_comment(@temporary_object_id, comment_text)
117
- get_result = @api.get_object(comment_result["id"])
118
-
119
- # make sure the text of the comment matches what we sent
120
- get_result["message"].should == comment_text
121
- end
114
+ # this will be deleted when the post gets deleted
115
+ comment_result = @api.put_comment(@temporary_object_id, "it's my comment!")
116
+ comment_result.should_not be_nil
117
+ end
122
118
 
123
- it "should be able to like an object" do
124
- result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
125
- @temporary_object_id = result["id"]
126
- like_result = @api.put_like(@temporary_object_id)
127
- end
119
+ it "should be able to verify a comment posted about an object" do
120
+ message_text = "Hello, world, from the test suite, testing comments!"
121
+ result = @api.put_wall_post(message_text)
122
+ @temporary_object_id = result["id"]
128
123
 
129
- # SEARCH
130
- it "should be able to search" do
131
- result = @api.search("facebook")
132
- result.length.should be_an(Integer)
133
- end
124
+ # this will be deleted when the post gets deleted
125
+ comment_text = "it's my comment!"
126
+ comment_result = @api.put_comment(@temporary_object_id, comment_text)
127
+ get_result = @api.get_object(comment_result["id"])
134
128
 
135
- # API
136
- # the above tests test this already, but we should consider additional api tests
129
+ # make sure the text of the comment matches what we sent
130
+ get_result["message"].should == comment_text
131
+ end
137
132
 
138
- it_should_behave_like "Koala GraphAPI with GraphCollection"
133
+ it "should be able to like an object" do
134
+ result = @api.put_wall_post("Hello, world, from the test suite, testing comments!")
135
+ @temporary_object_id = result["id"]
136
+ like_result = @api.put_like(@temporary_object_id)
137
+ like_result.should be_true
138
+ end
139
139
  end
140
140
 
141
141
  class FacebookWithAccessTokenTests < Test::Unit::TestCase
142
142
  describe "Koala GraphAPI with an access token" do
143
143
  include LiveTestingDataHelper
144
- it_should_behave_like "Koala GraphAPI with an access token"
145
-
144
+
146
145
  before :each do
147
146
  @api = Koala::Facebook::GraphAPI.new(@token)
148
147
  end
148
+
149
+ it_should_behave_like "Koala GraphAPI"
150
+ it_should_behave_like "Koala GraphAPI with an access token"
151
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
152
+
149
153
  end
150
154
  end
@@ -19,7 +19,7 @@ module LiveTestingDataHelper
19
19
  errors = []
20
20
 
21
21
  if count > 0
22
- print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object"}..."
22
+ print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object (#{@temporary_object_ids.first})"}..."
23
23
  @temporary_object_ids.each do |id|
24
24
  # get our API
25
25
  api = @api || (@test_users ? @test_users.graph_api : nil)
@@ -5,10 +5,19 @@ class NetHTTPServiceTests < Test::Unit::TestCase
5
5
  end
6
6
 
7
7
  describe "NetHTTPService module holder class Bear" do
8
+ before :each do
9
+ # reset the always_use_ssl parameter
10
+ Bear.always_use_ssl = nil
11
+ end
12
+
8
13
  it "should define a make_request static module method" do
9
14
  Bear.respond_to?(:make_request).should be_true
10
15
  end
11
16
 
17
+ it "should include the Koala::HTTPService module defining common features" do
18
+ Bear.included_modules.include?(Koala::HTTPService).should be_true
19
+ end
20
+
12
21
  describe "when making a request" do
13
22
  before(:each) do
14
23
  # Setup stubs for make_request to execute without exceptions
@@ -16,7 +25,7 @@ class NetHTTPServiceTests < Test::Unit::TestCase
16
25
  @mock_body = stub('Net::HTTPResponse body')
17
26
  @http_request_result = [@mock_http_response, @mock_body]
18
27
 
19
- # to_ary is called in Ruby 1.9 to provide backwards compatibility
28
+ # to_ary is called in Ruby 1.9 to provide backwards compatibility
20
29
  # with the response, body = http.get() syntax we use
21
30
  @mock_http_response.stub!(:to_ary).and_return(@http_request_result)
22
31
 
@@ -31,33 +40,102 @@ class NetHTTPServiceTests < Test::Unit::TestCase
31
40
  Net::HTTP.stub(:new).and_return(@http_mock)
32
41
  end
33
42
 
34
- it "should use POST if verb is not GET" do
35
- @http_yield_mock.should_receive(:post).and_return(@mock_http_response)
36
- @http_mock.should_receive(:start).and_yield(@http_yield_mock)
43
+ describe "the connection" do
44
+ it "should use POST if verb is not GET" do
45
+ @http_yield_mock.should_receive(:post).and_return(@mock_http_response)
46
+ @http_mock.should_receive(:start).and_yield(@http_yield_mock)
37
47
 
38
- Bear.make_request('anything', {}, 'anything')
48
+ Bear.make_request('anything', {}, 'anything')
49
+ end
50
+
51
+ it "should use GET if that verb is specified" do
52
+ @http_yield_mock.should_receive(:get).and_return(@mock_http_response)
53
+ @http_mock.should_receive(:start).and_yield(@http_yield_mock)
54
+
55
+ Bear.make_request('anything', {}, 'get')
56
+ end
57
+
58
+ it "should add the method to the arguments if it's not get or post" do
59
+ args = {}
60
+ method = "telekenesis"
61
+ # since the arguments get encoded later, we'll test for merge!
62
+ # even though that's somewhat testing internal implementation
63
+ args.should_receive(:merge!).with(:method => method)
64
+
65
+ Bear.make_request('anything', args, method)
66
+ end
39
67
  end
40
68
 
41
- it "should use port 443" do
42
- Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
69
+ describe "if the request has an access token" do
70
+ before :each do
71
+ @args = {"access_token" => "123"}
72
+ end
43
73
 
44
- Bear.make_request('anything', {}, 'anything')
74
+ it "should use SSL" do
75
+ @http_mock.should_receive('use_ssl=').with(true)
76
+
77
+ Bear.make_request('anything', @args, 'anything')
78
+ end
79
+
80
+ it "should set the port to 443" do
81
+ Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
82
+
83
+ Bear.make_request('anything', @args, 'anything')
84
+ end
45
85
  end
46
86
 
47
- it "should use SSL" do
48
- @http_mock.should_receive('use_ssl=').with(true)
87
+ describe "if always_use_ssl is true" do
88
+ before :each do
89
+ Bear.always_use_ssl = true
90
+ end
91
+
92
+ it "should use SSL" do
93
+ @http_mock.should_receive('use_ssl=').with(true)
49
94
 
50
- Bear.make_request('anything', {}, 'anything')
95
+ Bear.make_request('anything', {}, 'anything')
96
+ end
97
+
98
+ it "should set the port to 443" do
99
+ Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
100
+
101
+ Bear.make_request('anything', {}, 'anything')
102
+ end
103
+ end
104
+
105
+ describe "if the use_ssl option is provided" do
106
+ it "should use SSL" do
107
+ @http_mock.should_receive('use_ssl=').with(true)
108
+
109
+ Bear.make_request('anything', {}, 'anything', :use_ssl => true)
110
+ end
111
+
112
+ it "should set the port to 443" do
113
+ Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
114
+
115
+ Bear.make_request('anything', {}, 'anything', :use_ssl => true)
116
+ end
117
+ end
118
+
119
+ describe "if there's no token and always_use_ssl isn't true" do
120
+ it "should not use SSL" do
121
+ @http_mock.should_not_receive('use_ssl=')
122
+ Bear.make_request('anything', {}, 'anything')
123
+ end
124
+
125
+ it "should not set the port" do
126
+ Net::HTTP.should_receive(:new).with(anything, nil).and_return(@http_mock)
127
+ Bear.make_request('anything', {}, 'anything')
128
+ end
51
129
  end
52
130
 
53
131
  it "should use the graph server by default" do
54
132
  Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything).and_return(@http_mock)
55
- Bear.make_request('anything', {}, 'anything')
133
+ Bear.make_request('anything', {}, 'anything')
56
134
  end
57
135
 
58
136
  it "should use the REST server if the :rest_api option is true" do
59
137
  Net::HTTP.should_receive(:new).with(Koala::Facebook::REST_SERVER, anything).and_return(@http_mock)
60
- Bear.make_request('anything', {}, 'anything', :rest_api => true)
138
+ Bear.make_request('anything', {}, 'anything', :rest_api => true)
61
139
  end
62
140
 
63
141
  it "should turn off vertificate validaiton warnings" do
@@ -82,7 +160,7 @@ class NetHTTPServiceTests < Test::Unit::TestCase
82
160
  path = mock('Path')
83
161
  @http_yield_mock.should_receive(:post).with(path, anything).and_return(@http_request_result)
84
162
 
85
- Bear.make_request(path, {}, 'post')
163
+ Bear.make_request(path, {}, 'post')
86
164
  end
87
165
 
88
166
  it "should use encoded parameters" do
@@ -94,6 +172,45 @@ class NetHTTPServiceTests < Test::Unit::TestCase
94
172
 
95
173
  Bear.make_request('anything', args, 'post')
96
174
  end
175
+
176
+ describe "with multipart/form-data" do
177
+ before(:each) do
178
+ Bear.stub(:encode_multipart_params)
179
+ Bear.stub("params_require_multipart?").and_return(true)
180
+
181
+ @multipart_request_stub = stub('Stub Multipart Request')
182
+ Net::HTTP::Post::Multipart.stub(:new).and_return(@multipart_request_stub)
183
+
184
+ @file_stub = stub('fake File', "kind_of?" => true, "path" => 'anypath.jpg')
185
+
186
+ @http_yield_mock.stub(:request).with(@multipart_request_stub).and_return(@http_request_result)
187
+ end
188
+
189
+ it "should use multipart/form-data if any parameter is a valid file hash" do
190
+ @http_yield_mock.should_receive(:request).with(@multipart_request_stub).and_return(@http_request_result)
191
+
192
+ Bear.make_request('anything', {}, 'post')
193
+ end
194
+
195
+ it "should use the given request path for the request" do
196
+ args = {"file" => @file_stub}
197
+ expected_path = 'expected/path'
198
+
199
+ Net::HTTP::Post::Multipart.should_receive(:new).with(expected_path, anything).and_return(@multipart_request_stub)
200
+
201
+ Bear.make_request(expected_path, {}, 'post')
202
+ end
203
+
204
+ it "should use multipart encoded arguments for the request" do
205
+ args = {"file" => @file_stub}
206
+ expected_params = stub('Stub Multipart Params')
207
+
208
+ Bear.should_receive(:encode_multipart_params).with(args).and_return(expected_params)
209
+ Net::HTTP::Post::Multipart.should_receive(:new).with(anything, expected_params).and_return(@multipart_request_stub)
210
+
211
+ Bear.make_request('anything', args, 'post')
212
+ end
213
+ end
97
214
  end
98
215
 
99
216
  describe "via GET" do
@@ -125,7 +242,7 @@ class NetHTTPServiceTests < Test::Unit::TestCase
125
242
  end
126
243
 
127
244
  it "should return a Koala::Response with the right status" do
128
- @response.status.should == @mock_http_response.code
245
+ @response.status.should == @mock_http_response.code
129
246
  end
130
247
 
131
248
  it "should reutrn a Koala::Response with the right body" do
@@ -182,5 +299,132 @@ class NetHTTPServiceTests < Test::Unit::TestCase
182
299
  end
183
300
  end
184
301
  end
302
+
303
+ describe "when detecting if multipart posting is needed" do
304
+ it "should be true if any parameter value requires multipart post" do
305
+ valid_file_hash = stub("Stub Valid File Hash")
306
+
307
+ Bear.stub!("is_valid_file_hash?").and_return(false)
308
+ Bear.stub!("is_valid_file_hash?").with(valid_file_hash).and_return(true)
309
+
310
+ args = {
311
+ "key1" => "val",
312
+ "key2" => "val",
313
+ "key3" => valid_file_hash,
314
+ "key4" => "val"
315
+ }
316
+
317
+ Bear.params_require_multipart?(args).should be_true
318
+ end
319
+
320
+ describe "and looking at individual values" do
321
+ before(:each) do
322
+ @valid_hash = {
323
+ "content_type" => 1,
324
+ "path" => 1
325
+ }
326
+ end
327
+
328
+ it "should only accept hashes" do
329
+ Bear.is_valid_file_hash?(@valid_hash).should be_true
330
+
331
+ @valid_hash.stub!("kind_of?").with(Hash).and_return(false)
332
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
333
+ end
334
+
335
+ it "should always require a content_type key" do
336
+ @valid_hash.delete("content_type")
337
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
338
+ end
339
+
340
+ it "should always require the path key" do
341
+ @valid_hash.delete("path")
342
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
343
+ end
344
+
345
+ describe "with file IOs" do
346
+ before :each do
347
+ @stub_file = stub('Stub IO File')
348
+ @valid_hash["file"] = @stub_file
349
+ end
350
+
351
+ it "should accept hashes with the file object that responds to read" do
352
+ @stub_file.should_receive("respond_to?").with(:read).and_return(true)
353
+
354
+ @valid_hash["file"] = @stub_file
355
+ Bear.is_valid_file_hash?(@valid_hash).should be_true
356
+ end
357
+
358
+ it "should not accept hashes with a file object that does not respond to read" do
359
+ @stub_file.should_receive("respond_to?").with(:read).and_return(false)
360
+
361
+ @valid_hash["file"] = @stub_file
362
+ Bear.is_valid_file_hash?(@valid_hash).should be_false
363
+ end
364
+
365
+ end
366
+ end
367
+ end
368
+
369
+ describe "when encoding multipart/form-data params" do
370
+ it "should replace valid file hashes with file objects with UploadIO objects" do
371
+ file_hash_stub = {
372
+ "path" => "Fake File Name",
373
+ "content_type" => "Fake Content Type"
374
+ }
375
+
376
+ # UploadIO should be created
377
+ uploadio_stub = stub("UploadIO Shell Stub")
378
+ UploadIO.should_receive("new").with(file_hash_stub["path"], file_hash_stub["content_type"]).and_return(uploadio_stub)
379
+
380
+ # Ruby 1.9 test compatibility
381
+ content_stub = "UploadIOContent Stub"
382
+ uploadio_stub.stub(:to_ary).and_return([content_stub])
383
+
384
+ args = {
385
+ "not_a_file" => "not a file",
386
+ "file" => file_hash_stub
387
+ }
388
+
389
+ # Check that is_valid_file_hash is called on the file_hash_stub
390
+ Bear.stub!("is_valid_file_hash?").and_return(false)
391
+ Bear.should_receive("is_valid_file_hash?").with(file_hash_stub).and_return(true)
392
+
393
+ result = Bear.encode_multipart_params(args)
394
+
395
+ result["not_a_file"] == args["not_a_file"]
396
+ result["file"] == content_stub
397
+ end
398
+
399
+ it "should replace valid file hashes with file objects with UploadIO objects" do
400
+ file_hash_stub = {
401
+ "file" => "Fake File IO",
402
+ "path" => "Fake File Name",
403
+ "content_type" => "Fake Content Type"
404
+ }
405
+
406
+ # UploadIO should be created
407
+ uploadio_stub = stub("UploadIO Shell Stub")
408
+ UploadIO.should_receive("new").with(file_hash_stub["file"], file_hash_stub["content_type"], file_hash_stub["path"]).and_return(uploadio_stub)
409
+
410
+ # Ruby 1.9 test compatibility
411
+ content_stub = "UploadIOContent Stub"
412
+ uploadio_stub.stub(:to_ary).and_return([content_stub])
413
+
414
+ args = {
415
+ "not_a_file" => "not a file",
416
+ "file" => file_hash_stub
417
+ }
418
+
419
+ # Check that is_valid_file_hash is called on the file_hash_stub
420
+ Bear.stub!("is_valid_file_hash?").and_return(false)
421
+ Bear.should_receive("is_valid_file_hash?").with(file_hash_stub).and_return(true)
422
+
423
+ result = Bear.encode_multipart_params(args)
424
+
425
+ result["not_a_file"] == args["not_a_file"]
426
+ result["file"] == content_stub
427
+ end
428
+ end
185
429
  end
186
430
  end