spreedly 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. data/History.txt +6 -0
  2. data/Manifest.txt +66 -0
  3. data/README.txt +68 -0
  4. data/Rakefile +72 -0
  5. data/lib/spreedly.rb +154 -0
  6. data/lib/spreedly/common.rb +24 -0
  7. data/lib/spreedly/mock.rb +113 -0
  8. data/lib/spreedly/version.rb +3 -0
  9. data/test/spreedly_gem_test.rb +152 -0
  10. data/test/test_site.yml +2 -0
  11. data/vendor/httparty/History +108 -0
  12. data/vendor/httparty/MIT-LICENSE +20 -0
  13. data/vendor/httparty/Manifest +55 -0
  14. data/vendor/httparty/README +35 -0
  15. data/vendor/httparty/Rakefile +47 -0
  16. data/vendor/httparty/bin/httparty +98 -0
  17. data/vendor/httparty/cucumber.yml +1 -0
  18. data/vendor/httparty/examples/aaws.rb +32 -0
  19. data/vendor/httparty/examples/basic.rb +11 -0
  20. data/vendor/httparty/examples/delicious.rb +37 -0
  21. data/vendor/httparty/examples/google.rb +16 -0
  22. data/vendor/httparty/examples/rubyurl.rb +14 -0
  23. data/vendor/httparty/examples/twitter.rb +31 -0
  24. data/vendor/httparty/examples/whoismyrep.rb +10 -0
  25. data/vendor/httparty/features/basic_authentication.feature +20 -0
  26. data/vendor/httparty/features/command_line.feature +7 -0
  27. data/vendor/httparty/features/deals_with_http_error_codes.feature +26 -0
  28. data/vendor/httparty/features/handles_multiple_formats.feature +34 -0
  29. data/vendor/httparty/features/steps/env.rb +15 -0
  30. data/vendor/httparty/features/steps/httparty_response_steps.rb +26 -0
  31. data/vendor/httparty/features/steps/httparty_steps.rb +15 -0
  32. data/vendor/httparty/features/steps/mongrel_helper.rb +55 -0
  33. data/vendor/httparty/features/steps/remote_service_steps.rb +47 -0
  34. data/vendor/httparty/features/supports_redirection.feature +22 -0
  35. data/vendor/httparty/httparty.gemspec +37 -0
  36. data/vendor/httparty/lib/core_extensions.rb +189 -0
  37. data/vendor/httparty/lib/httparty.rb +201 -0
  38. data/vendor/httparty/lib/httparty/cookie_hash.rb +9 -0
  39. data/vendor/httparty/lib/httparty/exceptions.rb +7 -0
  40. data/vendor/httparty/lib/httparty/logging.rb +35 -0
  41. data/vendor/httparty/lib/httparty/module_inheritable_attributes.rb +25 -0
  42. data/vendor/httparty/lib/httparty/parsers.rb +4 -0
  43. data/vendor/httparty/lib/httparty/parsers/json.rb +74 -0
  44. data/vendor/httparty/lib/httparty/parsers/xml.rb +209 -0
  45. data/vendor/httparty/lib/httparty/request.rb +169 -0
  46. data/vendor/httparty/lib/httparty/response.rb +17 -0
  47. data/vendor/httparty/lib/httparty/version.rb +3 -0
  48. data/vendor/httparty/setup.rb +1585 -0
  49. data/vendor/httparty/spec/fixtures/delicious.xml +23 -0
  50. data/vendor/httparty/spec/fixtures/empty.xml +0 -0
  51. data/vendor/httparty/spec/fixtures/google.html +3 -0
  52. data/vendor/httparty/spec/fixtures/twitter.json +1 -0
  53. data/vendor/httparty/spec/fixtures/twitter.xml +403 -0
  54. data/vendor/httparty/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  55. data/vendor/httparty/spec/hash_spec.rb +49 -0
  56. data/vendor/httparty/spec/httparty/cookie_hash_spec.rb +38 -0
  57. data/vendor/httparty/spec/httparty/parsers/json_spec.rb +44 -0
  58. data/vendor/httparty/spec/httparty/parsers/xml_spec.rb +454 -0
  59. data/vendor/httparty/spec/httparty/request_spec.rb +203 -0
  60. data/vendor/httparty/spec/httparty/response_spec.rb +53 -0
  61. data/vendor/httparty/spec/httparty_spec.rb +259 -0
  62. data/vendor/httparty/spec/spec.opts +3 -0
  63. data/vendor/httparty/spec/spec_helper.rb +21 -0
  64. data/vendor/httparty/spec/string_spec.rb +29 -0
  65. data/vendor/httparty/website/css/common.css +47 -0
  66. data/vendor/httparty/website/index.html +74 -0
  67. metadata +141 -0
@@ -0,0 +1,203 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe HTTParty::Request do
4
+ def stub_response(body, code = 200)
5
+ unless @http
6
+ @http = Net::HTTP.new('localhost', 80)
7
+ @request.stub!(:http).and_return(@http)
8
+ @request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
9
+ end
10
+
11
+ response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body)
12
+ response.stub!(:body).and_return(body)
13
+
14
+ @http.stub!(:request).and_return(response)
15
+ response
16
+ end
17
+
18
+ before do
19
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
20
+ end
21
+
22
+ describe "#format" do
23
+ it "should return the correct parsing format" do
24
+ @request.format.should == :xml
25
+ end
26
+ end
27
+
28
+ describe 'http' do
29
+ it "should use ssl for port 443" do
30
+ request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443')
31
+ request.send(:http).use_ssl?.should == true
32
+ end
33
+
34
+ it 'should not use ssl for port 80' do
35
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://foobar.com')
36
+ @request.send(:http).use_ssl?.should == false
37
+ end
38
+
39
+ it "should use basic auth when configured" do
40
+ @request.options[:basic_auth] = {:username => 'foobar', :password => 'secret'}
41
+ @request.send(:setup_raw_request)
42
+ @request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil
43
+ end
44
+ end
45
+
46
+ describe '#format_from_mimetype' do
47
+ it 'should handle text/xml' do
48
+ ["text/xml", "text/xml; charset=iso8859-1"].each do |ct|
49
+ @request.send(:format_from_mimetype, ct).should == :xml
50
+ end
51
+ end
52
+
53
+ it 'should handle application/xml' do
54
+ ["application/xml", "application/xml; charset=iso8859-1"].each do |ct|
55
+ @request.send(:format_from_mimetype, ct).should == :xml
56
+ end
57
+ end
58
+
59
+ it 'should handle text/json' do
60
+ ["text/json", "text/json; charset=iso8859-1"].each do |ct|
61
+ @request.send(:format_from_mimetype, ct).should == :json
62
+ end
63
+ end
64
+
65
+ it 'should handle application/json' do
66
+ ["application/json", "application/json; charset=iso8859-1"].each do |ct|
67
+ @request.send(:format_from_mimetype, ct).should == :json
68
+ end
69
+ end
70
+
71
+ it 'should handle text/javascript' do
72
+ ["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct|
73
+ @request.send(:format_from_mimetype, ct).should == :json
74
+ end
75
+ end
76
+
77
+ it 'should handle application/javascript' do
78
+ ["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct|
79
+ @request.send(:format_from_mimetype, ct).should == :json
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'parsing responses' do
85
+ it 'should handle xml automatically' do
86
+ xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
87
+ @request.options[:format] = :xml
88
+ @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
89
+ end
90
+
91
+ it 'should handle json automatically' do
92
+ json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
93
+ @request.options[:format] = :json
94
+ @request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
95
+ end
96
+
97
+ it 'should handle yaml automatically' do
98
+ yaml = "books: \n book: \n name: Foo Bar!\n id: \"1234\"\n"
99
+ @request.options[:format] = :yaml
100
+ @request.send(:parse_response, yaml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
101
+ end
102
+
103
+ it "should include any HTTP headers in the returned response" do
104
+ @request.options[:format] = :html
105
+ response = stub_response "Content"
106
+ response.initialize_http_header("key" => "value")
107
+
108
+ @request.perform.headers.should == { "key" => ["value"] }
109
+ end
110
+
111
+ describe 'with non-200 responses' do
112
+
113
+ it 'should return a valid object for 4xx response' do
114
+ stub_response '<foo><bar>yes</bar></foo>', 401
115
+ resp = @request.perform
116
+ resp.code.should == 401
117
+ resp.body.should == "<foo><bar>yes</bar></foo>"
118
+ resp['foo']['bar'].should == "yes"
119
+ end
120
+
121
+ it 'should return a valid object for 5xx response' do
122
+ stub_response '<foo><bar>error</bar></foo>', 500
123
+ resp = @request.perform
124
+ resp.code.should == 500
125
+ resp.body.should == "<foo><bar>error</bar></foo>"
126
+ resp['foo']['bar'].should == "error"
127
+ end
128
+
129
+ end
130
+ end
131
+
132
+ it "should not attempt to parse empty responses" do
133
+ stub_response "", 204
134
+
135
+ @request.options[:format] = :xml
136
+ @request.perform.should be_nil
137
+ end
138
+
139
+ it "should not attempt to parse pure-whitespace responses" do
140
+ stub_response " ", 204
141
+
142
+ @request.options[:format] = :xml
143
+ @request.perform.should be_nil
144
+ end
145
+
146
+ it "should not fail for missing mime type" do
147
+ stub_response "Content for you"
148
+ @request.options[:format] = :html
149
+ @request.perform.should == 'Content for you'
150
+ end
151
+
152
+ describe "a request that redirects" do
153
+ before(:each) do
154
+ @redirect = stub_response("", 302)
155
+ @redirect['location'] = '/foo'
156
+
157
+ @ok = stub_response('<hash><foo>bar</foo></hash>', 200)
158
+ end
159
+
160
+ describe "once" do
161
+ before(:each) do
162
+ @http.stub!(:request).and_return(@redirect, @ok)
163
+ end
164
+
165
+ it "should be handled by GET transparently" do
166
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
167
+ end
168
+
169
+ it "should be handled by POST transparently" do
170
+ @request.http_method = Net::HTTP::Post
171
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
172
+ end
173
+
174
+ it "should be handled by DELETE transparently" do
175
+ @request.http_method = Net::HTTP::Delete
176
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
177
+ end
178
+
179
+ it "should be handled by PUT transparently" do
180
+ @request.http_method = Net::HTTP::Put
181
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
182
+ end
183
+ end
184
+
185
+ describe "infinitely" do
186
+ before(:each) do
187
+ @http.stub!(:request).and_return(@redirect)
188
+ end
189
+
190
+ it "should raise an exception" do
191
+ lambda { @request.perform }.should raise_error(HTTParty::RedirectionTooDeep)
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ describe HTTParty::Request, "with POST http method" do
198
+ it "should raise argument error if query is not a hash" do
199
+ lambda {
200
+ HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml, :query => 'astring').perform
201
+ }.should raise_error(ArgumentError)
202
+ end
203
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe HTTParty::Response do
4
+ describe "initialization" do
5
+ before do
6
+ @response_object = {'foo' => 'bar'}
7
+ @body = "{foo:'bar'}"
8
+ @code = 200
9
+ @response = HTTParty::Response.new(@response_object, @body, @code)
10
+ end
11
+
12
+ it "should set delegate" do
13
+ @response.delegate.should == @response_object
14
+ end
15
+
16
+ it "should set body" do
17
+ @response.body.should == @body
18
+ end
19
+
20
+ it "should set code" do
21
+ @response.code.should == @code
22
+ end
23
+ end
24
+
25
+ it "should be able to set headers during initialization" do
26
+ response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, {'foo' => 'bar'})
27
+ response.headers.should == {'foo' => 'bar'}
28
+ end
29
+
30
+ it "should send missing methods to delegate" do
31
+ response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200)
32
+ response['foo'].should == 'bar'
33
+ end
34
+
35
+ it "should be able to iterate delegate if it is array" do
36
+ response = HTTParty::Response.new([{'foo' => 'bar'}, {'foo' => 'baz'}], "[{foo:'bar'}, {foo:'baz'}]", 200)
37
+ response.size.should == 2
38
+ lambda {
39
+ response.each { |item| }
40
+ }.should_not raise_error
41
+ end
42
+
43
+ xit "should allow hashes to be accessed with dot notation" do
44
+ response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200)
45
+ response.foo.should == 'bar'
46
+ end
47
+
48
+ xit "should allow nested hashes to be accessed with dot notation" do
49
+ response = HTTParty::Response.new({'foo' => {'bar' => 'baz'}}, "{foo: {bar:'baz'}}", 200)
50
+ response.foo.should == {'bar' => 'baz'}
51
+ response.foo.bar.should == 'baz'
52
+ end
53
+ end
@@ -0,0 +1,259 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe HTTParty do
4
+ before(:each) do
5
+ @klass = Class.new
6
+ @klass.instance_eval { include HTTParty }
7
+ end
8
+
9
+ describe "base uri" do
10
+ before(:each) do
11
+ @klass.base_uri('api.foo.com/v1')
12
+ end
13
+
14
+ it "should have reader" do
15
+ @klass.base_uri.should == 'http://api.foo.com/v1'
16
+ end
17
+
18
+ it 'should have writer' do
19
+ @klass.base_uri('http://api.foobar.com')
20
+ @klass.base_uri.should == 'http://api.foobar.com'
21
+ end
22
+ end
23
+
24
+ describe "#normalize_base_uri" do
25
+ it "should add http if not present for non ssl requests" do
26
+ uri = HTTParty.normalize_base_uri('api.foobar.com')
27
+ uri.should == 'http://api.foobar.com'
28
+ end
29
+
30
+ it "should add https if not present for ssl requests" do
31
+ uri = HTTParty.normalize_base_uri('api.foo.com/v1:443')
32
+ uri.should == 'https://api.foo.com/v1:443'
33
+ end
34
+
35
+ it "should not remove https for ssl requests" do
36
+ uri = HTTParty.normalize_base_uri('https://api.foo.com/v1:443')
37
+ uri.should == 'https://api.foo.com/v1:443'
38
+ end
39
+ end
40
+
41
+ describe "headers" do
42
+ it "should default to empty hash" do
43
+ @klass.headers.should == {}
44
+ end
45
+
46
+ it "should be able to be updated" do
47
+ init_headers = {:foo => 'bar', :baz => 'spax'}
48
+ @klass.headers init_headers
49
+ @klass.headers.should == init_headers
50
+ end
51
+ end
52
+
53
+ describe "cookies" do
54
+ def expect_cookie_header(s)
55
+ HTTParty::Request.should_receive(:new) \
56
+ .with(anything, anything, hash_including({ :headers => { "cookie" => s } })) \
57
+ .and_return(mock("mock response", :perform => nil))
58
+ end
59
+
60
+ it "should not be in the headers by default" do
61
+ HTTParty::Request.stub!(:new).and_return(stub(nil, :perform => nil))
62
+ @klass.get("")
63
+ @klass.headers.keys.should_not include("cookie")
64
+ end
65
+
66
+ it "should raise an ArgumentError if passed a non-Hash" do
67
+ lambda do
68
+ @klass.cookies("nonsense")
69
+ end.should raise_error(ArgumentError)
70
+ end
71
+
72
+ it "should allow a cookie to be specified with a one-off request" do
73
+ expect_cookie_header "type=snickerdoodle"
74
+ @klass.get("", :cookies => { :type => "snickerdoodle" })
75
+ end
76
+
77
+ describe "when a cookie is set at the class level" do
78
+ before(:each) do
79
+ @klass.cookies({ :type => "snickerdoodle" })
80
+ end
81
+
82
+ it "should include that cookie in the request" do
83
+ expect_cookie_header "type=snickerdoodle"
84
+ @klass.get("")
85
+ end
86
+
87
+ it "should allow the class defaults to be overridden" do
88
+ expect_cookie_header "type=chocolate_chip"
89
+
90
+ @klass.get("", :cookies => { :type => "chocolate_chip" })
91
+ end
92
+ end
93
+
94
+ describe "in a class with multiple methods that use different cookies" do
95
+ before(:each) do
96
+ @klass.instance_eval do
97
+ def first_method
98
+ get("first_method", :cookies => { :first_method_cookie => "foo" })
99
+ end
100
+
101
+ def second_method
102
+ get("second_method", :cookies => { :second_method_cookie => "foo" })
103
+ end
104
+ end
105
+ end
106
+
107
+ it "should not allow cookies used in one method to carry over into other methods" do
108
+ expect_cookie_header "first_method_cookie=foo"
109
+ @klass.first_method
110
+
111
+ expect_cookie_header "second_method_cookie=foo"
112
+ @klass.second_method
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "default params" do
118
+ it "should default to empty hash" do
119
+ @klass.default_params.should == {}
120
+ end
121
+
122
+ it "should be able to be updated" do
123
+ new_defaults = {:foo => 'bar', :baz => 'spax'}
124
+ @klass.default_params new_defaults
125
+ @klass.default_params.should == new_defaults
126
+ end
127
+ end
128
+
129
+ describe "basic http authentication" do
130
+ it "should work" do
131
+ @klass.basic_auth 'foobar', 'secret'
132
+ @klass.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'}
133
+ end
134
+ end
135
+
136
+ describe "format" do
137
+ it "should allow xml" do
138
+ @klass.format :xml
139
+ @klass.default_options[:format].should == :xml
140
+ end
141
+
142
+ it "should allow json" do
143
+ @klass.format :json
144
+ @klass.default_options[:format].should == :json
145
+ end
146
+
147
+ it "should allow yaml" do
148
+ @klass.format :yaml
149
+ @klass.default_options[:format].should == :yaml
150
+ end
151
+
152
+ it 'should not allow funky format' do
153
+ lambda do
154
+ @klass.format :foobar
155
+ end.should raise_error(HTTParty::UnsupportedFormat)
156
+ end
157
+ end
158
+
159
+ describe "with explicit override of automatic redirect handling" do
160
+
161
+ it "should fail with redirected GET" do
162
+ lambda do
163
+ @klass.get('/foo', :no_follow => true)
164
+ end.should raise_error(HTTParty::RedirectionTooDeep)
165
+ end
166
+
167
+ it "should fail with redirected POST" do
168
+ lambda do
169
+ @klass.post('/foo', :no_follow => true)
170
+ end.should raise_error(HTTParty::RedirectionTooDeep)
171
+ end
172
+
173
+ it "should fail with redirected DELETE" do
174
+ lambda do
175
+ @klass.delete('/foo', :no_follow => true)
176
+ end.should raise_error(HTTParty::RedirectionTooDeep)
177
+ end
178
+
179
+ it "should fail with redirected PUT" do
180
+ lambda do
181
+ @klass.put('/foo', :no_follow => true)
182
+ end.should raise_error(HTTParty::RedirectionTooDeep)
183
+ end
184
+ end
185
+
186
+ describe "with multiple class definitions" do
187
+ before(:each) do
188
+ @klass.instance_eval do
189
+ base_uri "http://first.com"
190
+ default_params :one => 1
191
+ end
192
+
193
+ @additional_klass = Class.new
194
+ @additional_klass.instance_eval do
195
+ include HTTParty
196
+ base_uri "http://second.com"
197
+ default_params :two => 2
198
+ end
199
+ end
200
+
201
+ it "should not run over each others options" do
202
+ @klass.default_options.should == { :base_uri => 'http://first.com', :default_params => { :one => 1 } }
203
+ @additional_klass.default_options.should == { :base_uri => 'http://second.com', :default_params => { :two => 2 } }
204
+ end
205
+ end
206
+
207
+ describe "#get" do
208
+ it "should be able to get html" do
209
+ stub_http_response_with('google.html')
210
+ HTTParty.get('http://www.google.com').should == file_fixture('google.html')
211
+ end
212
+
213
+ it "should be able to parse response type json automatically" do
214
+ stub_http_response_with('twitter.json')
215
+ tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
216
+ tweets.size.should == 20
217
+ tweets.first['user'].should == {
218
+ "name" => "Pyk",
219
+ "url" => nil,
220
+ "id" => "7694602",
221
+ "description" => nil,
222
+ "protected" => false,
223
+ "screen_name" => "Pyk",
224
+ "followers_count" => 1,
225
+ "location" => "Opera Plaza, California",
226
+ "profile_image_url" => "http://static.twitter.com/images/default_profile_normal.png"
227
+ }
228
+ end
229
+
230
+ it "should be able to parse response type xml automatically" do
231
+ stub_http_response_with('twitter.xml')
232
+ tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.xml')
233
+ tweets['statuses'].size.should == 20
234
+ tweets['statuses'].first['user'].should == {
235
+ "name" => "Magic 8 Bot",
236
+ "url" => nil,
237
+ "id" => "17656026",
238
+ "description" => "ask me a question",
239
+ "protected" => "false",
240
+ "screen_name" => "magic8bot",
241
+ "followers_count" => "90",
242
+ "profile_image_url" => "http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg",
243
+ "location" => nil
244
+ }
245
+ end
246
+
247
+ it "should not get undefined method add_node for nil class for the following xml" do
248
+ stub_http_response_with('undefined_method_add_node_for_nil.xml')
249
+ result = HTTParty.get('http://foobar.com')
250
+ result.should == {"Entities"=>{"href"=>"https://s3-sandbox.parature.com/api/v1/5578/5633/Account", "results"=>"0", "total"=>"0", "page_size"=>"25", "page"=>"1"}}
251
+ end
252
+
253
+ it "should parse empty response fine" do
254
+ stub_http_response_with('empty.xml')
255
+ result = HTTParty.get('http://foobar.com')
256
+ result.should == nil
257
+ end
258
+ end
259
+ end