weary 0.7.2 → 1.0.0.rc1

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 (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