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.
- data/.gitignore +4 -1
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/Gemfile +11 -8
- data/Gemfile.lock +49 -53
- data/LICENSE +1 -1
- data/README.md +134 -208
- data/Rakefile +6 -47
- data/lib/weary.rb +4 -66
- data/lib/weary/adapter.rb +23 -0
- data/lib/weary/adapters/net_http.rb +68 -0
- data/lib/weary/client.rb +243 -0
- data/lib/weary/deferred.rb +35 -0
- data/lib/weary/env.rb +32 -0
- data/lib/weary/middleware.rb +9 -0
- data/lib/weary/middleware/basic_auth.rb +17 -0
- data/lib/weary/middleware/content_type.rb +28 -0
- data/lib/weary/middleware/oauth.rb +31 -0
- data/lib/weary/request.rb +137 -124
- data/lib/weary/resource.rb +152 -128
- data/lib/weary/response.rb +48 -99
- data/lib/weary/route.rb +53 -0
- data/lib/weary/version.rb +3 -0
- data/spec/spec_helper.rb +4 -56
- data/spec/support/shared_examples_for_a_rack_app.rb +70 -0
- data/spec/support/shared_examples_for_a_rack_env.rb +14 -0
- data/spec/support/shared_examples_for_a_uri.rb +9 -0
- data/spec/weary/adapter_spec.rb +26 -0
- data/spec/weary/adapters/nethttp_spec.rb +88 -0
- data/spec/weary/client_spec.rb +258 -0
- data/spec/weary/deferred_spec.rb +35 -0
- data/spec/weary/env_spec.rb +12 -0
- data/spec/weary/middleware/basic_auth_spec.rb +23 -0
- data/spec/weary/middleware/content_type_spec.rb +34 -0
- data/spec/weary/middleware/oauth_spec.rb +27 -0
- data/spec/weary/request_spec.rb +227 -315
- data/spec/weary/resource_spec.rb +233 -233
- data/spec/weary/response_spec.rb +82 -159
- data/spec/weary/route_spec.rb +72 -0
- data/spec/weary_spec.rb +3 -56
- data/weary.gemspec +16 -79
- metadata +138 -98
- data/VERSION +0 -1
- data/examples/batch.rb +0 -20
- data/examples/repo.rb +0 -16
- data/examples/status.rb +0 -26
- data/lib/weary/base.rb +0 -124
- data/lib/weary/batch.rb +0 -37
- data/lib/weary/exceptions.rb +0 -15
- data/lib/weary/httpverb.rb +0 -32
- data/spec/fixtures/github.yml +0 -11
- data/spec/fixtures/twitter.xml +0 -763
- data/spec/fixtures/vimeo.json +0 -1
- data/spec/weary/base_spec.rb +0 -320
- data/spec/weary/batch_spec.rb +0 -71
- 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
|
data/spec/weary/request_spec.rb
CHANGED
@@ -1,344 +1,256 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Weary::Request do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
67
|
-
|
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
|
75
|
-
|
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
|
81
|
-
|
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
|
90
|
-
|
91
|
-
|
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
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
283
|
-
|
284
|
-
|
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
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
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
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
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
|
-
|
299
|
-
|
300
|
-
|
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
|
-
|
303
|
-
|
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
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
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
|
-
|
340
|
-
end
|
252
|
+
}
|
253
|
+
let(:env) { subject.env }
|
341
254
|
end
|
342
255
|
end
|
343
|
-
|
344
256
|
end
|