rest-client 1.8.0 → 2.1.0
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.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.mailmap +10 -0
- data/.rspec +2 -1
- data/.rubocop +2 -0
- data/.rubocop-disables.yml +386 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +56 -8
- data/AUTHORS +26 -1
- data/README.md +901 -0
- data/Rakefile +27 -3
- data/bin/restclient +3 -5
- data/history.md +181 -0
- data/lib/restclient/abstract_response.rb +172 -55
- data/lib/restclient/exceptions.rb +96 -55
- data/lib/restclient/params_array.rb +72 -0
- data/lib/restclient/payload.rb +70 -74
- data/lib/restclient/platform.rb +19 -0
- data/lib/restclient/raw_response.rb +21 -7
- data/lib/restclient/request.rb +540 -281
- data/lib/restclient/resource.rb +19 -9
- data/lib/restclient/response.rb +75 -6
- data/lib/restclient/utils.rb +274 -0
- data/lib/restclient/version.rb +2 -1
- data/lib/restclient.rb +21 -3
- data/rest-client.gemspec +12 -10
- data/spec/ISS.jpg +0 -0
- data/spec/helpers.rb +54 -0
- data/spec/integration/_lib.rb +1 -0
- data/spec/integration/capath_digicert/3513523f.0 +22 -0
- data/spec/integration/capath_digicert/399e7759.0 +22 -0
- data/spec/integration/capath_digicert/digicert.crt +20 -17
- data/spec/integration/certs/digicert.crt +20 -17
- data/spec/integration/httpbin_spec.rb +128 -0
- data/spec/integration/integration_spec.rb +97 -14
- data/spec/integration/request_spec.rb +25 -2
- data/spec/spec_helper.rb +28 -1
- data/spec/unit/_lib.rb +1 -0
- data/spec/unit/abstract_response_spec.rb +95 -38
- data/spec/unit/exceptions_spec.rb +41 -28
- data/spec/unit/params_array_spec.rb +36 -0
- data/spec/unit/payload_spec.rb +118 -68
- data/spec/unit/raw_response_spec.rb +10 -6
- data/spec/unit/request2_spec.rb +34 -12
- data/spec/unit/request_spec.rb +745 -424
- data/spec/unit/resource_spec.rb +31 -27
- data/spec/unit/response_spec.rb +134 -57
- data/spec/unit/restclient_spec.rb +16 -15
- data/spec/unit/utils_spec.rb +147 -0
- data/spec/unit/windows/root_certs_spec.rb +3 -3
- metadata +79 -29
- data/README.rdoc +0 -324
- data/spec/integration/capath_digicert/244b5494.0 +0 -19
- data/spec/integration/capath_digicert/81b9768f.0 +0 -19
- data/spec/unit/master_shake.jpg +0 -0
@@ -1,32 +1,32 @@
|
|
1
|
-
|
1
|
+
require_relative '_lib'
|
2
2
|
|
3
3
|
describe RestClient::Exception do
|
4
4
|
it "returns a 'message' equal to the class name if the message is not set, because 'message' should not be nil" do
|
5
5
|
e = RestClient::Exception.new
|
6
|
-
e.message.
|
6
|
+
expect(e.message).to eq "RestClient::Exception"
|
7
7
|
end
|
8
8
|
|
9
9
|
it "returns the 'message' that was set" do
|
10
10
|
e = RestClient::Exception.new
|
11
11
|
message = "An explicitly set message"
|
12
12
|
e.message = message
|
13
|
-
e.message.
|
13
|
+
expect(e.message).to eq message
|
14
14
|
end
|
15
15
|
|
16
16
|
it "sets the exception message to ErrorMessage" do
|
17
|
-
RestClient::ResourceNotFound.new.message.
|
17
|
+
expect(RestClient::ResourceNotFound.new.message).to eq 'Not Found'
|
18
18
|
end
|
19
19
|
|
20
20
|
it "contains exceptions in RestClient" do
|
21
|
-
RestClient::Unauthorized.new.
|
22
|
-
RestClient::ServerBrokeConnection.new.
|
21
|
+
expect(RestClient::Unauthorized.new).to be_a_kind_of(RestClient::Exception)
|
22
|
+
expect(RestClient::ServerBrokeConnection.new).to be_a_kind_of(RestClient::Exception)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe RestClient::ServerBrokeConnection do
|
27
27
|
it "should have a default message of 'Server broke connection'" do
|
28
28
|
e = RestClient::ServerBrokeConnection.new
|
29
|
-
e.message.
|
29
|
+
expect(e.message).to eq 'Server broke connection'
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -40,21 +40,21 @@ describe RestClient::RequestFailed do
|
|
40
40
|
begin
|
41
41
|
raise RestClient::RequestFailed, response
|
42
42
|
rescue RestClient::RequestFailed => e
|
43
|
-
e.response.
|
43
|
+
expect(e.response).to eq response
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
it "http_code convenience method for fetching the code as an integer" do
|
48
|
-
RestClient::RequestFailed.new(@response).http_code.
|
48
|
+
expect(RestClient::RequestFailed.new(@response).http_code).to eq 502
|
49
49
|
end
|
50
50
|
|
51
51
|
it "http_body convenience method for fetching the body (decoding when necessary)" do
|
52
|
-
RestClient::RequestFailed.new(@response).http_code.
|
53
|
-
RestClient::RequestFailed.new(@response).message.
|
52
|
+
expect(RestClient::RequestFailed.new(@response).http_code).to eq 502
|
53
|
+
expect(RestClient::RequestFailed.new(@response).message).to eq 'HTTP status code 502'
|
54
54
|
end
|
55
55
|
|
56
56
|
it "shows the status code in the message" do
|
57
|
-
RestClient::RequestFailed.new(@response).to_s.
|
57
|
+
expect(RestClient::RequestFailed.new(@response).to_s).to match(/502/)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -64,32 +64,45 @@ describe RestClient::ResourceNotFound do
|
|
64
64
|
begin
|
65
65
|
raise RestClient::ResourceNotFound, response
|
66
66
|
rescue RestClient::ResourceNotFound => e
|
67
|
-
e.response.
|
67
|
+
expect(e.response).to eq response
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'stores the body on the response of the exception' do
|
72
|
+
body = "body"
|
73
|
+
stub_request(:get, "www.example.com").to_return(:body => body, :status => 404)
|
74
|
+
begin
|
75
|
+
RestClient.get "www.example.com"
|
76
|
+
raise
|
77
|
+
rescue RestClient::ResourceNotFound => e
|
78
|
+
expect(e.response.body).to eq body
|
68
79
|
end
|
69
80
|
end
|
70
81
|
end
|
71
82
|
|
72
83
|
describe "backwards compatibility" do
|
73
|
-
it
|
74
|
-
RestClient::
|
84
|
+
it 'aliases RestClient::NotFound as ResourceNotFound' do
|
85
|
+
expect(RestClient::ResourceNotFound).to eq RestClient::NotFound
|
75
86
|
end
|
76
87
|
|
77
|
-
it
|
78
|
-
RestClient::
|
88
|
+
it 'aliases old names for HTTP 413, 414, 416' do
|
89
|
+
expect(RestClient::RequestEntityTooLarge).to eq RestClient::PayloadTooLarge
|
90
|
+
expect(RestClient::RequestURITooLong).to eq RestClient::URITooLong
|
91
|
+
expect(RestClient::RequestedRangeNotSatisfiable).to eq RestClient::RangeNotSatisfiable
|
79
92
|
end
|
80
93
|
|
81
|
-
it
|
82
|
-
RestClient::
|
94
|
+
it 'subclasses NotFound from RequestFailed, ExceptionWithResponse' do
|
95
|
+
expect(RestClient::NotFound).to be < RestClient::RequestFailed
|
96
|
+
expect(RestClient::NotFound).to be < RestClient::ExceptionWithResponse
|
83
97
|
end
|
84
98
|
|
85
|
-
it
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
e.response.body.should eq body
|
93
|
-
end
|
99
|
+
it 'subclasses timeout from RestClient::RequestTimeout, RequestFailed, EWR' do
|
100
|
+
expect(RestClient::Exceptions::OpenTimeout).to be < RestClient::Exceptions::Timeout
|
101
|
+
expect(RestClient::Exceptions::ReadTimeout).to be < RestClient::Exceptions::Timeout
|
102
|
+
|
103
|
+
expect(RestClient::Exceptions::Timeout).to be < RestClient::RequestTimeout
|
104
|
+
expect(RestClient::Exceptions::Timeout).to be < RestClient::RequestFailed
|
105
|
+
expect(RestClient::Exceptions::Timeout).to be < RestClient::ExceptionWithResponse
|
94
106
|
end
|
107
|
+
|
95
108
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '_lib'
|
2
|
+
|
3
|
+
describe RestClient::ParamsArray do
|
4
|
+
|
5
|
+
describe '.new' do
|
6
|
+
it 'accepts various types of containers' do
|
7
|
+
as_array = [[:foo, 123], [:foo, 456], [:bar, 789], [:empty, nil]]
|
8
|
+
[
|
9
|
+
[[:foo, 123], [:foo, 456], [:bar, 789], [:empty, nil]],
|
10
|
+
[{foo: 123}, {foo: 456}, {bar: 789}, {empty: nil}],
|
11
|
+
[{foo: 123}, {foo: 456}, {bar: 789}, {empty: nil}],
|
12
|
+
[{foo: 123}, [:foo, 456], {bar: 789}, {empty: nil}],
|
13
|
+
[{foo: 123}, [:foo, 456], {bar: 789}, [:empty]],
|
14
|
+
].each do |input|
|
15
|
+
expect(RestClient::ParamsArray.new(input).to_a).to eq as_array
|
16
|
+
end
|
17
|
+
|
18
|
+
expect(RestClient::ParamsArray.new([]).to_a).to eq []
|
19
|
+
expect(RestClient::ParamsArray.new([]).empty?).to eq true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'rejects various invalid input' do
|
23
|
+
expect {
|
24
|
+
RestClient::ParamsArray.new([[]])
|
25
|
+
}.to raise_error(IndexError)
|
26
|
+
|
27
|
+
expect {
|
28
|
+
RestClient::ParamsArray.new([[1,2,3]])
|
29
|
+
}.to raise_error(ArgumentError)
|
30
|
+
|
31
|
+
expect {
|
32
|
+
RestClient::ParamsArray.new([1,2,3])
|
33
|
+
}.to raise_error(NoMethodError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/spec/unit/payload_spec.rb
CHANGED
@@ -1,60 +1,68 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '_lib'
|
4
|
+
|
5
|
+
describe RestClient::Payload, :include_helpers do
|
6
|
+
context "Base Payload" do
|
7
|
+
it "should reset stream after to_s" do
|
8
|
+
payload = RestClient::Payload::Base.new('foobar')
|
9
|
+
expect(payload.to_s).to eq 'foobar'
|
10
|
+
expect(payload.to_s).to eq 'foobar'
|
11
|
+
end
|
12
|
+
end
|
4
13
|
|
5
|
-
describe RestClient::Payload do
|
6
14
|
context "A regular Payload" do
|
7
15
|
it "should use standard enctype as default content-type" do
|
8
|
-
RestClient::Payload::UrlEncoded.new({}).headers['Content-Type'].
|
9
|
-
|
16
|
+
expect(RestClient::Payload::UrlEncoded.new({}).headers['Content-Type']).
|
17
|
+
to eq 'application/x-www-form-urlencoded'
|
10
18
|
end
|
11
19
|
|
12
20
|
it "should form properly encoded params" do
|
13
|
-
RestClient::Payload::UrlEncoded.new({:foo => 'bar'}).to_s.
|
14
|
-
|
15
|
-
["foo=bar&baz=qux", "baz=qux&foo=bar"].
|
21
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => 'bar'}).to_s).
|
22
|
+
to eq "foo=bar"
|
23
|
+
expect(["foo=bar&baz=qux", "baz=qux&foo=bar"]).to include(
|
16
24
|
RestClient::Payload::UrlEncoded.new({:foo => 'bar', :baz => 'qux'}).to_s)
|
17
25
|
end
|
18
26
|
|
19
27
|
it "should escape parameters" do
|
20
|
-
RestClient::Payload::UrlEncoded.new({'foo ' => '
|
21
|
-
|
28
|
+
expect(RestClient::Payload::UrlEncoded.new({'foo + bar' => 'baz'}).to_s).
|
29
|
+
to eq "foo+%2B+bar=baz"
|
22
30
|
end
|
23
31
|
|
24
32
|
it "should properly handle hashes as parameter" do
|
25
|
-
RestClient::Payload::UrlEncoded.new({:foo => {:bar => 'baz'}}).to_s.
|
26
|
-
|
27
|
-
RestClient::Payload::UrlEncoded.new({:foo => {:bar => {:baz => 'qux'}}}).to_s.
|
28
|
-
|
33
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => {:bar => 'baz'}}).to_s).
|
34
|
+
to eq "foo[bar]=baz"
|
35
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => {:bar => {:baz => 'qux'}}}).to_s).
|
36
|
+
to eq "foo[bar][baz]=qux"
|
29
37
|
end
|
30
38
|
|
31
39
|
it "should handle many attributes inside a hash" do
|
32
40
|
parameters = RestClient::Payload::UrlEncoded.new({:foo => {:bar => 'baz', :baz => 'qux'}}).to_s
|
33
|
-
parameters.
|
41
|
+
expect(parameters).to eq 'foo[bar]=baz&foo[baz]=qux'
|
34
42
|
end
|
35
43
|
|
36
|
-
it "should handle attributes inside
|
44
|
+
it "should handle attributes inside an array inside an hash" do
|
37
45
|
parameters = RestClient::Payload::UrlEncoded.new({"foo" => [{"bar" => 'baz'}, {"bar" => 'qux'}]}).to_s
|
38
|
-
parameters.
|
46
|
+
expect(parameters).to eq 'foo[][bar]=baz&foo[][bar]=qux'
|
39
47
|
end
|
40
48
|
|
41
|
-
it "should handle
|
42
|
-
parameters = RestClient::Payload::UrlEncoded.new({"foo" =>
|
43
|
-
parameters.
|
49
|
+
it "should handle arrays inside a hash inside a hash" do
|
50
|
+
parameters = RestClient::Payload::UrlEncoded.new({"foo" => {'even' => [0, 2], 'odd' => [1, 3]}}).to_s
|
51
|
+
expect(parameters).to eq 'foo[even][]=0&foo[even][]=2&foo[odd][]=1&foo[odd][]=3'
|
44
52
|
end
|
45
53
|
|
46
54
|
it "should form properly use symbols as parameters" do
|
47
|
-
RestClient::Payload::UrlEncoded.new({:foo => :bar}).to_s.
|
48
|
-
|
49
|
-
RestClient::Payload::UrlEncoded.new({:foo => {:bar => :baz}}).to_s.
|
50
|
-
|
55
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => :bar}).to_s).
|
56
|
+
to eq "foo=bar"
|
57
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => {:bar => :baz}}).to_s).
|
58
|
+
to eq "foo[bar]=baz"
|
51
59
|
end
|
52
60
|
|
53
61
|
it "should properly handle arrays as repeated parameters" do
|
54
|
-
RestClient::Payload::UrlEncoded.new({:foo => ['bar']}).to_s.
|
55
|
-
|
56
|
-
RestClient::Payload::UrlEncoded.new({:foo => ['bar', 'baz']}).to_s.
|
57
|
-
|
62
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => ['bar']}).to_s).
|
63
|
+
to eq "foo[]=bar"
|
64
|
+
expect(RestClient::Payload::UrlEncoded.new({:foo => ['bar', 'baz']}).to_s).
|
65
|
+
to eq "foo[]=bar&foo[]=baz"
|
58
66
|
end
|
59
67
|
|
60
68
|
it 'should not close if stream already closed' do
|
@@ -67,18 +75,18 @@ describe RestClient::Payload do
|
|
67
75
|
context "A multipart Payload" do
|
68
76
|
it "should use standard enctype as default content-type" do
|
69
77
|
m = RestClient::Payload::Multipart.new({})
|
70
|
-
m.
|
71
|
-
m.headers['Content-Type'].
|
78
|
+
allow(m).to receive(:boundary).and_return(123)
|
79
|
+
expect(m.headers['Content-Type']).to eq 'multipart/form-data; boundary=123'
|
72
80
|
end
|
73
81
|
|
74
82
|
it 'should not error on close if stream already closed' do
|
75
|
-
m = RestClient::Payload::Multipart.new(:file => File.new(
|
83
|
+
m = RestClient::Payload::Multipart.new(:file => File.new(test_image_path))
|
76
84
|
3.times {m.close}
|
77
85
|
end
|
78
86
|
|
79
87
|
it "should form properly separated multipart data" do
|
80
88
|
m = RestClient::Payload::Multipart.new([[:bar, "baz"], [:foo, "bar"]])
|
81
|
-
m.to_s.
|
89
|
+
expect(m.to_s).to eq <<-EOS
|
82
90
|
--#{m.boundary}\r
|
83
91
|
Content-Disposition: form-data; name="bar"\r
|
84
92
|
\r
|
@@ -93,7 +101,7 @@ bar\r
|
|
93
101
|
|
94
102
|
it "should not escape parameters names" do
|
95
103
|
m = RestClient::Payload::Multipart.new([["bar ", "baz"]])
|
96
|
-
m.to_s.
|
104
|
+
expect(m.to_s).to eq <<-EOS
|
97
105
|
--#{m.boundary}\r
|
98
106
|
Content-Disposition: form-data; name="bar "\r
|
99
107
|
\r
|
@@ -103,11 +111,11 @@ baz\r
|
|
103
111
|
end
|
104
112
|
|
105
113
|
it "should form properly separated multipart data" do
|
106
|
-
f = File.new(
|
114
|
+
f = File.new(test_image_path)
|
107
115
|
m = RestClient::Payload::Multipart.new({:foo => f})
|
108
|
-
m.to_s.
|
116
|
+
expect(m.to_s).to eq <<-EOS
|
109
117
|
--#{m.boundary}\r
|
110
|
-
Content-Disposition: form-data; name="foo"; filename="
|
118
|
+
Content-Disposition: form-data; name="foo"; filename="ISS.jpg"\r
|
111
119
|
Content-Type: image/jpeg\r
|
112
120
|
\r
|
113
121
|
#{File.open(f.path, 'rb'){|bin| bin.read}}\r
|
@@ -116,11 +124,11 @@ Content-Type: image/jpeg\r
|
|
116
124
|
end
|
117
125
|
|
118
126
|
it "should ignore the name attribute when it's not set" do
|
119
|
-
f = File.new(
|
127
|
+
f = File.new(test_image_path)
|
120
128
|
m = RestClient::Payload::Multipart.new({nil => f})
|
121
|
-
m.to_s.
|
129
|
+
expect(m.to_s).to eq <<-EOS
|
122
130
|
--#{m.boundary}\r
|
123
|
-
Content-Disposition: form-data; filename="
|
131
|
+
Content-Disposition: form-data; filename="ISS.jpg"\r
|
124
132
|
Content-Type: image/jpeg\r
|
125
133
|
\r
|
126
134
|
#{File.open(f.path, 'rb'){|bin| bin.read}}\r
|
@@ -129,11 +137,11 @@ Content-Type: image/jpeg\r
|
|
129
137
|
end
|
130
138
|
|
131
139
|
it "should detect optional (original) content type and filename" do
|
132
|
-
f = File.new(
|
133
|
-
f.
|
134
|
-
f.
|
140
|
+
f = File.new(test_image_path)
|
141
|
+
expect(f).to receive(:content_type).and_return('text/plain')
|
142
|
+
expect(f).to receive(:original_filename).and_return('foo.txt')
|
135
143
|
m = RestClient::Payload::Multipart.new({:foo => f})
|
136
|
-
m.to_s.
|
144
|
+
expect(m.to_s).to eq <<-EOS
|
137
145
|
--#{m.boundary}\r
|
138
146
|
Content-Disposition: form-data; name="foo"; filename="foo.txt"\r
|
139
147
|
Content-Type: text/plain\r
|
@@ -145,7 +153,7 @@ Content-Type: text/plain\r
|
|
145
153
|
|
146
154
|
it "should handle hash in hash parameters" do
|
147
155
|
m = RestClient::Payload::Multipart.new({:bar => {:baz => "foo"}})
|
148
|
-
m.to_s.
|
156
|
+
expect(m.to_s).to eq <<-EOS
|
149
157
|
--#{m.boundary}\r
|
150
158
|
Content-Disposition: form-data; name="bar[baz]"\r
|
151
159
|
\r
|
@@ -153,11 +161,11 @@ foo\r
|
|
153
161
|
--#{m.boundary}--\r
|
154
162
|
EOS
|
155
163
|
|
156
|
-
f = File.new(
|
164
|
+
f = File.new(test_image_path)
|
157
165
|
f.instance_eval "def content_type; 'text/plain'; end"
|
158
166
|
f.instance_eval "def original_filename; 'foo.txt'; end"
|
159
167
|
m = RestClient::Payload::Multipart.new({:foo => {:bar => f}})
|
160
|
-
m.to_s.
|
168
|
+
expect(m.to_s).to eq <<-EOS
|
161
169
|
--#{m.boundary}\r
|
162
170
|
Content-Disposition: form-data; name="foo[bar]"; filename="foo.txt"\r
|
163
171
|
Content-Type: text/plain\r
|
@@ -167,79 +175,121 @@ Content-Type: text/plain\r
|
|
167
175
|
EOS
|
168
176
|
end
|
169
177
|
|
178
|
+
it 'should correctly format hex boundary' do
|
179
|
+
allow(SecureRandom).to receive(:base64).with(12).and_return('TGs89+ttw/xna6TV')
|
180
|
+
f = File.new(test_image_path)
|
181
|
+
m = RestClient::Payload::Multipart.new({:foo => f})
|
182
|
+
expect(m.boundary).to eq('-' * 4 + 'RubyFormBoundary' + 'TGs89AttwBxna6TV')
|
183
|
+
end
|
184
|
+
|
170
185
|
end
|
171
186
|
|
172
187
|
context "streamed payloads" do
|
173
188
|
it "should properly determine the size of file payloads" do
|
174
|
-
f = File.new(
|
189
|
+
f = File.new(test_image_path)
|
175
190
|
payload = RestClient::Payload.generate(f)
|
176
|
-
payload.size.
|
177
|
-
payload.length.
|
191
|
+
expect(payload.size).to eq 72_463
|
192
|
+
expect(payload.length).to eq 72_463
|
178
193
|
end
|
179
194
|
|
180
195
|
it "should properly determine the size of other kinds of streaming payloads" do
|
181
196
|
s = StringIO.new 'foo'
|
182
197
|
payload = RestClient::Payload.generate(s)
|
183
|
-
payload.size.
|
184
|
-
payload.length.
|
198
|
+
expect(payload.size).to eq 3
|
199
|
+
expect(payload.length).to eq 3
|
185
200
|
|
186
201
|
begin
|
187
202
|
f = Tempfile.new "rest-client"
|
188
203
|
f.write 'foo bar'
|
189
204
|
|
190
205
|
payload = RestClient::Payload.generate(f)
|
191
|
-
payload.size.
|
192
|
-
payload.length.
|
206
|
+
expect(payload.size).to eq 7
|
207
|
+
expect(payload.length).to eq 7
|
193
208
|
ensure
|
194
209
|
f.close
|
195
210
|
end
|
196
211
|
end
|
212
|
+
|
213
|
+
it "should have a closed? method" do
|
214
|
+
f = File.new(test_image_path)
|
215
|
+
payload = RestClient::Payload.generate(f)
|
216
|
+
expect(payload.closed?).to be_falsey
|
217
|
+
payload.close
|
218
|
+
expect(payload.closed?).to be_truthy
|
219
|
+
end
|
197
220
|
end
|
198
221
|
|
199
222
|
context "Payload generation" do
|
200
223
|
it "should recognize standard urlencoded params" do
|
201
|
-
RestClient::Payload.generate({"foo" => 'bar'}).
|
224
|
+
expect(RestClient::Payload.generate({"foo" => 'bar'})).to be_kind_of(RestClient::Payload::UrlEncoded)
|
202
225
|
end
|
203
226
|
|
204
227
|
it "should recognize multipart params" do
|
205
|
-
f = File.new(
|
206
|
-
RestClient::Payload.generate({"foo" => f}).
|
228
|
+
f = File.new(test_image_path)
|
229
|
+
expect(RestClient::Payload.generate({"foo" => f})).to be_kind_of(RestClient::Payload::Multipart)
|
207
230
|
end
|
208
231
|
|
209
232
|
it "should be multipart if forced" do
|
210
|
-
RestClient::Payload.generate({"foo" => "bar", :multipart => true}).
|
233
|
+
expect(RestClient::Payload.generate({"foo" => "bar", :multipart => true})).to be_kind_of(RestClient::Payload::Multipart)
|
211
234
|
end
|
212
235
|
|
236
|
+
it "should handle deeply nested multipart" do
|
237
|
+
f = File.new(test_image_path)
|
238
|
+
params = {foo: RestClient::ParamsArray.new({nested: f})}
|
239
|
+
expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::Multipart)
|
240
|
+
end
|
241
|
+
|
242
|
+
|
213
243
|
it "should return data if no of the above" do
|
214
|
-
RestClient::Payload.generate("data").
|
244
|
+
expect(RestClient::Payload.generate("data")).to be_kind_of(RestClient::Payload::Base)
|
215
245
|
end
|
216
246
|
|
217
247
|
it "should recognize nested multipart payloads in hashes" do
|
218
|
-
f = File.new(
|
219
|
-
RestClient::Payload.generate({"foo" => {"file" => f}}).
|
248
|
+
f = File.new(test_image_path)
|
249
|
+
expect(RestClient::Payload.generate({"foo" => {"file" => f}})).to be_kind_of(RestClient::Payload::Multipart)
|
220
250
|
end
|
221
251
|
|
222
252
|
it "should recognize nested multipart payloads in arrays" do
|
223
|
-
f = File.new(
|
224
|
-
RestClient::Payload.generate({"foo" => [f]}).
|
253
|
+
f = File.new(test_image_path)
|
254
|
+
expect(RestClient::Payload.generate({"foo" => [f]})).to be_kind_of(RestClient::Payload::Multipart)
|
225
255
|
end
|
226
256
|
|
227
257
|
it "should recognize file payloads that can be streamed" do
|
228
|
-
f = File.new(
|
229
|
-
RestClient::Payload.generate(f).
|
258
|
+
f = File.new(test_image_path)
|
259
|
+
expect(RestClient::Payload.generate(f)).to be_kind_of(RestClient::Payload::Streamed)
|
230
260
|
end
|
231
261
|
|
232
262
|
it "should recognize other payloads that can be streamed" do
|
233
|
-
RestClient::Payload.generate(StringIO.new('foo')).
|
263
|
+
expect(RestClient::Payload.generate(StringIO.new('foo'))).to be_kind_of(RestClient::Payload::Streamed)
|
234
264
|
end
|
235
265
|
|
236
266
|
# hashery gem introduces Hash#read convenience method. Existence of #read method used to determine of content is streameable :/
|
237
267
|
it "shouldn't treat hashes as streameable" do
|
238
|
-
RestClient::Payload.generate({"foo" => 'bar'}).
|
268
|
+
expect(RestClient::Payload.generate({"foo" => 'bar'})).to be_kind_of(RestClient::Payload::UrlEncoded)
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should recognize multipart payload wrapped in ParamsArray" do
|
272
|
+
f = File.new(test_image_path)
|
273
|
+
params = RestClient::ParamsArray.new([[:image, f]])
|
274
|
+
expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::Multipart)
|
239
275
|
end
|
240
|
-
end
|
241
276
|
|
242
|
-
|
243
|
-
|
277
|
+
it "should handle non-multipart payload wrapped in ParamsArray" do
|
278
|
+
params = RestClient::ParamsArray.new([[:arg, 'value1'], [:arg, 'value2']])
|
279
|
+
expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::UrlEncoded)
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should pass through Payload::Base and subclasses unchanged" do
|
283
|
+
payloads = [
|
284
|
+
RestClient::Payload::Base.new('foobar'),
|
285
|
+
RestClient::Payload::UrlEncoded.new({:foo => 'bar'}),
|
286
|
+
RestClient::Payload::Streamed.new(File.new(test_image_path)),
|
287
|
+
RestClient::Payload::Multipart.new({myfile: File.new(test_image_path)}),
|
288
|
+
]
|
289
|
+
|
290
|
+
payloads.each do |payload|
|
291
|
+
expect(RestClient::Payload.generate(payload)).to equal(payload)
|
292
|
+
end
|
293
|
+
end
|
244
294
|
end
|
245
295
|
end
|
@@ -1,18 +1,22 @@
|
|
1
|
-
|
1
|
+
require_relative '_lib'
|
2
2
|
|
3
3
|
describe RestClient::RawResponse do
|
4
4
|
before do
|
5
|
-
@tf = double("Tempfile", :read => "the answer is 42", :open => true)
|
5
|
+
@tf = double("Tempfile", :read => "the answer is 42", :open => true, :rewind => true)
|
6
6
|
@net_http_res = double('net http response')
|
7
|
-
@request = double('
|
8
|
-
@response = RestClient::RawResponse.new(@tf, @net_http_res,
|
7
|
+
@request = double('restclient request', :redirection_history => nil)
|
8
|
+
@response = RestClient::RawResponse.new(@tf, @net_http_res, @request)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "behaves like string" do
|
12
|
-
@response.to_s.
|
12
|
+
expect(@response.to_s).to eq 'the answer is 42'
|
13
13
|
end
|
14
14
|
|
15
15
|
it "exposes a Tempfile" do
|
16
|
-
@response.file.
|
16
|
+
expect(@response.file).to eq @tf
|
17
|
+
end
|
18
|
+
|
19
|
+
it "includes AbstractResponse" do
|
20
|
+
expect(RestClient::RawResponse.ancestors).to include(RestClient::AbstractResponse)
|
17
21
|
end
|
18
22
|
end
|
data/spec/unit/request2_spec.rb
CHANGED
@@ -1,13 +1,35 @@
|
|
1
|
-
|
1
|
+
require_relative '_lib'
|
2
2
|
|
3
|
-
describe RestClient::Request do
|
3
|
+
describe RestClient::Request, :include_helpers do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
context 'params for GET requests' do
|
6
|
+
it "manage params for get requests" do
|
7
|
+
stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
|
8
|
+
expect(RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => {:a => :b, 'c' => 'd'}}).body).to eq 'foo'
|
9
|
+
|
10
|
+
stub_request(:get, 'http://some/resource').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
|
11
|
+
expect(RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => :a}).body).to eq 'foo'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'adds GET params when params are present in URL' do
|
15
|
+
stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
|
16
|
+
expect(RestClient::Request.execute(:url => 'http://some/resource?a=b', :method => :get, :headers => {:foo => :bar, :params => {:c => 'd'}}).body).to eq 'foo'
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'encodes nested GET params' do
|
20
|
+
stub_request(:get, 'http://some/resource?a[foo][]=1&a[foo][]=2&a[bar]&b=foo+bar&math=2+%2B+2+%3D%3D+4').with(:headers => {'Accept'=>'*/*',}).to_return(:body => 'foo', :status => 200)
|
21
|
+
expect(RestClient::Request.execute(url: 'http://some/resource', method: :get, headers: {
|
22
|
+
params: {
|
23
|
+
a: {
|
24
|
+
foo: [1,2],
|
25
|
+
bar: nil,
|
26
|
+
},
|
27
|
+
b: 'foo bar',
|
28
|
+
math: '2 + 2 == 4',
|
29
|
+
}
|
30
|
+
}).body).to eq 'foo'
|
31
|
+
end
|
8
32
|
|
9
|
-
stub_request(:get, 'http://some/resource').with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar', 'params' => 'a'}).to_return(:body => 'foo', :status => 200)
|
10
|
-
RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => :a}).body.should eq 'foo'
|
11
33
|
end
|
12
34
|
|
13
35
|
it "can use a block to process response" do
|
@@ -15,18 +37,18 @@ describe RestClient::Request do
|
|
15
37
|
block = proc do |http_response|
|
16
38
|
response_value = http_response.body
|
17
39
|
end
|
18
|
-
stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'
|
40
|
+
stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
|
19
41
|
RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => {:a => :b, 'c' => 'd'}}, :block_response => block)
|
20
|
-
response_value.
|
42
|
+
expect(response_value).to eq "foo"
|
21
43
|
end
|
22
44
|
|
23
45
|
it 'closes payload if not nil' do
|
24
|
-
test_file = File.new(
|
46
|
+
test_file = File.new(test_image_path)
|
25
47
|
|
26
|
-
stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'
|
48
|
+
stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'*/*'}).to_return(:body => 'foo', :status => 200)
|
27
49
|
RestClient::Request.execute(:url => 'http://some/resource', :method => :post, :payload => {:file => test_file})
|
28
50
|
|
29
|
-
test_file.closed
|
51
|
+
expect(test_file.closed?).to be true
|
30
52
|
end
|
31
53
|
|
32
54
|
end
|