hugs 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +0 -4
- data/VERSION +1 -1
- data/hugs.gemspec +2 -2
- data/lib/hugs/errors.rb +10 -6
- data/test/lib/hugs/client_test.rb +32 -41
- data/test/lib/hugs/errors_test.rb +26 -54
- data/test/test_helper.rb +18 -1
- metadata +3 -3
data/README.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
data/hugs.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hugs}
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["retr0h"]
|
12
|
-
s.date = %q{2011-01-
|
12
|
+
s.date = %q{2011-01-13}
|
13
13
|
s.email = %q{john@dewey.ws}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
data/lib/hugs/errors.rb
CHANGED
@@ -3,7 +3,10 @@ module Hugs
|
|
3
3
|
class Error < StandardError; end
|
4
4
|
|
5
5
|
class HTTPStatusError < Error
|
6
|
-
|
6
|
+
attr_accessor :response
|
7
|
+
|
8
|
+
def initialize msg, response
|
9
|
+
@response = response
|
7
10
|
super msg
|
8
11
|
end
|
9
12
|
end
|
@@ -66,15 +69,16 @@ module Hugs
|
|
66
69
|
}
|
67
70
|
|
68
71
|
case response.code
|
69
|
-
when raise_4xx && %r{^4[0-9]{2}$} ; raise_for(response
|
70
|
-
when raise_5xx && %r{^5[0-9]{2}$} ; raise_for(response
|
72
|
+
when raise_4xx && %r{^4[0-9]{2}$} ; raise_for(response)
|
73
|
+
when raise_5xx && %r{^5[0-9]{2}$} ; raise_for(response)
|
71
74
|
end
|
72
75
|
end
|
73
76
|
|
74
77
|
private
|
75
|
-
def self.raise_for
|
76
|
-
error, message = @errors[code.to_i]
|
77
|
-
|
78
|
+
def self.raise_for response
|
79
|
+
error, message = @errors[response.code.to_i]
|
80
|
+
|
81
|
+
raise error.new message, response
|
78
82
|
end
|
79
83
|
end
|
80
84
|
end
|
@@ -2,18 +2,9 @@
|
|
2
2
|
|
3
3
|
describe Hugs::Client do
|
4
4
|
before do
|
5
|
-
@
|
6
|
-
@host = "example.com"
|
7
|
-
@port = 80
|
8
|
-
@base = "#{@host}:#{@port}"
|
9
|
-
@valid_options = {
|
10
|
-
:host => @host,
|
11
|
-
:port => @port,
|
12
|
-
:scheme => @scheme,
|
13
|
-
}
|
5
|
+
@instance = Hugs::Client.new valid_options
|
14
6
|
|
15
7
|
WebMock.reset!
|
16
|
-
@instance = Hugs::Client.new @valid_options
|
17
8
|
end
|
18
9
|
|
19
10
|
describe "#response_for" do
|
@@ -23,27 +14,27 @@ describe Hugs::Client do
|
|
23
14
|
|
24
15
|
describe "path" do
|
25
16
|
it "is valid" do
|
26
|
-
stub_request :get,
|
17
|
+
stub_request :get, url
|
27
18
|
|
28
19
|
@instance.send :response_for, @request, "/", {}
|
29
20
|
|
30
|
-
assert_requested :get,
|
21
|
+
assert_requested :get, url
|
31
22
|
end
|
32
23
|
|
33
24
|
it "is valid when an invalid :query is supplied" do
|
34
|
-
stub_request :get,
|
25
|
+
stub_request :get, url
|
35
26
|
|
36
27
|
@instance.send :response_for, @request, "/", :query => nil
|
37
28
|
|
38
|
-
assert_requested :get,
|
29
|
+
assert_requested :get, url
|
39
30
|
end
|
40
31
|
|
41
32
|
it "also has a query string" do
|
42
|
-
stub_request(:get,
|
33
|
+
stub_request(:get, url).with:query => {"foo" => "bar"}
|
43
34
|
|
44
35
|
@instance.send :response_for, @request, "/", :query => "foo=bar"
|
45
36
|
|
46
|
-
assert_requested :get,
|
37
|
+
assert_requested :get, url, :query => {"foo" => "bar"}
|
47
38
|
end
|
48
39
|
end
|
49
40
|
|
@@ -55,7 +46,7 @@ describe Hugs::Client do
|
|
55
46
|
end
|
56
47
|
|
57
48
|
it "uploads a file" do
|
58
|
-
stub_request :post,
|
49
|
+
stub_request :post, url
|
59
50
|
upload = {
|
60
51
|
:upload => {
|
61
52
|
:parts => { :file => "/dev/null" },
|
@@ -65,13 +56,13 @@ describe Hugs::Client do
|
|
65
56
|
|
66
57
|
@instance.send :response_for, @request, "/", upload
|
67
58
|
|
68
|
-
assert_requested :post,
|
59
|
+
assert_requested :post, url, :body => %r{Content-Type: type/subtype}, :headers => {
|
69
60
|
"Content-Type" => Content_Type_Matcher
|
70
61
|
}
|
71
62
|
end
|
72
63
|
|
73
64
|
it "has parts" do
|
74
|
-
stub_request :post,
|
65
|
+
stub_request :post, url
|
75
66
|
upload = {
|
76
67
|
:upload => {
|
77
68
|
:parts => { :foo => :bar, :baz => :xyzzy },
|
@@ -83,7 +74,7 @@ describe Hugs::Client do
|
|
83
74
|
|
84
75
|
### wtf can't use mx together.
|
85
76
|
content_disposition_matcher = %r{^Content-Disposition: form-data; name="foo".*^bar.*^Content-Disposition: form-data; name="baz".*^xyzzy.*}m
|
86
|
-
assert_requested :post,
|
77
|
+
assert_requested :post, url, :body => content_disposition_matcher, :headers => {
|
87
78
|
"Content-Type" => Content_Type_Matcher
|
88
79
|
}
|
89
80
|
end
|
@@ -93,8 +84,8 @@ describe Hugs::Client do
|
|
93
84
|
describe "parses response" do
|
94
85
|
describe "json" do
|
95
86
|
it "objectifies and returns a hash" do
|
96
|
-
stub_request(:get,
|
97
|
-
instance = Hugs::Client.new
|
87
|
+
stub_request(:get, url).to_return :body => '{"foo":"bar"}'
|
88
|
+
instance = Hugs::Client.new valid_options(:type => :json)
|
98
89
|
|
99
90
|
response = instance.get "/"
|
100
91
|
|
@@ -104,8 +95,8 @@ describe Hugs::Client do
|
|
104
95
|
|
105
96
|
describe "xml" do
|
106
97
|
it "parses and returns a Nokogiri object" do
|
107
|
-
stub_request(:get,
|
108
|
-
instance = Hugs::Client.new
|
98
|
+
stub_request(:get, url).to_return :body => "<STORAGE></STORAGE>"
|
99
|
+
instance = Hugs::Client.new valid_options(:type => :xml)
|
109
100
|
|
110
101
|
response = instance.get "/"
|
111
102
|
|
@@ -116,38 +107,38 @@ describe Hugs::Client do
|
|
116
107
|
|
117
108
|
describe "encodes request" do
|
118
109
|
before do
|
119
|
-
stub_request :get,
|
110
|
+
stub_request :get, url
|
120
111
|
end
|
121
112
|
|
122
113
|
it "is not set when :body invalid" do
|
123
114
|
@instance.send :response_for, @request, "/", :body => nil
|
124
115
|
|
125
|
-
assert_requested :get,
|
116
|
+
assert_requested :get, url, :body => nil
|
126
117
|
end
|
127
118
|
|
128
119
|
it "is not set when :body is missing" do
|
129
120
|
@instance.send :response_for, @request, "/", {}
|
130
121
|
|
131
|
-
assert_requested :get,
|
122
|
+
assert_requested :get, url, {}
|
132
123
|
end
|
133
124
|
|
134
125
|
describe "json" do
|
135
126
|
it "is valid" do
|
136
|
-
instance = Hugs::Client.new
|
127
|
+
instance = Hugs::Client.new valid_options(:type => :json)
|
137
128
|
|
138
129
|
instance.send :response_for, @request, "/", :body => {:foo => :bar}
|
139
130
|
|
140
|
-
assert_requested :get,
|
131
|
+
assert_requested :get, url, :body => '{"foo":"bar"}'
|
141
132
|
end
|
142
133
|
end
|
143
134
|
|
144
135
|
describe "xml" do
|
145
136
|
it "is valid" do
|
146
|
-
instance = Hugs::Client.new
|
137
|
+
instance = Hugs::Client.new valid_options(:type => :xml)
|
147
138
|
|
148
139
|
instance.send :response_for, @request, "/", :body => "foo bar"
|
149
140
|
|
150
|
-
assert_requested :get,
|
141
|
+
assert_requested :get, url, :body => "foo bar"
|
151
142
|
end
|
152
143
|
end
|
153
144
|
end
|
@@ -157,11 +148,11 @@ describe Hugs::Client do
|
|
157
148
|
describe "headers" do
|
158
149
|
describe "authentication" do
|
159
150
|
it "uses basic auth when providing user and password" do
|
160
|
-
stub_request :get, "
|
161
|
-
instance = Hugs::Client.new
|
151
|
+
stub_request :get, url("/", "user:credentials")
|
152
|
+
instance = Hugs::Client.new valid_options(:user => "user", :password => "credentials")
|
162
153
|
|
163
154
|
instance.send :response_for, @request, "/", {}
|
164
|
-
assert_requested :get, "
|
155
|
+
assert_requested :get, url("/", "user:credentials")
|
165
156
|
end
|
166
157
|
|
167
158
|
it "doesn't use basic auth without a user" do
|
@@ -216,26 +207,26 @@ describe Hugs::Client do
|
|
216
207
|
|
217
208
|
assert mimetype, "Unsupported Mimetype '#{type}'"
|
218
209
|
|
219
|
-
clazz =
|
210
|
+
clazz = Net::HTTP.const_get verb.capitalize
|
220
211
|
|
221
|
-
stub_request verb,
|
222
|
-
instance = Hugs::Client.new
|
212
|
+
stub_request verb, url
|
213
|
+
instance = Hugs::Client.new valid_options(:type => type)
|
223
214
|
|
224
215
|
instance.send :response_for, clazz, "/", {}
|
225
216
|
|
226
217
|
headers = { "Accept" => ["*/*", mimetype] }
|
227
218
|
headers["Content-Type"] = mimetype if [:put, :put].include? type
|
228
219
|
|
229
|
-
assert_requested verb,
|
220
|
+
assert_requested verb, url, :headers => headers
|
230
221
|
end
|
231
222
|
|
232
223
|
def assert_doesnt_use_basic_auth_without option
|
233
|
-
stub_request :get,
|
234
|
-
instance = Hugs::Client.new
|
224
|
+
stub_request :get, url
|
225
|
+
instance = Hugs::Client.new valid_options(option => "value")
|
235
226
|
|
236
227
|
instance.send :response_for, @request, "/", {}
|
237
228
|
|
238
|
-
assert_requested :get,
|
229
|
+
assert_requested :get, url
|
239
230
|
end
|
240
231
|
end
|
241
232
|
end
|
@@ -2,73 +2,45 @@ require "test_helper"
|
|
2
2
|
|
3
3
|
describe Hugs::Errors do
|
4
4
|
before do
|
5
|
-
@
|
6
|
-
@host = "example.com"
|
7
|
-
@port = 80
|
8
|
-
@base = "#{@host}:#{@port}"
|
9
|
-
@valid_options = {
|
10
|
-
:host => @host,
|
11
|
-
:port => @port,
|
12
|
-
:scheme => @scheme,
|
13
|
-
}
|
5
|
+
@instance = Hugs::Client.new valid_options
|
14
6
|
|
15
|
-
@instance = Hugs::Client.new @valid_options
|
16
7
|
WebMock.reset!
|
17
8
|
end
|
18
9
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
402 => [Hugs::Errors::PaymentRequired, 'Payment Required'],
|
23
|
-
403 => [Hugs::Errors::Forbidden, 'Forbidden'],
|
24
|
-
404 => [Hugs::Errors::NotFound, 'Not Found'],
|
25
|
-
405 => [Hugs::Errors::MethodNotAllowed, 'Method Not Allowed'],
|
26
|
-
406 => [Hugs::Errors::NotAcceptable, 'Not Acceptable'],
|
27
|
-
407 => [Hugs::Errors::ProxyAuthenticationRequired, 'Proxy Authentication Required'],
|
28
|
-
408 => [Hugs::Errors::RequestTimeout, 'Request Timeout'],
|
29
|
-
409 => [Hugs::Errors::Conflict, 'Conflict'],
|
30
|
-
410 => [Hugs::Errors::Gone, 'Gone'],
|
31
|
-
411 => [Hugs::Errors::LengthRequired, 'Length Required'],
|
32
|
-
412 => [Hugs::Errors::PreconditionFailed, 'Precondition Failed'],
|
33
|
-
413 => [Hugs::Errors::RequestEntityTooLarge, 'Request Entity Too Large'],
|
34
|
-
414 => [Hugs::Errors::RequestURITooLong, 'Request-URI Too Long'],
|
35
|
-
415 => [Hugs::Errors::UnsupportedMediaType, 'Unsupported Media Type'],
|
36
|
-
416 => [Hugs::Errors::RequestedRangeNotSatisfiable, 'Request Range Not Satisfiable'],
|
37
|
-
417 => [Hugs::Errors::ExpectationFailed, 'Expectation Failed'],
|
38
|
-
422 => [Hugs::Errors::UnprocessableEntity, 'Unprocessable Entity'],
|
39
|
-
}
|
10
|
+
describe "response codes" do
|
11
|
+
Errors_4xx = (400..417).to_a << 422
|
12
|
+
Errors_5xx = (500..504).to_a
|
40
13
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
503 => [Hugs::Errors::ServiceUnavailable, 'Service Unavailable'],
|
46
|
-
504 => [Hugs::Errors::GatewayTimeout, 'Gateway Timeout']
|
47
|
-
}
|
14
|
+
(Errors_4xx + Errors_5xx).each do |code|
|
15
|
+
it "raises on #{code}" do
|
16
|
+
assert_raises_on code
|
17
|
+
end
|
48
18
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@instance.raise_5xx = false
|
19
|
+
it "does not raise on #{code}" do
|
20
|
+
assert_does_not_raise_on code
|
21
|
+
end
|
53
22
|
end
|
54
23
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
it "raises" do
|
59
|
-
(code.to_s =~ %r{^4[0-9]{2}$}) ? (@instance.raise_4xx = true) : (@instance.raise_5xx = true)
|
60
|
-
stub_request(:get, "#{@scheme}://#{@base}/").to_return :status => [code, message]
|
24
|
+
def assert_raises_on code
|
25
|
+
(code.to_s =~ %r{^4[0-9]{2}$}) ? (@instance.raise_4xx = true) : (@instance.raise_5xx = true)
|
26
|
+
stub_request(:get, url).to_return :status => [code, "error #{code}"]
|
61
27
|
|
62
|
-
|
28
|
+
begin
|
29
|
+
@instance.send :response_for, Net::HTTP::Get, "/", {}
|
30
|
+
rescue => e
|
31
|
+
e.class.superclass.must_be_same_as Hugs::Errors::HTTPStatusError
|
32
|
+
e.must_respond_to :response
|
33
|
+
return
|
63
34
|
end
|
35
|
+
raise StandardError.new "did not raise expected exception"
|
36
|
+
end
|
64
37
|
|
65
|
-
|
66
|
-
|
38
|
+
def assert_does_not_raise_on code
|
39
|
+
stub_request(:get, url).to_return :status => [code, "error #{code}"]
|
67
40
|
|
68
|
-
|
41
|
+
response = @instance.send :response_for, Net::HTTP::Get, "/", {}
|
69
42
|
|
70
|
-
|
71
|
-
end
|
43
|
+
response.code.must_equal code.to_s
|
72
44
|
end
|
73
45
|
end
|
74
46
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
require "bundler"
|
2
2
|
Bundler.setup :default, :test
|
3
3
|
|
4
|
-
%w(minitest/spec webmock ./lib/hugs).each { |r| require r }
|
4
|
+
%w(minitest/spec webmock ./lib/hugs uri).each { |r| require r }
|
5
5
|
|
6
6
|
class MiniTest::Unit::TestCase
|
7
7
|
include WebMock::API
|
8
|
+
|
9
|
+
def valid_options opts = {}
|
10
|
+
{
|
11
|
+
:host => "example.com",
|
12
|
+
:port => 80,
|
13
|
+
:scheme => "https"
|
14
|
+
}.merge opts
|
15
|
+
end
|
16
|
+
|
17
|
+
def url path = "/", credentials = nil
|
18
|
+
URI::HTTPS.build(
|
19
|
+
valid_options(
|
20
|
+
:path => path,
|
21
|
+
:userinfo => credentials
|
22
|
+
)
|
23
|
+
).to_s
|
24
|
+
end
|
8
25
|
end
|
9
26
|
|
10
27
|
MiniTest::Unit.autorun
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 2
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 2.
|
9
|
+
version: 2.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- retr0h
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-13 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|