weary 0.7.2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +4 -1
  2. data/.rspec +2 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +11 -8
  5. data/Gemfile.lock +49 -53
  6. data/LICENSE +1 -1
  7. data/README.md +134 -208
  8. data/Rakefile +6 -47
  9. data/lib/weary.rb +4 -66
  10. data/lib/weary/adapter.rb +23 -0
  11. data/lib/weary/adapters/net_http.rb +68 -0
  12. data/lib/weary/client.rb +243 -0
  13. data/lib/weary/deferred.rb +35 -0
  14. data/lib/weary/env.rb +32 -0
  15. data/lib/weary/middleware.rb +9 -0
  16. data/lib/weary/middleware/basic_auth.rb +17 -0
  17. data/lib/weary/middleware/content_type.rb +28 -0
  18. data/lib/weary/middleware/oauth.rb +31 -0
  19. data/lib/weary/request.rb +137 -124
  20. data/lib/weary/resource.rb +152 -128
  21. data/lib/weary/response.rb +48 -99
  22. data/lib/weary/route.rb +53 -0
  23. data/lib/weary/version.rb +3 -0
  24. data/spec/spec_helper.rb +4 -56
  25. data/spec/support/shared_examples_for_a_rack_app.rb +70 -0
  26. data/spec/support/shared_examples_for_a_rack_env.rb +14 -0
  27. data/spec/support/shared_examples_for_a_uri.rb +9 -0
  28. data/spec/weary/adapter_spec.rb +26 -0
  29. data/spec/weary/adapters/nethttp_spec.rb +88 -0
  30. data/spec/weary/client_spec.rb +258 -0
  31. data/spec/weary/deferred_spec.rb +35 -0
  32. data/spec/weary/env_spec.rb +12 -0
  33. data/spec/weary/middleware/basic_auth_spec.rb +23 -0
  34. data/spec/weary/middleware/content_type_spec.rb +34 -0
  35. data/spec/weary/middleware/oauth_spec.rb +27 -0
  36. data/spec/weary/request_spec.rb +227 -315
  37. data/spec/weary/resource_spec.rb +233 -233
  38. data/spec/weary/response_spec.rb +82 -159
  39. data/spec/weary/route_spec.rb +72 -0
  40. data/spec/weary_spec.rb +3 -56
  41. data/weary.gemspec +16 -79
  42. metadata +138 -98
  43. data/VERSION +0 -1
  44. data/examples/batch.rb +0 -20
  45. data/examples/repo.rb +0 -16
  46. data/examples/status.rb +0 -26
  47. data/lib/weary/base.rb +0 -124
  48. data/lib/weary/batch.rb +0 -37
  49. data/lib/weary/exceptions.rb +0 -15
  50. data/lib/weary/httpverb.rb +0 -32
  51. data/spec/fixtures/github.yml +0 -11
  52. data/spec/fixtures/twitter.xml +0 -763
  53. data/spec/fixtures/vimeo.json +0 -1
  54. data/spec/weary/base_spec.rb +0 -320
  55. data/spec/weary/batch_spec.rb +0 -71
  56. data/spec/weary/httpverb_spec.rb +0 -25
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+ require 'rack/lobster'
3
+
4
+ describe Weary::Client do
5
+ describe "::resource" do
6
+ before do
7
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
8
+ end
9
+
10
+ subject { Class.new(Weary::Client) }
11
+
12
+ it "defines a user resource" do
13
+ resource = subject.resource :show, "GET", @url
14
+ resource.should be_a Weary::Resource
15
+ end
16
+
17
+ it "allows the resource to be further modified by a block" do
18
+ new_url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
19
+ resource = subject.resource :show, "GET", @url do |r|
20
+ r.url new_url
21
+ end
22
+ resource.url.variables.size.should eql 2
23
+ end
24
+ end
25
+
26
+ Weary::Client::REQUEST_METHODS.each do |request_method|
27
+ describe "::#{request_method}" do
28
+ before do
29
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
30
+ end
31
+
32
+ subject { Class.new(Weary::Client) }
33
+
34
+ it "creates a class method named the same as the request method" do
35
+ subject.should respond_to request_method
36
+ end
37
+
38
+ it "is a convenience method for ::resource" do
39
+ upcase_method = request_method.to_s.upcase
40
+ subject.stub(:resource) { Weary::Resource.new upcase_method, @url }
41
+ subject.should_receive(:resource).with(:name, upcase_method, @url)
42
+ subject.send(request_method, :name, @url) {|r| r.basic_auth! }
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "::domain" do
48
+ before do
49
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
50
+ end
51
+
52
+ subject { Class.new(Weary::Client) }
53
+
54
+ it "prepends the domain to the path when creating resources" do
55
+ repo = {:user => "mwunsch", :repo => "weary"}
56
+ subject.domain "http://github.com/api/v2/json/repos"
57
+ resource = subject.get :show, "/show/{user}/{repo}"
58
+ resource.url.expand(repo).to_s.should eql @url
59
+ end
60
+ end
61
+
62
+ describe "::optional" do
63
+ before do
64
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
65
+ end
66
+
67
+ subject { Class.new(Weary::Client) }
68
+
69
+ it "passes optional requirements to the resources" do
70
+ param = :username
71
+ subject.optional param
72
+ resource = subject.get :show, @url
73
+ resource.optional.should include param
74
+ end
75
+ end
76
+
77
+ describe "::required" do
78
+ before do
79
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
80
+ end
81
+
82
+ subject { Class.new(Weary::Client) }
83
+
84
+ it "passes optional requirements to the resources" do
85
+ param = :username
86
+ subject.required param
87
+ resource = subject.get :show, @url
88
+ resource.required.should include param
89
+ end
90
+ end
91
+
92
+ describe "::defaults" do
93
+ before do
94
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
95
+ end
96
+
97
+ subject { Class.new(Weary::Client) }
98
+
99
+ it "passes default parameters into the resources" do
100
+ params = { :foo => "baz" }
101
+ subject.defaults params
102
+ resource = subject.get :show, @url
103
+ resource.defaults.should eql params
104
+ end
105
+ end
106
+
107
+ describe "::headers" do
108
+ before do
109
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
110
+ end
111
+
112
+ subject { Class.new(Weary::Client) }
113
+
114
+ it "passes headers into the resources" do
115
+ header = {'User-Agent' => "RSpec"}
116
+ subject.headers header
117
+ resource = subject.get :show, @url
118
+ resource.headers.should eql header
119
+ end
120
+ end
121
+
122
+ describe "::use" do
123
+ before do
124
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
125
+ end
126
+
127
+ subject { Class.new(Weary::Client) }
128
+
129
+ it "adds a middleware to a stack and passes it into subsequent requests" do
130
+ subject.use Rack::Lobster
131
+ subject.get :show, @url
132
+ client = subject.new
133
+ stack = client.show.instance_variable_get :@middlewares
134
+ stack.flatten.should include Rack::Lobster
135
+ end
136
+ end
137
+
138
+ describe "::resources" do
139
+ before do
140
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
141
+ end
142
+
143
+ subject { Class.new(Weary::Client) }
144
+
145
+ it "is a map of all the resources of the class" do
146
+ action = :show
147
+ resource = subject.get action, @url
148
+ subject.resources[action].should be resource
149
+ end
150
+ end
151
+
152
+ describe "::[]=" do
153
+ before do
154
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
155
+ end
156
+
157
+ subject { Class.new(Weary::Client) }
158
+
159
+ it "stores a named Weary::Resource" do
160
+ action = :show
161
+ resource = Weary::Resource.new "GET", @url
162
+ subject[action] = resource
163
+ subject.resources[action].should be resource
164
+ end
165
+
166
+ it "raises an error if a resource is not passed" do
167
+ action = :show
168
+ expect { subject[action] = "not a resource" }.to raise_error(ArgumentError)
169
+ end
170
+ end
171
+
172
+ describe "::[]" do
173
+ before do
174
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
175
+ end
176
+
177
+ subject { Class.new(Weary::Client) }
178
+
179
+ it "retrieves a stored resource" do
180
+ action = :show
181
+ resource = subject.get action, @url
182
+ subject[action].should be resource
183
+ end
184
+ end
185
+
186
+ describe "::route" do
187
+ before do
188
+ @client = Class.new(Weary::Client)
189
+ @client.domain "https://api.github.com"
190
+ @client.get(:list, "/user/repos") {|r| r.basic_auth! }
191
+ @client.get(:user, "/users/{user}/repos")
192
+ @client.post(:create, "/user/repos") {|r| r.basic_auth! }
193
+ @client.get(:repo, "/users/{user}/{repo}")
194
+ @client.patch(:edit, "/users/{user}/{repo}") {|r| r.basic_auth! }
195
+ end
196
+
197
+ it "returns a router for the resources" do
198
+ @client.route.should be_a Weary::Route
199
+ end
200
+ end
201
+
202
+ describe "::call" do
203
+ before do
204
+ @client = Class.new(Weary::Client)
205
+ @client.domain "https://api.github.com"
206
+ @client.get(:list, "/user/repos") {|r| r.basic_auth! }
207
+ @client.get(:user, "/users/{user}/repos")
208
+ @client.post(:create, "/user/repos") {|r| r.basic_auth! }
209
+ @client.get(:repo, "/users/{user}/{repo}")
210
+ @client.patch(:edit, "/users/{user}/{repo}") {|r| r.basic_auth! }
211
+ end
212
+
213
+ it_behaves_like "a Rack application" do
214
+ subject { @client }
215
+ let(:env) { @client.resources[:list].request.env }
216
+ end
217
+ end
218
+
219
+ describe "#initialize" do
220
+ before do
221
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
222
+ @klass = Class.new(Weary::Client)
223
+ end
224
+
225
+ it "responds to a method with the name of the resource" do
226
+ action = :show_repo
227
+ @klass.get action, @url
228
+ client = @klass.new
229
+ client.should respond_to action
230
+ end
231
+
232
+ it "returns a Weary::Request when calling the named method" do
233
+ action = :show
234
+ @klass.get action, @url
235
+ client = @klass.new
236
+ client.send(action).should be_a Weary::Request
237
+ end
238
+
239
+ it "generates a method for the resource that takes a set of parameters" do
240
+ action = :show
241
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
242
+ @klass.get action, url
243
+ client = @klass.new
244
+ request = client.send(action, :user => "mwunsch", :repo => "weary")
245
+ request.uri.to_s.should eql @url
246
+ end
247
+
248
+ it "combines a @defaults instance_variable with params on method execution" do
249
+ action = :show
250
+ url = "http://github.com/api/v2/json/repos/show/{user}/{repo}"
251
+ @klass.get action, url
252
+ client = @klass.new
253
+ client.instance_variable_set :@defaults, :user => "mwunsch", :repo => "weary"
254
+ expect { client.send(action) }.to_not raise_error
255
+ end
256
+ end
257
+
258
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'weary/deferred'
3
+
4
+ describe Weary::Deferred do
5
+ before :all do
6
+ @struct = Struct.new "Deferred", :response
7
+ end
8
+
9
+ before do
10
+ @request = Weary::Request.new "http://github.com/api/v2/json/repos/show/mwunsch/weary"
11
+ adapter = Class.new { include Weary::Adapter }
12
+ @request.adapter adapter
13
+ end
14
+
15
+ describe "::new" do
16
+ it "creates a new deffered proxy object around a model" do
17
+ deferred = described_class.new @request.perform, @struct
18
+ deferred.should be_instance_of @struct
19
+ end
20
+
21
+ it "with a factory method" do
22
+ deferred = described_class.new @request.perform, @struct, lambda {|model, response| response.status }
23
+ deferred.should eq 501
24
+ end
25
+ end
26
+
27
+ describe "#complete?" do
28
+ it "is true when the target is ready" do
29
+ deferred = described_class.new @request.perform, @struct
30
+ deferred.inspect
31
+ deferred.complete?.should be_true
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Weary::Env do
4
+ describe "#env" do
5
+ it_behaves_like "a Rack env" do
6
+ subject do
7
+ req = Weary::Request.new("http://github.com/api/v2/json/repos/show/mwunsch/weary")
8
+ described_class.new(req).env
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ require 'weary/middleware/basic_auth'
2
+ require 'spec_helper'
3
+
4
+ describe Weary::Middleware::BasicAuth do
5
+ describe "#call" do
6
+ before do
7
+ @request = Weary::Request.new("http://github.com/api/v2/json/repos/show/mwunsch/weary")
8
+ @url = "http://mwunsch:secret@github.com/api/v2/json/repos/show/mwunsch/weary"
9
+ stub_request :get, @url
10
+ end
11
+
12
+ it_behaves_like "a Rack application" do
13
+ subject { described_class.new(@request, ["mwunsch", "secret"]) }
14
+ let(:env) { @request.env }
15
+ end
16
+
17
+ it "prepares the Authorization header for the request" do
18
+ middleware = described_class.new(@request, ["mwunsch", "secret"])
19
+ middleware.call(@request.env)
20
+ a_request(:get, @url).should have_been_made
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ require 'weary/middleware/content_type'
2
+ require 'spec_helper'
3
+
4
+ describe Weary::Middleware::ContentType do
5
+ describe "#call" do
6
+ before do
7
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
8
+ @request = Weary::Request.new @url, 'POST'
9
+ stub_request :post, @request.uri.to_s
10
+ end
11
+
12
+ it_behaves_like "a Rack application" do
13
+ subject { described_class.new(@request) }
14
+ let(:env) { @request.env }
15
+ end
16
+
17
+ it "adds a Content-Type header to the request" do
18
+ middleware = described_class.new(@request)
19
+ middleware.call(@request.env)
20
+ a_request(:post, @url).
21
+ with {|req| req.headers.has_key?("Content-Type") }.
22
+ should have_been_made
23
+ end
24
+
25
+ it "adds a Content-Length header to the request" do
26
+ middleware = described_class.new(@request)
27
+ middleware.call(@request.env)
28
+ a_request(:post, @url).
29
+ with {|req| req.headers.has_key?("Content-Length") }.
30
+ should have_been_made
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ require 'weary/middleware/oauth'
2
+ require 'spec_helper'
3
+
4
+ describe Weary::Middleware::OAuth do
5
+ describe "#call" do
6
+ before do
7
+ @url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
8
+ @request = Weary::Request.new @url
9
+ stub_request :get, @request.uri.to_s
10
+ end
11
+
12
+ it_behaves_like "a Rack application" do
13
+ subject { described_class.new(@request, "consumer_key", "access_token") }
14
+ let(:env) { @request.env }
15
+ end
16
+
17
+ it "prepares the Authorization header for the request" do
18
+ middleware = described_class.new(@request, "consumer_key", "access_token")
19
+ middleware.call(@request.env)
20
+ signed_header = middleware.sign(@request.env)
21
+ a_request(:get, @url).
22
+ with {|req| req.headers.has_key?("Authorization") }.
23
+ should have_been_made
24
+ end
25
+
26
+ end
27
+ end
@@ -1,344 +1,256 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Weary::Request do
4
-
5
- it 'creates a Net/HTTP connection' do
6
- test = Weary::Request.new("http://google.com")
7
- test.http.class.should == Net::HTTP
4
+ describe "#uri" do
5
+ subject { described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary" }
6
+
7
+ it_behaves_like "a URI" do
8
+ let(:uri) { subject.uri }
9
+ end
10
+
11
+ it "infers a port of 80" do
12
+ subject.uri.inferred_port.should eql 80
13
+ end
14
+
15
+ it "has a scheme of http" do
16
+ subject.uri.scheme.should eql 'http'
17
+ end
8
18
  end
9
-
10
- it 'maps to a Net/HTTPRequest class' do
11
- test = Weary::Request.new("http://google.com")
12
- test.connection.class.should == Net::HTTP::Get
19
+
20
+ describe "#uri=" do
21
+ context "given a URI string" do
22
+ subject { described_class.new "http://github.com/api/v2/json/user/show/mwunsch" }
23
+
24
+ it "sets the request URI" do
25
+ original_path = subject.uri.path
26
+ new_path = "/api/v2/json/repos/show/mwunsch/weary"
27
+ expect {
28
+ subject.uri = "http://github.com#{new_path}"
29
+ }.to change{subject.uri.path}.from(original_path).to(new_path)
30
+ end
31
+ end
32
+
33
+ context "given a URI object" do
34
+ subject { described_class.new "http://github.com/api/v2/json/user/show/mwunsch" }
35
+
36
+ it "sets the request URI" do
37
+ original_path = subject.uri.path
38
+ new_path = "/api/v2/json/repos/show/mwunsch/weary"
39
+ expect {
40
+ subject.uri = URI("http://github.com#{new_path}")
41
+ }.to change{subject.uri.path}.from(original_path).to(new_path)
42
+ end
43
+ end
13
44
  end
14
-
15
- describe 'Request' do
16
- it 'prepares a Net/HTTP request' do
17
- test = Weary::Request.new("http://google.com")
18
- test.request.class.should == Net::HTTP::Get
19
- end
20
-
21
- it 'prepares a body for POST' do
22
- test = Weary::Request.new("http://foo.bar", :post)
23
- test.with = {:name => "markwunsch"}
24
- req = test.request
25
- req.class.should == Net::HTTP::Post
26
- req.body.should == test.with
27
- end
28
-
29
- it 'sets up headers' do
30
- test = Weary::Request.new("http://foo.bar")
31
- test.headers = {"User-Agent" => Weary::UserAgents["Safari 4.0.2 - Mac"]}
32
- req = test.request
33
- req['User-Agent'].should == Weary::UserAgents["Safari 4.0.2 - Mac"]
34
- end
35
-
36
- it 'has an authorization header when basic auth is used' do
37
- test = Weary::Request.new("http://foo.bar")
38
- test.credentials = {:username => "mark", :password => "secret"}
39
- req = test.request
40
- req.key?('Authorization').should == true
41
- end
42
-
43
- it "prepares an oauth scheme if a token is provided" do
44
- consumer = OAuth::Consumer.new("consumer_token","consumer_secret",{:site => 'http://foo.bar'})
45
- token = OAuth::AccessToken.new(consumer, "token", "secret")
46
- test = Weary::Request.new("http://foo.bar", :post)
47
- test.credentials = token
48
- test.request.oauth_helper.options[:token].should == token
45
+
46
+ describe "#method" do
47
+ before do
48
+ @uri = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
49
+ end
50
+
51
+ it "infers a GET request on initialization" do
52
+ r = described_class.new @uri
53
+ r.method.should eql "GET"
54
+ end
55
+
56
+ it "is a Rack-friendly token" do
57
+ r = described_class.new @uri, :get
58
+ r.method.should eql "GET"
49
59
  end
50
60
  end
51
-
52
- describe 'Options' do
53
- it 'sets the credentials to basic authentication' do
54
- basic_auth = {:username => 'mark', :password => 'secret'}
55
- test = Weary::Request.new("http://foo.bar", :get, {:basic_auth => basic_auth})
56
- test.credentials.should == basic_auth
61
+
62
+ describe "#method=" do
63
+ before do
64
+ uri = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
65
+ @request = described_class.new uri
57
66
  end
58
67
 
59
- it 'sets the credentials to an oauth token' do
60
- consumer = OAuth::Consumer.new("consumer_token","consumer_secret",{:site => 'http://foo.bar'})
61
- token = OAuth::AccessToken.new(consumer, "token", "secret")
62
- test = Weary::Request.new("http://foo.bar", :post, {:oauth => token})
63
- test.credentials.should == token
68
+ it "transforms the http verb to a Rack-friendly token" do
69
+ expect {
70
+ @request.method = :head
71
+ }.to change{ @request.method }.from('GET').to('HEAD')
64
72
  end
73
+ end
74
+
75
+ describe "#env" do
76
+ let(:request) { described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary" }
65
77
 
66
- it 'sets the body params' do
67
- body = {:options => "something"}
68
- test = Weary::Request.new("http://foo.bar", :post, {:body => body})
69
- test.with.should == body.to_params
70
- test2 = Weary::Request.new("http://foo.bar", :post, {:body => body.to_params})
71
- test2.with.should == body.to_params
78
+ it_behaves_like "a Rack env" do
79
+ subject { request.env }
72
80
  end
73
81
 
74
- it 'sets header values' do
75
- head = {"User-Agent" => Weary::UserAgents["Safari 4.0.2 - Mac"]}
76
- test = Weary::Request.new("http://foo.bar", :get, {:headers => head})
77
- test.headers.should == head
82
+ it "includes the calling object in the hash" do
83
+ request.env["weary.request"].should be request
78
84
  end
79
85
 
80
- it 'sets a following value for redirection' do
81
- test = Weary::Request.new("http://foo.bar", :get, {:no_follow => true})
82
- test.follows?.should == false
83
- test = Weary::Request.new("http://foo.bar", :get, {:no_follow => false})
84
- test.follows?.should == true
85
- test = Weary::Request.new("http://foo.bar", :get)
86
- test.follows?.should == true
86
+ it "infers a SERVER_PORT of 80" do
87
+ request.env["SERVER_PORT"].should eql "80"
87
88
  end
88
-
89
- it 'uses the #with hash to create a URI query string if the method is a GET' do
90
- test = Weary::Request.new("http://foo.bar/path/to/something")
91
- test.with = {:name => "markwunsch", :title => "awesome"}
92
- test.uri.query.should == test.with
89
+
90
+ it "pulls the query string out of the uri" do
91
+ request.uri = "http://api.twitter.com/version/users/show.format?screen_name=markwunsch"
92
+ request.env['QUERY_STRING'].should eql 'screen_name=markwunsch'
93
93
  end
94
94
  end
95
-
96
- describe 'Perform' do
97
- # These tests reveal tight coupling with Response API, which may or may not be a good thing
98
-
99
- after do
100
- FakeWeb.clean_registry
101
- end
102
-
103
- it 'performs the request and gets back a response' do
104
- hello = "Hello from FakeWeb"
105
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => hello)
106
-
107
- test = Weary::Request.new("http://markwunsch.com")
108
- response = test.perform
109
- response.class.should == Weary::Response
110
- response.body.should == hello
111
- end
112
-
113
- it 'follows redirection' do
114
- hello = "Hello from FakeWeb"
115
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(301), :Location => 'http://redirected.com')
116
- FakeWeb.register_uri(:get, "http://redirected.com", :body => hello)
117
-
118
- test = Weary::Request.new("http://markwunsch.com")
119
- response = test.perform
120
- response.body.should == hello
121
- end
122
-
123
- it 'will not follow redirection if disabled' do
124
- hello = "Hello from FakeWeb"
125
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(301), :Location => 'http://redirected.com')
126
- FakeWeb.register_uri(:get, "http://redirected.com", :body => hello)
127
-
128
- test = Weary::Request.new("http://markwunsch.com", :get, :no_follow => true)
129
- response = test.perform
130
- response.code.should == 301
131
- end
132
-
133
- it 'passes the response into a callback' do
134
- hello = "Hello from FakeWeb"
135
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => hello)
136
- response_body = ""
137
-
138
- test = Weary::Request.new("http://markwunsch.com")
139
- test.perform do |response|
140
- response_body = response.body
141
- end
142
-
143
- response_body.should == hello
144
- end
145
-
146
- it 'performs the callback even when redirected' do
147
- hello = "Hello from FakeWeb"
148
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(301), :Location => 'http://redirected.com')
149
- FakeWeb.register_uri(:get, "http://redirected.com", :body => hello)
150
-
151
- response_body = ""
152
-
153
- test = Weary::Request.new("http://markwunsch.com")
154
- test.perform do |response|
155
- response_body = response.body
156
- end
157
-
158
- response_body.should == hello
159
- end
160
-
161
- it 'authorizes with basic authentication' do
162
- message = 'You are authorized to do that.'
163
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(401))
164
- FakeWeb.register_uri(:get, "http://mark:secret@markwunsch.com", :body => message)
165
-
166
- test = Weary::Request.new("http://markwunsch.com")
167
- response = test.perform
168
- response.code.should == 401
169
- response.body.should_not == message
170
- test.credentials = {:username => 'mark', :password => 'secret'}
171
- response = test.perform
172
- response.code.should == 200
173
- response.body.should == message
174
- end
175
-
176
- it 'still authorizes correctly if redirected' do
177
- message = 'You are authorized to do that.'
178
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(401))
179
- FakeWeb.register_uri(:get, "http://mark:secret@markwunsch.com", :status => http_status_message(301), :Location => 'http://markwunsch.net')
180
- FakeWeb.register_uri(:get, "http://markwunsch.net", :status => http_status_message(401))
181
- FakeWeb.register_uri(:get, "http://mark:secret@markwunsch.net", :body => message)
182
-
183
- test = Weary::Request.new("http://markwunsch.com")
184
- test.credentials = {:username => 'mark', :password => 'secret'}
185
- response = test.perform
186
- response.code.should == 200
187
- response.body.should == message
188
- end
189
-
190
- it 'converts parameters to url query strings' do
191
- params = {:id => 'mark', :message => 'hello'}
192
- message = "Using FakeWeb with params of #{params.to_params}"
193
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(403))
194
- FakeWeb.register_uri(:get, "http://markwunsch.com?#{params.to_params}", :body => message)
195
-
196
- test = Weary::Request.new("http://markwunsch.com")
197
- test.with = params
198
- response = test.perform
199
- response.body.should == message
200
- end
201
-
202
- it 'sends query strings correctly when redirected' do
203
- params = {:id => 'mark', :message => 'hello'}
204
- message = "Using FakeWeb with params of #{params.to_params}"
205
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(403))
206
- FakeWeb.register_uri(:get, "http://markwunsch.net", :status => http_status_message(403))
207
- FakeWeb.register_uri(:get, "http://markwunsch.com?#{params.to_params}", :status => http_status_message(301), :Location => 'http://markwunsch.net')
208
- FakeWeb.register_uri(:get, "http://markwunsch.net?#{params.to_params}", :body => message)
209
-
210
- test = Weary::Request.new("http://markwunsch.com")
211
- test.with = params
212
- response = test.perform
213
- response.code.should == 200
214
- end
215
-
216
- it 'converts parameters to request body on post' do
217
- params = {:id => 'mark', :message => 'hello'}
218
- message = "Using FakeWeb with params of #{params.to_params}"
219
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(403))
220
- FakeWeb.register_uri(:post, "http://markwunsch.com", :body => message)
221
-
222
- test = Weary::Request.new("http://markwunsch.com")
223
- test.via = :post
224
- test.with = params
225
- response = test.perform
226
- response.code.should == 200
227
- response.body.should == message
228
-
229
- # No way of testing Request bodies with FakeWeb as of 1.2.7
230
- end
231
-
232
- describe 'Non-Blocking, Threaded' do
233
- # Not exactly sure the best way to test these
234
-
235
- it 'creates a new thread to perform the request' do
236
- hello = "Hello from FakeWeb"
237
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => hello)
238
-
239
- test = Weary::Request.new("http://markwunsch.com")
240
- test.perform!.value.body.should == hello
241
- end
242
-
243
- it "sets its callback" do
244
- msg = "You did it!"
245
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => msg)
246
- test = Weary::Request.new("http://markwunsch.com")
247
- body = ""
248
-
249
- thread = test.perform! do |r|
250
- body = r.body
251
- end
252
- body = thread.value.body
253
- body.should == msg
254
- end
95
+
96
+ describe "#headers" do
97
+ subject { described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary" }
98
+ let(:hash) { {'User-Agent' => Weary::USER_AGENTS['Lynx 2.8.4rel.1 on Linux']} }
99
+
100
+ it "sets headers for the request" do
101
+ subject.headers(hash)
102
+ subject.instance_variable_get(:@headers).should eql hash
103
+ end
104
+
105
+ it "gets previously set headers" do
106
+ subject.headers(hash)
107
+ subject.headers.should eql hash
108
+ end
109
+
110
+ it "updates the env with the Rack-friendly key" do
111
+ subject.headers(hash)
112
+ subject.env.should have_key('HTTP_USER_AGENT')
113
+ end
114
+
115
+ it "updates the env with its HTTP_* value" do
116
+ subject.headers(hash)
117
+ subject.env['HTTP_USER_AGENT'].should eql(hash.values.first)
255
118
  end
256
119
  end
257
-
258
- describe 'Callbacks' do
259
- after do
260
- FakeWeb.clean_registry
261
- end
262
-
263
- describe 'on_complete' do
264
- it 'stores the callback' do
265
- test = Weary::Request.new("http://markwunsch.com")
266
- test.on_complete do
267
- 'hello'
268
- end
269
- test.on_complete.call.should == 'hello'
270
- end
271
-
272
- it 'accepts a block, and the block becomes the callback' do
273
- msg = "You did it!"
274
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => msg)
275
- test = Weary::Request.new("http://markwunsch.com")
276
- body = ""
277
-
278
- test.on_complete do |response|
279
- body = response.body
280
- end
281
120
 
282
- test.perform
283
- body.should == msg
284
- end
121
+ describe "#user_agent" do
122
+ subject { described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary" }
123
+ let(:agent) { 'RSpec' }
285
124
 
286
- it 'is overriden when a block is passed to the perform method' do
287
- msg = "You did it!"
288
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => msg)
289
- test = Weary::Request.new("http://markwunsch.com")
290
- body = ""
125
+ it "updates the #headers hash with a User-Agent" do
126
+ subject.user_agent agent
127
+ subject.headers.should have_key 'User-Agent'
128
+ end
291
129
 
292
- test.on_complete do |response|
293
- body = response.body
294
- end
295
- test.perform
296
- body.should == msg
130
+ it "sets the user agent for the headers" do
131
+ subject.user_agent agent
132
+ subject.headers['User-Agent'].should be agent
133
+ end
134
+ end
297
135
 
298
- test.perform do |response|
299
- body = 'Now it is different'
300
- end
136
+ describe "#params" do
137
+ it "sets the query string for a GET request" do
138
+ req = described_class.new "http://api.twitter.com/version/users/show.json"
139
+ req.params :screen_name => 'markwunsch'
140
+ req.uri.query.should eql "screen_name=markwunsch"
141
+ end
301
142
 
302
- body.should == 'Now it is different'
303
- end
143
+ it "sets the rack input for a POST request" do
144
+ req = described_class.new "https://api.github.com/gists", "POST"
145
+ req.params :public => true,
146
+ :files => { "file1.txt" => { :content => "String file contents"}}
147
+ req.env['rack.input'].read.should eql req.params
304
148
  end
305
-
306
- describe 'before_send' do
307
- it 'stores the callback' do
308
- test = Weary::Request.new("http://markwunsch.com")
309
- test.before_send do
310
- 'hello'
311
- end
312
- test.before_send.call.should == 'hello'
313
- end
314
-
315
- it 'accepts a block, and the block becomes the callback' do
316
- msg = "You did it!"
317
- FakeWeb.register_uri(:get, "http://markwunsch.com", :body => msg)
318
- test = Weary::Request.new("http://markwunsch.com")
319
- body = ""
320
-
321
- test.before_send do
322
- body = msg
323
- end
324
- body.should_not == msg
325
- test.perform
326
- body.should == msg
327
- end
328
-
329
- it 'takes the Request as an argument, so it can be manipulate before sending' do
330
- hello = "Hello from FakeWeb"
331
- FakeWeb.register_uri(:get, "http://markwunsch.com", :status => http_status_message(301), :Location => 'http://redirected.com')
332
- FakeWeb.register_uri(:get, "http://redirected.com", :body => hello)
333
-
334
- test = Weary::Request.new("http://markwunsch.com")
335
- test.before_send do |req|
336
- req.follows = false
149
+
150
+ it "adds a Middleware to the stack for the Content-Type and Length" do
151
+ req = described_class.new "https://api.github.com/gists", "POST"
152
+ req.should_receive(:use).with(Weary::Middleware::ContentType)
153
+ req.params :foo => "baz"
154
+ end
155
+ end
156
+
157
+ describe "#json" do
158
+ it "sets the request body to be a json string from a hash" do
159
+ hash = {:foo => 'baz'}
160
+ req = described_class.new "https://api.github.com/gists", "POST"
161
+ req.json hash
162
+ req.env['rack.input'].read.should eql MultiJson.encode(hash)
163
+ end
164
+ end
165
+
166
+ describe "#basic_auth" do
167
+ it "adds a Middleware to the stack to handle authentication" do
168
+ req = described_class.new "https://api.github.com/gists", "POST"
169
+ cred = ["mwunsch", "secret-passphrase"]
170
+ req.should_receive(:use).with(Weary::Middleware::BasicAuth, cred)
171
+ req.basic_auth *cred
172
+ end
173
+
174
+ it "returns true if auth has been set" do
175
+ req = described_class.new "https://api.github.com/gists", "POST"
176
+ cred = ["mwunsch", "secret-passphrase"]
177
+ req.basic_auth *cred
178
+ req.basic_auth.should be_true
179
+ end
180
+ end
181
+
182
+ describe "#oauth" do
183
+ it "adds a Middleware to the stack to sign the request" do
184
+ req = described_class.new "https://api.github.com/gists", "POST"
185
+ cred = ["consumer_key", "access_token"]
186
+ req.should_receive(:use).with(Weary::Middleware::OAuth, cred)
187
+ req.oauth *cred
188
+ end
189
+
190
+ it "returns true if auth has been set" do
191
+ req = described_class.new "https://api.github.com/gists", "POST"
192
+ cred = ["consumer_key", "access_token"]
193
+ req.oauth *cred
194
+ req.oauth.should be_true
195
+ end
196
+ end
197
+
198
+ describe "#adapter" do
199
+ subject { described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary" }
200
+
201
+ it "sets a new adapter to set the connection" do
202
+ klass = Class.new { include Weary::Adapter }
203
+ subject.adapter(klass)
204
+ subject.adapter.should be klass
205
+ end
206
+
207
+ it "defaults to the Net::HTTP adapter" do
208
+ subject.adapter.should be Weary::Adapter::NetHttp
209
+ end
210
+ end
211
+
212
+ describe "#perform" do
213
+ subject do
214
+ url = "http://github.com/api/v2/json/repos/show/mwunsch/weary"
215
+ described_class.new url
216
+ end
217
+
218
+ before do
219
+ stub_request(:get, subject.uri.to_s).
220
+ to_rack(lambda{|env| [200, {'Content-Type' => 'text/html'}, ['']]})
221
+ end
222
+
223
+ it "returns a future containing a Weary::Response" do
224
+ subject.perform.should be_a Weary::Response
225
+ end
226
+
227
+ it "accepts an optional block" do
228
+ code = nil
229
+ subject.perform {|response| code = response.status }.force
230
+ code.should be >= 100
231
+ end
232
+ end
233
+
234
+ describe "#use" do
235
+ it "adds a middleware to the stack" do
236
+ req = described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary"
237
+ req.adapter(Class.new { include Weary::Adapter })
238
+ # Rack::Runtime sets an "X-Runtime" response header
239
+ # http://rack.rubyforge.org/doc/Rack/Runtime.html
240
+ req.use Rack::Runtime, "RSpec"
241
+ code, headers, body = req.call({})
242
+ headers.should have_key "X-Runtime-RSpec"
243
+ end
244
+ end
245
+
246
+ describe "#call" do
247
+ it_behaves_like "a Rack application" do
248
+ subject {
249
+ described_class.new "http://github.com/api/v2/json/repos/show/mwunsch/weary" do |req|
250
+ req.adapter Class.new { include Weary::Adapter }
337
251
  end
338
-
339
- test.perform.code.should == 301
340
- end
252
+ }
253
+ let(:env) { subject.env }
341
254
  end
342
255
  end
343
-
344
256
  end