restfully 0.7.1.rc3 → 0.7.1.rc4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/restfully +3 -0
- data/lib/restfully/collection.rb +5 -16
- data/lib/restfully/http/request.rb +53 -18
- data/lib/restfully/http/response.rb +1 -1
- data/lib/restfully/resource.rb +6 -4
- data/lib/restfully/session.rb +20 -27
- data/lib/restfully/version.rb +1 -1
- data/spec/restfully/http/request_spec.rb +33 -0
- data/spec/restfully/http/response_spec.rb +3 -0
- data/spec/restfully/resource_spec.rb +13 -4
- data/spec/restfully/session_spec.rb +58 -38
- metadata +3 -3
data/bin/restfully
CHANGED
@@ -49,6 +49,9 @@ BANNER
|
|
49
49
|
@options["logger"] = logger
|
50
50
|
end
|
51
51
|
opts.on("-v", "--verbose", "Run verbosely") do |v|
|
52
|
+
@options["logger"].level = Logger::INFO
|
53
|
+
end
|
54
|
+
opts.on("--debug", "Run in debug mode") do |v|
|
52
55
|
@options["logger"].level = Logger::DEBUG
|
53
56
|
end
|
54
57
|
opts.on_tail("-h", "--help", "Show this message") do
|
data/lib/restfully/collection.rb
CHANGED
@@ -14,13 +14,13 @@ module Restfully
|
|
14
14
|
super(property)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def find_by_uid(symbol)
|
19
19
|
found = find{ |i| i.media_type.represents?(symbol) }
|
20
20
|
found.expand unless found.nil?
|
21
21
|
found
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def find_by_index(index)
|
25
25
|
index = index+length if index < 0
|
26
26
|
each_with_index{|item, i|
|
@@ -69,27 +69,16 @@ module Restfully
|
|
69
69
|
def empty?
|
70
70
|
total == 0
|
71
71
|
end
|
72
|
-
|
73
|
-
# Expand the items that
|
72
|
+
|
73
|
+
# Expand the items that
|
74
74
|
def expand
|
75
75
|
each {|i| i.expand}
|
76
76
|
self
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def inspect
|
80
80
|
map{|item| item}.inspect
|
81
81
|
end
|
82
|
-
# def (key)
|
83
|
-
# p Addressable::URI.parse("./"+key.to_s)
|
84
|
-
# p self.uri
|
85
|
-
# uri_to_find = Addressable::URI.join(self.uri, "./"+key.to_s)
|
86
|
-
# p uri_to_find
|
87
|
-
# find{|resource|
|
88
|
-
# resource.uri == uri_to_find
|
89
|
-
# }
|
90
|
-
# end
|
91
|
-
|
92
|
-
|
93
82
|
end
|
94
83
|
|
95
84
|
end
|
@@ -2,27 +2,33 @@
|
|
2
2
|
|
3
3
|
module Restfully
|
4
4
|
module HTTP
|
5
|
-
|
5
|
+
|
6
6
|
class Request
|
7
7
|
include Helper
|
8
|
-
|
9
|
-
attr_reader :method, :uri, :head, :body
|
10
|
-
|
11
|
-
|
8
|
+
|
9
|
+
attr_reader :session, :method, :uri, :head, :body, :attempts
|
10
|
+
attr_accessor :retry_on_error, :wait_before_retry
|
11
|
+
|
12
|
+
def initialize(session, method, path, options = {})
|
12
13
|
@session = session
|
13
|
-
|
14
|
+
@attempts = 0
|
15
|
+
|
14
16
|
request = options.symbolize_keys
|
17
|
+
|
18
|
+
@retry_on_error = request[:retry_on_error] || session.config[:retry_on_error]
|
19
|
+
@wait_before_retry = request[:wait_before_retry] || session.config[:wait_before_retry]
|
20
|
+
|
15
21
|
request[:method] = method
|
16
22
|
|
17
23
|
request[:head] = sanitize_head(@session.default_headers).merge(
|
18
24
|
build_head(request)
|
19
25
|
)
|
20
|
-
|
26
|
+
|
21
27
|
request[:uri] = @session.uri_to(path)
|
22
28
|
if request[:query]
|
23
29
|
request[:uri].query_values = sanitize_query(request[:query])
|
24
30
|
end
|
25
|
-
|
31
|
+
|
26
32
|
request[:body] = if [:post, :put].include?(request[:method])
|
27
33
|
build_body(request)
|
28
34
|
end
|
@@ -30,9 +36,10 @@ module Restfully
|
|
30
36
|
@method, @uri, @head, @body = request.values_at(
|
31
37
|
:method, :uri, :head, :body
|
32
38
|
)
|
39
|
+
|
33
40
|
end
|
34
|
-
|
35
|
-
# Updates the request header and query parameters
|
41
|
+
|
42
|
+
# Updates the request header and query parameters.
|
36
43
|
# Returns nil if no changes were made, otherwise self.
|
37
44
|
def update!(options = {})
|
38
45
|
objects_that_may_be_updated = [@uri, @head]
|
@@ -48,33 +55,61 @@ module Restfully
|
|
48
55
|
self
|
49
56
|
end
|
50
57
|
end
|
51
|
-
|
58
|
+
|
52
59
|
def inspect
|
53
60
|
"#{method.to_s.upcase} #{uri.to_s}, head=#{head.inspect}, body=#{body.inspect}"
|
54
61
|
end
|
55
|
-
|
62
|
+
|
56
63
|
def no_cache?
|
57
64
|
head['Cache-Control'] && head['Cache-Control'].include?('no-cache')
|
58
65
|
end
|
59
|
-
|
66
|
+
|
60
67
|
def no_cache!
|
61
68
|
@forced_cache = true
|
62
69
|
head['Cache-Control'] = 'no-cache'
|
63
70
|
end
|
64
|
-
|
71
|
+
|
65
72
|
def forced_cache?
|
66
73
|
!!@forced_cache
|
67
74
|
end
|
68
|
-
|
75
|
+
|
76
|
+
def execute!
|
77
|
+
session.logger.debug self.inspect
|
78
|
+
resource = RestClient::Resource.new(
|
79
|
+
uri.to_s,
|
80
|
+
:headers => head
|
81
|
+
)
|
82
|
+
|
83
|
+
begin
|
84
|
+
reqcode, reqhead, reqbody = resource.send(method, body || {})
|
85
|
+
response = Response.new(session, reqcode, reqhead, reqbody)
|
86
|
+
session.logger.debug response.inspect
|
87
|
+
response
|
88
|
+
rescue Errno::ECONNREFUSED => e
|
89
|
+
retry! || raise(e)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def retry!
|
94
|
+
if @attempts < @retry_on_error
|
95
|
+
@attempts+=1
|
96
|
+
session.logger.info "Encountered connection or server error. Retrying in #{@wait_before_retry}s... [#{@attempts}/#{@retry_on_error}]"
|
97
|
+
sleep @wait_before_retry if @wait_before_retry > 0
|
98
|
+
execute!
|
99
|
+
else
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
69
104
|
def remove_no_cache!
|
70
105
|
@forced_cache = false
|
71
106
|
if head['Cache-Control']
|
72
|
-
head['Cache-Control'] = head['Cache-Control'].split(/\s+,\s+/).reject{|v|
|
107
|
+
head['Cache-Control'] = head['Cache-Control'].split(/\s+,\s+/).reject{|v|
|
73
108
|
v =~ /no-cache/i
|
74
109
|
}.join(",")
|
75
110
|
end
|
76
111
|
end
|
77
|
-
|
112
|
+
|
78
113
|
protected
|
79
114
|
def build_head(options = {})
|
80
115
|
sanitize_head(
|
@@ -94,7 +129,7 @@ module Restfully
|
|
94
129
|
nil
|
95
130
|
end
|
96
131
|
end
|
97
|
-
|
132
|
+
|
98
133
|
end
|
99
134
|
end
|
100
135
|
end
|
data/lib/restfully/resource.rb
CHANGED
@@ -25,7 +25,10 @@ module Restfully
|
|
25
25
|
# resource["uid"]
|
26
26
|
# => "rennes"
|
27
27
|
def [](key)
|
28
|
-
|
28
|
+
unless collection?
|
29
|
+
expand
|
30
|
+
end
|
31
|
+
media_type.property(key)
|
29
32
|
end
|
30
33
|
|
31
34
|
def uri
|
@@ -58,7 +61,7 @@ module Restfully
|
|
58
61
|
def load(options = {})
|
59
62
|
# Send a GET request only if given a different set of options
|
60
63
|
if @request.update!(options) || @request.no_cache?
|
61
|
-
@response =
|
64
|
+
@response = @request.execute!
|
62
65
|
@request.remove_no_cache! if @request.forced_cache?
|
63
66
|
if session.process(@response, @request)
|
64
67
|
@associations.clear
|
@@ -121,8 +124,7 @@ module Restfully
|
|
121
124
|
end
|
122
125
|
|
123
126
|
def allow?(method)
|
124
|
-
reload
|
125
|
-
response.allow?(method)
|
127
|
+
response.allow?(method) || reload.response.allow?(method)
|
126
128
|
end
|
127
129
|
|
128
130
|
def inspect
|
data/lib/restfully/session.rb
CHANGED
@@ -16,6 +16,8 @@ module Restfully
|
|
16
16
|
def initialize(options = {})
|
17
17
|
@config = options.symbolize_keys
|
18
18
|
@logger = @config.delete(:logger) || Logger.new(STDERR)
|
19
|
+
@config[:retry_on_error] ||= 5
|
20
|
+
@config[:wait_before_retry] ||= 5
|
19
21
|
|
20
22
|
@uri = @config.delete(:uri)
|
21
23
|
if @uri.nil? || @uri.empty?
|
@@ -100,29 +102,14 @@ module Restfully
|
|
100
102
|
transmit :delete, path, options
|
101
103
|
end
|
102
104
|
|
103
|
-
# Build and
|
105
|
+
# Build and execute the corresponding HTTP request,
|
106
|
+
# then process the response.
|
104
107
|
def transmit(method, path, options)
|
105
108
|
request = HTTP::Request.new(self, method, path, options)
|
106
|
-
|
107
|
-
response = execute(request)
|
108
|
-
|
109
|
+
response = request.execute!
|
109
110
|
process(response, request)
|
110
111
|
end
|
111
112
|
|
112
|
-
def execute(request)
|
113
|
-
resource = RestClient::Resource.new(
|
114
|
-
request.uri.to_s,
|
115
|
-
:headers => request.head
|
116
|
-
)
|
117
|
-
|
118
|
-
logger.debug request.inspect
|
119
|
-
code, head, body = resource.send(request.method, request.body || {})
|
120
|
-
|
121
|
-
response = Restfully::HTTP::Response.new(self, code, head, body)
|
122
|
-
logger.debug response.inspect
|
123
|
-
response
|
124
|
-
end
|
125
|
-
|
126
113
|
# Process a Restfully::HTTP::Response.
|
127
114
|
def process(response, request)
|
128
115
|
case code=response.code
|
@@ -135,14 +122,15 @@ module Restfully
|
|
135
122
|
when 204
|
136
123
|
true
|
137
124
|
when 400..499
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
125
|
+
raise HTTP::ClientError, error_message(request, response)
|
126
|
+
when 502..504
|
127
|
+
if res = request.retry!
|
128
|
+
process(res, request)
|
129
|
+
else
|
130
|
+
raise(HTTP::ServerError, error_message(request, response))
|
131
|
+
end
|
132
|
+
when 500, 501
|
133
|
+
raise HTTP::ServerError, error_message(request, response)
|
146
134
|
else
|
147
135
|
raise Error, "Restfully does not handle code #{code.inspect}."
|
148
136
|
end
|
@@ -150,7 +138,12 @@ module Restfully
|
|
150
138
|
|
151
139
|
protected
|
152
140
|
def setup_cache
|
153
|
-
enable ::Rack::Cache, :verbose => (logger.level
|
141
|
+
enable ::Rack::Cache, :verbose => (logger.level <= Logger::INFO)
|
142
|
+
end
|
143
|
+
|
144
|
+
def error_message(request, response)
|
145
|
+
msg = "Encountered error #{response.code} on #{request.method.upcase} #{request.uri}"
|
146
|
+
msg += " --- #{response.body[0..200]}" unless response.body.empty?
|
154
147
|
end
|
155
148
|
|
156
149
|
end
|
data/lib/restfully/version.rb
CHANGED
@@ -7,6 +7,11 @@ describe Restfully::HTTP::Request do
|
|
7
7
|
:default_headers => {
|
8
8
|
'Accept' => '*/*; application/xml',
|
9
9
|
:accept_encoding => "gzip, deflate"
|
10
|
+
},
|
11
|
+
:logger => Logger.new(STDERR),
|
12
|
+
:config => {
|
13
|
+
:retry_on_error => 5,
|
14
|
+
:wait_before_retry => 5
|
10
15
|
}
|
11
16
|
)
|
12
17
|
|
@@ -102,5 +107,33 @@ describe Restfully::HTTP::Request do
|
|
102
107
|
request.body.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<network xmlns=\"http://api.bonfire-project.eu/doc/schemas/occi\">\n <name>whatever</name>\n</network>\n"
|
103
108
|
end
|
104
109
|
end
|
110
|
+
|
111
|
+
describe "execute" do
|
112
|
+
before do
|
113
|
+
@request = Restfully::HTTP::Request.new(
|
114
|
+
@session,
|
115
|
+
:get,
|
116
|
+
"/path"
|
117
|
+
)
|
118
|
+
end
|
119
|
+
it "should build the RestClient::Resource and build a response" do
|
120
|
+
RestClient::Resource.should_receive(:new).with(
|
121
|
+
@request.uri.to_s,
|
122
|
+
:headers => @request.head
|
123
|
+
).and_return(
|
124
|
+
resource = mock(RestClient::Resource)
|
125
|
+
)
|
126
|
+
resource.should_receive(:get).and_return([
|
127
|
+
200,
|
128
|
+
{'Content-Type' => 'text/plain'},
|
129
|
+
["hello"]
|
130
|
+
])
|
131
|
+
response = @request.execute!
|
132
|
+
response.should be_a(Restfully::HTTP::Response)
|
133
|
+
response.code.should == 200
|
134
|
+
response.body.should == "hello"
|
135
|
+
response.head.should == {'Content-Type' => 'text/plain'}
|
136
|
+
end
|
137
|
+
end
|
105
138
|
|
106
139
|
end
|
@@ -36,6 +36,9 @@ describe Restfully::HTTP::Response do
|
|
36
36
|
|
37
37
|
response.allow?(:get).should be_true
|
38
38
|
response.allow?(:post).should be_true
|
39
|
+
response.allow?("POST").should be_true
|
40
|
+
response.allow?("GET").should be_true
|
41
|
+
response.allow?("PUT").should be_false
|
39
42
|
end
|
40
43
|
|
41
44
|
it "should raise an error if it cannot find a corresponding media-type" do
|
@@ -45,14 +45,23 @@ describe Restfully::Resource do
|
|
45
45
|
@resource.clusters
|
46
46
|
end
|
47
47
|
{:update => "PUT", :submit => "POST", :delete => "DELETE"}.each do |method, http_method|
|
48
|
-
it "should
|
49
|
-
@resource.should_receive(:reload).once.and_return(@resource)
|
48
|
+
it "should get the Allowed HTTP methods when calling #{method.to_sym}" do
|
50
49
|
@response.should_receive(:allow?).with(http_method).and_return(true)
|
51
50
|
@session.should_receive(http_method.downcase.to_sym).
|
52
51
|
and_return(mock(Restfully::HTTP::Response))
|
53
52
|
@resource.send(method.to_sym)
|
54
53
|
end
|
55
54
|
end
|
55
|
+
{:update => "PUT", :submit => "POST", :delete => "DELETE"}.each do |method, http_method|
|
56
|
+
it "should reload itself to get the Allowed HTTP methods when calling #{method.to_sym}" do
|
57
|
+
@response.should_receive(:allow?).with(http_method).and_return(false)
|
58
|
+
@response.should_receive(:allow?).with(http_method).and_return(true)
|
59
|
+
@resource.should_receive(:reload).once.and_return(@resource)
|
60
|
+
@session.should_receive(http_method.downcase.to_sym).
|
61
|
+
and_return(mock(Restfully::HTTP::Response))
|
62
|
+
@resource.send(method.to_sym)
|
63
|
+
end
|
64
|
+
end
|
56
65
|
it "should not allow to submit if POST not allowed on the resource" do
|
57
66
|
@resource.should_receive(:reload).and_return(@resource)
|
58
67
|
lambda{
|
@@ -125,14 +134,14 @@ describe Restfully::Resource do
|
|
125
134
|
end
|
126
135
|
|
127
136
|
it "should reload the resource even after having reloaded it once before" do
|
128
|
-
@
|
137
|
+
@request.should_receive(:execute!).twice.
|
129
138
|
and_return(@response)
|
130
139
|
@resource.reload
|
131
140
|
@resource.reload
|
132
141
|
end
|
133
142
|
|
134
143
|
it "should raise an error if it cannot reload the resource" do
|
135
|
-
@
|
144
|
+
@request.should_receive(:execute!).
|
136
145
|
and_return(res=mock(Restfully::HTTP::Response))
|
137
146
|
@session.should_receive(:process).with(res, @request).
|
138
147
|
and_return(false)
|
@@ -10,20 +10,20 @@ describe Restfully::Session do
|
|
10
10
|
:logger => @logger
|
11
11
|
}
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "should initialize a session with the correct properties" do
|
15
15
|
session = Restfully::Session.new(@config.merge("key" => "value"))
|
16
16
|
session.logger.should == @logger
|
17
17
|
session.uri.should == Addressable::URI.parse(@uri)
|
18
|
-
session.config.should == {:key
|
18
|
+
session.config.should == {:wait_before_retry=>5, :key=>"value", :retry_on_error=>5}
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it "should raise an error if no URI given" do
|
22
22
|
lambda{
|
23
23
|
Restfully::Session.new(@config.merge(:uri => ""))
|
24
24
|
}.should raise_error(ArgumentError)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it "should fetch the root path [no URI path]" do
|
28
28
|
session = Restfully::Session.new(@config)
|
29
29
|
session.should_receive(:get).with("").
|
@@ -31,7 +31,7 @@ describe Restfully::Session do
|
|
31
31
|
res.should_receive(:load).and_return(res)
|
32
32
|
session.root.should == res
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it "should fetch the root path [URI path present]" do
|
36
36
|
session = Restfully::Session.new(
|
37
37
|
@config.merge(:uri => "https://api.grid5000.fr/resource/path")
|
@@ -41,21 +41,21 @@ describe Restfully::Session do
|
|
41
41
|
res.should_receive(:load).and_return(res)
|
42
42
|
session.root.should == res
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "should add or replace additional headers to the default set" do
|
46
46
|
session = Restfully::Session.new(
|
47
47
|
@config.merge(:default_headers => {
|
48
|
-
'Accept' => 'application/xml',
|
48
|
+
'Accept' => 'application/xml',
|
49
49
|
'Cache-Control' => 'no-cache'
|
50
50
|
})
|
51
51
|
)
|
52
52
|
session.default_headers.should == {
|
53
|
-
'Accept' => 'application/xml',
|
53
|
+
'Accept' => 'application/xml',
|
54
54
|
'Cache-Control' => 'no-cache',
|
55
55
|
'Accept-Encoding' => 'gzip, deflate'
|
56
56
|
}
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
describe "middleware" do
|
60
60
|
it "should only have Rack::Cache enabled by default" do
|
61
61
|
session = Restfully::Session.new(@config)
|
@@ -64,7 +64,7 @@ describe Restfully::Session do
|
|
64
64
|
Rack::Cache
|
65
65
|
]
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it "should use Restfully::Rack::BasicAuth if basic authentication is used" do
|
69
69
|
session = Restfully::Session.new(@config.merge(
|
70
70
|
:username => "crohr", :password => "p4ssw0rd"
|
@@ -76,15 +76,15 @@ describe Restfully::Session do
|
|
76
76
|
]
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
describe "transmitting requests" do
|
81
81
|
before do
|
82
82
|
@session = Restfully::Session.new(@config)
|
83
83
|
@path = "/path"
|
84
84
|
@default_headers = @session.default_headers
|
85
85
|
end
|
86
|
-
|
87
|
-
it "should make a get request" do
|
86
|
+
|
87
|
+
it "should make a get request" do
|
88
88
|
stub_request(:get, @uri+@path+"?k1=v1&k2=v2").with(
|
89
89
|
:headers => @default_headers.merge({
|
90
90
|
'Accept' => '*/*',
|
@@ -106,13 +106,13 @@ describe Restfully::Session do
|
|
106
106
|
@response,
|
107
107
|
instance_of(Restfully::HTTP::Request)
|
108
108
|
)
|
109
|
-
|
109
|
+
|
110
110
|
@session.transmit :get, @path, {
|
111
111
|
:query => {:k1 => "v1", :k2 => "v2"},
|
112
112
|
:headers => {'X-Header' => 'value'}
|
113
113
|
}
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
it "should make an authenticated get request" do
|
117
117
|
stub_request(:get, "https://crohr:p4ssw0rd@api.grid5000.fr"+@path+"?k1=v1&k2=v2").with(
|
118
118
|
:headers => @default_headers.merge({
|
@@ -127,57 +127,77 @@ describe Restfully::Session do
|
|
127
127
|
:headers => {'X-Header' => 'value'}
|
128
128
|
}
|
129
129
|
end
|
130
|
+
|
131
|
+
it "should retry for at most :max_attempts_on_connection_error if connection to the server failed" do
|
132
|
+
|
133
|
+
end
|
130
134
|
end
|
131
|
-
|
135
|
+
|
132
136
|
describe "processing responses" do
|
133
137
|
before do
|
134
138
|
@session = Restfully::Session.new(@config)
|
135
|
-
@request =
|
136
|
-
|
137
|
-
:
|
138
|
-
|
139
|
-
:head => mock("head"),
|
140
|
-
:update! => nil
|
139
|
+
@request = Restfully::HTTP::Request.new(
|
140
|
+
@session,
|
141
|
+
:get,
|
142
|
+
@uri
|
141
143
|
)
|
144
|
+
@request.stub!(:head).and_return({})
|
145
|
+
@request.stub!(:update!).and_return(nil)
|
146
|
+
|
142
147
|
@response = Restfully::HTTP::Response.new(
|
143
148
|
@session,
|
144
149
|
200,
|
145
|
-
{'X' => 'Y'},
|
150
|
+
{'X' => 'Y', 'Content-Type' => 'text/plain'},
|
146
151
|
'body'
|
147
152
|
)
|
148
153
|
end
|
149
|
-
|
154
|
+
|
150
155
|
it "should return true if status=204" do
|
151
156
|
@response.stub!(:code).and_return(204)
|
152
157
|
@session.process(@response, @request).should be_true
|
153
158
|
end
|
154
|
-
|
159
|
+
|
155
160
|
it "should raise a Restfully::HTTP::ClientError if status in 400..499" do
|
156
161
|
@response.stub!(:code).and_return(400)
|
157
162
|
lambda{
|
158
163
|
@session.process(@response, @request)
|
159
164
|
}.should raise_error(Restfully::HTTP::ClientError)
|
160
165
|
end
|
161
|
-
|
166
|
+
|
162
167
|
it "should raise a Restfully::HTTP::ServerError if status in 500..599" do
|
163
168
|
@response.stub!(:code).and_return(500)
|
164
169
|
lambda{
|
165
170
|
@session.process(@response, @request)
|
166
171
|
}.should raise_error(Restfully::HTTP::ServerError)
|
167
172
|
end
|
168
|
-
|
173
|
+
it "should retry if the server returns one of [502,503,504], and request.retry! returns a response" do
|
174
|
+
@request.should_receive(:retry!).once.
|
175
|
+
and_return(@response)
|
176
|
+
@response.should_receive(:code).ordered.and_return(503)
|
177
|
+
@response.should_receive(:code).ordered.and_return(200)
|
178
|
+
@session.process(@response, @request)
|
179
|
+
end
|
180
|
+
it "should not retry if the server returns one of [502,503,504], but request.retry! returns false" do
|
181
|
+
@request.should_receive(:retry!).once.
|
182
|
+
and_return(false)
|
183
|
+
@response.stub!(:code).and_return(503)
|
184
|
+
lambda{
|
185
|
+
@session.process(@response, @request)
|
186
|
+
}.should raise_error(Restfully::HTTP::ServerError, /503/)
|
187
|
+
end
|
188
|
+
|
169
189
|
it "should raise an error if the status is not supported" do
|
170
190
|
@response.stub!(:code).and_return(50)
|
171
191
|
lambda{
|
172
192
|
@session.process(@response, @request)
|
173
193
|
}.should raise_error(Restfully::Error)
|
174
194
|
end
|
175
|
-
|
195
|
+
|
176
196
|
[201, 202].each do |status|
|
177
197
|
it "should fetch the resource specified in the Location header if status = #{status}" do
|
178
198
|
@response.stub!(:code).and_return(status)
|
179
199
|
@response.head['Location'] = @uri+"/path"
|
180
|
-
|
200
|
+
|
181
201
|
@session.should_receive(:get).
|
182
202
|
with(@uri+"/path", :head => @request.head).
|
183
203
|
and_return(resource=mock("resource"))
|
@@ -185,7 +205,7 @@ describe Restfully::Session do
|
|
185
205
|
should == resource
|
186
206
|
end
|
187
207
|
end
|
188
|
-
|
208
|
+
|
189
209
|
it "should return a Restfully::Resource if successful" do
|
190
210
|
Restfully::MediaType.register Restfully::MediaType::ApplicationJson
|
191
211
|
body = {
|
@@ -197,33 +217,33 @@ describe Restfully::Session do
|
|
197
217
|
{'Content-Type' => 'application/json'},
|
198
218
|
JSON.dump(body)
|
199
219
|
)
|
200
|
-
|
220
|
+
|
201
221
|
resource = @session.process(
|
202
222
|
@response,
|
203
223
|
@request
|
204
224
|
)
|
205
|
-
|
225
|
+
|
206
226
|
resource.should be_a(Restfully::Resource)
|
207
227
|
resource.uri.should == @request.uri
|
208
228
|
resource['key1'].should == body[:key1]
|
209
229
|
resource['key2'].should == body[:key2]
|
210
230
|
end
|
211
|
-
|
231
|
+
|
212
232
|
it "should raise an error if the response content-type is not supported" do
|
213
233
|
@response = Restfully::HTTP::Response.new(
|
214
234
|
@session, 200,
|
215
235
|
{'Content-Type' => ''},
|
216
236
|
'body'
|
217
237
|
)
|
218
|
-
|
219
|
-
lambda{
|
220
|
-
@session.process(@response,@request)
|
238
|
+
|
239
|
+
lambda{
|
240
|
+
@session.process(@response,@request)
|
221
241
|
}.should raise_error(
|
222
|
-
Restfully::Error,
|
242
|
+
Restfully::Error,
|
223
243
|
"Cannot find a media-type for content-type=\"\""
|
224
244
|
)
|
225
245
|
end
|
226
246
|
end
|
227
|
-
|
247
|
+
|
228
248
|
end
|
229
249
|
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restfully
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15424101
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
9
|
- 1
|
10
10
|
- rc
|
11
|
-
-
|
12
|
-
version: 0.7.1.
|
11
|
+
- 4
|
12
|
+
version: 0.7.1.rc4
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Cyril Rohr
|