savon 2.0.3 → 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.
- data/.gitignore +1 -0
- data/CHANGELOG.md +38 -6
- data/Gemfile +1 -0
- data/lib/savon.rb +3 -3
- data/lib/savon/builder.rb +14 -3
- data/lib/savon/client.rb +22 -9
- data/lib/savon/operation.rb +70 -2
- data/lib/savon/options.rb +26 -20
- data/lib/savon/qualified_message.rb +2 -6
- data/lib/savon/request.rb +52 -79
- data/lib/savon/version.rb +1 -1
- data/savon.gemspec +11 -2
- data/savon.sublime-workspace +494 -0
- data/spec/fixtures/ssl/client_encrypted_key.pem +30 -0
- data/spec/fixtures/ssl/client_encrypted_key_cert.pem +24 -0
- data/spec/integration/support/application.rb +10 -8
- data/spec/savon/client_spec.rb +27 -18
- data/spec/savon/operation_spec.rb +112 -7
- data/spec/savon/options_spec.rb +126 -28
- data/spec/savon/request_spec.rb +404 -84
- data/spec/spec_helper.rb +11 -0
- metadata +25 -6
data/spec/savon/request_spec.rb
CHANGED
@@ -1,144 +1,464 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "integration/support/server"
|
3
3
|
|
4
|
-
describe Savon::
|
4
|
+
describe Savon::WSDLRequest do
|
5
5
|
|
6
|
-
|
6
|
+
let(:globals) { Savon::GlobalOptions.new }
|
7
|
+
let(:http_request) { HTTPI::Request.new }
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
let(:wsdl) { Wasabi::Document.new Fixture.wsdl(:authentication) }
|
11
|
-
let(:no_wsdl) { Wasabi::Document.new }
|
12
|
-
|
13
|
-
before :all do
|
14
|
-
@server = IntegrationServer.run
|
9
|
+
def new_wsdl_request
|
10
|
+
Savon::WSDLRequest.new(globals, http_request)
|
15
11
|
end
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
describe "#build" do
|
14
|
+
it "returns an HTTPI::Request" do
|
15
|
+
wsdl_request = Savon::WSDLRequest.new(globals)
|
16
|
+
expect(wsdl_request.build).to be_an(HTTPI::Request)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "proxy" do
|
20
|
+
it "is set when specified" do
|
21
|
+
globals.proxy("http://proxy.example.com")
|
22
|
+
http_request.expects(:proxy=).with("http://proxy.example.com")
|
23
|
+
|
24
|
+
new_wsdl_request.build
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is not set otherwise" do
|
28
|
+
http_request.expects(:proxy=).never
|
29
|
+
new_wsdl_request.build
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "open timeout" do
|
34
|
+
it "is set when specified" do
|
35
|
+
globals.open_timeout(22)
|
36
|
+
http_request.expects(:open_timeout=).with(22)
|
37
|
+
|
38
|
+
new_wsdl_request.build
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is not set otherwise" do
|
42
|
+
http_request.expects(:open_timeout=).never
|
43
|
+
new_wsdl_request.build
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "read timeout" do
|
48
|
+
it "is set when specified" do
|
49
|
+
globals.read_timeout(33)
|
50
|
+
http_request.expects(:read_timeout=).with(33)
|
51
|
+
|
52
|
+
new_wsdl_request.build
|
53
|
+
end
|
54
|
+
|
55
|
+
it "is not set otherwise" do
|
56
|
+
http_request.expects(:read_timeout=).never
|
57
|
+
new_wsdl_request.build
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "ssl version" do
|
62
|
+
it "is set when specified" do
|
63
|
+
globals.ssl_version(:SSLv3)
|
64
|
+
http_request.auth.ssl.expects(:ssl_version=).with(:SSLv3)
|
65
|
+
|
66
|
+
new_wsdl_request.build
|
67
|
+
end
|
68
|
+
|
69
|
+
it "is not set otherwise" do
|
70
|
+
http_request.auth.ssl.expects(:ssl_version=).never
|
71
|
+
new_wsdl_request.build
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "ssl verify mode" do
|
76
|
+
it "is set when specified" do
|
77
|
+
globals.ssl_verify_mode(:none)
|
78
|
+
http_request.auth.ssl.expects(:verify_mode=).with(:none)
|
20
79
|
|
21
|
-
|
22
|
-
|
23
|
-
response = request.call("<xml/>")
|
80
|
+
new_wsdl_request.build
|
81
|
+
end
|
24
82
|
|
25
|
-
|
26
|
-
|
27
|
-
|
83
|
+
it "is not set otherwise" do
|
84
|
+
http_request.auth.ssl.expects(:verify_mode=).never
|
85
|
+
new_wsdl_request.build
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "ssl cert key file" do
|
90
|
+
it "is set when specified" do
|
91
|
+
cert_key = File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)
|
92
|
+
globals.ssl_cert_key_file(cert_key)
|
93
|
+
http_request.auth.ssl.expects(:cert_key_file=).with(cert_key)
|
94
|
+
|
95
|
+
new_wsdl_request.build
|
96
|
+
end
|
97
|
+
|
98
|
+
it "is not set otherwise" do
|
99
|
+
http_request.auth.ssl.expects(:cert_key_file=).never
|
100
|
+
new_wsdl_request.build
|
101
|
+
end
|
102
|
+
end
|
28
103
|
|
29
|
-
|
104
|
+
describe "ssl cert key password" do
|
105
|
+
it "is set when specified" do
|
106
|
+
the_pass = "secure-password!42"
|
107
|
+
globals.ssl_cert_key_password(the_pass)
|
108
|
+
http_request.auth.ssl.expects(:cert_key_password=).with(the_pass)
|
109
|
+
|
110
|
+
new_wsdl_request.build
|
111
|
+
end
|
112
|
+
|
113
|
+
it "is not set otherwise" do
|
114
|
+
http_request.auth.ssl.expects(:cert_key_password=).never
|
115
|
+
new_wsdl_request.build
|
116
|
+
end
|
30
117
|
end
|
31
118
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
119
|
+
describe "ssl encrypted cert key file" do
|
120
|
+
describe "set with an invalid decrypting password" do
|
121
|
+
it "fails when attempting to use the SSL private key" do
|
122
|
+
pass = "wrong-password"
|
123
|
+
key = File.expand_path("../../fixtures/ssl/client_encrypted_key.pem", __FILE__)
|
124
|
+
cert = File.expand_path("../../fixtures/ssl/client_encrypted_key_cert.pem", __FILE__)
|
125
|
+
|
126
|
+
globals.ssl_cert_file(cert)
|
127
|
+
globals.ssl_cert_key_password(pass)
|
128
|
+
globals.ssl_cert_key_file(key)
|
129
|
+
|
130
|
+
new_wsdl_request.build
|
131
|
+
|
132
|
+
expect { http_request.auth.ssl.cert_key }.to raise_error(OpenSSL::PKey::RSAError)
|
133
|
+
end
|
134
|
+
end
|
37
135
|
|
38
|
-
|
136
|
+
describe "set with a valid decrypting password" do
|
137
|
+
it "handles SSL private keys properly" do
|
138
|
+
pass = "secure-password!42"
|
139
|
+
key = File.expand_path("../../fixtures/ssl/client_encrypted_key.pem", __FILE__)
|
140
|
+
cert = File.expand_path("../../fixtures/ssl/client_encrypted_key_cert.pem", __FILE__)
|
141
|
+
|
142
|
+
globals.ssl_cert_file(cert)
|
143
|
+
globals.ssl_cert_key_password(pass)
|
144
|
+
globals.ssl_cert_key_file(key)
|
145
|
+
|
146
|
+
new_wsdl_request.build
|
147
|
+
|
148
|
+
http_request.auth.ssl.cert_key.to_s.should =~ /BEGIN RSA PRIVATE KEY/
|
149
|
+
end
|
150
|
+
end
|
39
151
|
end
|
40
152
|
|
41
|
-
|
42
|
-
|
43
|
-
|
153
|
+
describe "ssl cert file" do
|
154
|
+
it "is set when specified" do
|
155
|
+
cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
|
156
|
+
globals.ssl_cert_file(cert)
|
157
|
+
http_request.auth.ssl.expects(:cert_file=).with(cert)
|
158
|
+
|
159
|
+
new_wsdl_request.build
|
160
|
+
end
|
161
|
+
|
162
|
+
it "is not set otherwise" do
|
163
|
+
http_request.auth.ssl.expects(:cert_file=).never
|
164
|
+
new_wsdl_request.build
|
165
|
+
end
|
44
166
|
end
|
45
167
|
|
46
|
-
|
47
|
-
|
168
|
+
describe "ssl ca cert file" do
|
169
|
+
it "is set when specified" do
|
170
|
+
ca_cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
|
171
|
+
globals.ssl_ca_cert_file(ca_cert)
|
172
|
+
http_request.auth.ssl.expects(:ca_cert_file=).with(ca_cert)
|
173
|
+
|
174
|
+
new_wsdl_request.build
|
175
|
+
end
|
176
|
+
|
177
|
+
it "is not set otherwise" do
|
178
|
+
http_request.auth.ssl.expects(:ca_cert_file=).never
|
179
|
+
new_wsdl_request.build
|
180
|
+
end
|
48
181
|
end
|
49
182
|
|
50
|
-
|
51
|
-
|
52
|
-
|
183
|
+
describe "basic auth" do
|
184
|
+
it "is set when specified" do
|
185
|
+
globals.basic_auth("luke", "secret")
|
186
|
+
http_request.auth.expects(:basic).with("luke", "secret")
|
187
|
+
|
188
|
+
new_wsdl_request.build
|
189
|
+
end
|
53
190
|
|
54
|
-
|
55
|
-
|
191
|
+
it "is not set otherwise" do
|
192
|
+
http_request.auth.expects(:basic).never
|
193
|
+
new_wsdl_request.build
|
194
|
+
end
|
56
195
|
end
|
57
196
|
|
58
|
-
|
59
|
-
|
197
|
+
describe "digest auth" do
|
198
|
+
it "is set when specified" do
|
199
|
+
globals.digest_auth("lea", "top-secret")
|
200
|
+
http_request.auth.expects(:digest).with("lea", "top-secret")
|
201
|
+
|
202
|
+
new_wsdl_request.build
|
203
|
+
end
|
204
|
+
|
205
|
+
it "is not set otherwise" do
|
206
|
+
http_request.auth.expects(:digest).never
|
207
|
+
new_wsdl_request.build
|
208
|
+
end
|
60
209
|
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
describe Savon::SOAPRequest do
|
215
|
+
|
216
|
+
let(:globals) { Savon::GlobalOptions.new }
|
217
|
+
let(:http_request) { HTTPI::Request.new }
|
61
218
|
|
62
|
-
|
63
|
-
|
64
|
-
|
219
|
+
def new_soap_request
|
220
|
+
Savon::SOAPRequest.new(globals, http_request)
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "#build" do
|
224
|
+
it "returns an HTTPI::Request" do
|
225
|
+
soap_request = Savon::SOAPRequest.new(globals)
|
226
|
+
expect(soap_request.build).to be_an(HTTPI::Request)
|
65
227
|
end
|
66
228
|
|
67
|
-
|
68
|
-
|
69
|
-
|
229
|
+
describe "proxy" do
|
230
|
+
it "is set when specified" do
|
231
|
+
globals.proxy("http://proxy.example.com")
|
232
|
+
http_request.expects(:proxy=).with("http://proxy.example.com")
|
233
|
+
|
234
|
+
new_soap_request.build
|
235
|
+
end
|
236
|
+
|
237
|
+
it "is not set otherwise" do
|
238
|
+
http_request.expects(:proxy=).never
|
239
|
+
new_soap_request.build
|
240
|
+
end
|
70
241
|
end
|
71
242
|
|
72
|
-
|
73
|
-
|
74
|
-
|
243
|
+
describe "cookies" do
|
244
|
+
it "sets the given cookies" do
|
245
|
+
cookies = [HTTPI::Cookie.new("some-cookie=choc-chip; Path=/; HttpOnly")]
|
246
|
+
|
247
|
+
http_request.expects(:set_cookies).with(cookies)
|
248
|
+
new_soap_request.build(:cookies => cookies)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "does not set the cookies if there are none" do
|
252
|
+
http_request.expects(:set_cookies).never
|
253
|
+
new_soap_request.build
|
254
|
+
end
|
75
255
|
end
|
76
256
|
|
77
|
-
|
78
|
-
|
257
|
+
describe "open timeout" do
|
258
|
+
it "is set when specified" do
|
259
|
+
globals.open_timeout(22)
|
260
|
+
http_request.expects(:open_timeout=).with(22)
|
261
|
+
|
262
|
+
new_soap_request.build
|
263
|
+
end
|
264
|
+
|
265
|
+
it "is not set otherwise" do
|
266
|
+
http_request.expects(:open_timeout=).never
|
267
|
+
new_soap_request.build
|
268
|
+
end
|
79
269
|
end
|
80
270
|
|
81
|
-
|
82
|
-
|
83
|
-
|
271
|
+
describe "read timeout" do
|
272
|
+
it "is set when specified" do
|
273
|
+
globals.read_timeout(33)
|
274
|
+
http_request.expects(:read_timeout=).with(33)
|
275
|
+
|
276
|
+
new_soap_request.build
|
277
|
+
end
|
278
|
+
|
279
|
+
it "is not set otherwise" do
|
280
|
+
http_request.expects(:read_timeout=).never
|
281
|
+
new_soap_request.build
|
282
|
+
end
|
84
283
|
end
|
85
284
|
|
86
|
-
|
87
|
-
|
88
|
-
|
285
|
+
describe "headers" do
|
286
|
+
it "are set when specified" do
|
287
|
+
globals.headers("X-Token" => "secret")
|
288
|
+
configured_http_request = new_soap_request.build
|
289
|
+
|
290
|
+
expect(configured_http_request.headers["X-Token"]).to eq("secret")
|
291
|
+
end
|
292
|
+
|
293
|
+
it "are not set otherwise" do
|
294
|
+
configured_http_request = new_soap_request.build
|
295
|
+
expect(configured_http_request.headers).to_not include("X-Token")
|
296
|
+
end
|
89
297
|
end
|
90
298
|
|
91
|
-
|
92
|
-
|
299
|
+
describe "SOAPAction header" do
|
300
|
+
it "is set and wrapped in parenthesis" do
|
301
|
+
configured_http_request = new_soap_request.build(:soap_action => "findUser")
|
302
|
+
soap_action = configured_http_request.headers["SOAPAction"]
|
303
|
+
|
304
|
+
expect(soap_action).to eq(%("findUser"))
|
305
|
+
end
|
306
|
+
|
307
|
+
it "is not set when it's explicitely set to nil" do
|
308
|
+
configured_http_request = new_soap_request.build(:soap_action => nil)
|
309
|
+
expect(configured_http_request.headers).to_not include("SOAPAction")
|
310
|
+
end
|
311
|
+
|
312
|
+
it "is not set when there is already a SOAPAction value" do
|
313
|
+
globals.headers("SOAPAction" => %("authenticate"))
|
314
|
+
configured_http_request = new_soap_request.build(:soap_action => "findUser")
|
315
|
+
soap_action = configured_http_request.headers["SOAPAction"]
|
316
|
+
|
317
|
+
expect(soap_action).to eq(%("authenticate"))
|
318
|
+
end
|
93
319
|
end
|
94
320
|
|
95
|
-
|
96
|
-
|
97
|
-
|
321
|
+
describe "Content-Type header" do
|
322
|
+
it "defaults to SOAP 1.1 and UTF-8" do
|
323
|
+
configured_http_request = new_soap_request.build
|
324
|
+
content_type = configured_http_request.headers["Content-Type"]
|
325
|
+
|
326
|
+
expect(content_type).to eq("text/xml;charset=UTF-8")
|
327
|
+
end
|
328
|
+
|
329
|
+
it "can be changed to SOAP 1.2 and any other encoding" do
|
330
|
+
globals.soap_version(2)
|
331
|
+
globals.encoding("ISO-8859-1")
|
332
|
+
|
333
|
+
configured_http_request = new_soap_request.build
|
334
|
+
content_type = configured_http_request.headers["Content-Type"]
|
335
|
+
|
336
|
+
expect(content_type).to eq("application/soap+xml;charset=ISO-8859-1")
|
337
|
+
end
|
338
|
+
|
339
|
+
it "is not set when there is already a Content-Type value" do
|
340
|
+
globals.headers("Content-Type" => "application/awesomeness;charset=UTF-3000")
|
341
|
+
configured_http_request = new_soap_request.build(:soap_action => "findUser")
|
342
|
+
content_type = configured_http_request.headers["Content-Type"]
|
343
|
+
|
344
|
+
expect(content_type).to eq("application/awesomeness;charset=UTF-3000")
|
345
|
+
end
|
98
346
|
end
|
99
347
|
|
100
|
-
|
101
|
-
|
102
|
-
|
348
|
+
describe "ssl version" do
|
349
|
+
it "is set when specified" do
|
350
|
+
globals.ssl_version(:SSLv3)
|
351
|
+
http_request.auth.ssl.expects(:ssl_version=).with(:SSLv3)
|
352
|
+
|
353
|
+
new_soap_request.build
|
354
|
+
end
|
103
355
|
|
104
|
-
|
356
|
+
it "is not set otherwise" do
|
357
|
+
http_request.auth.ssl.expects(:ssl_version=).never
|
358
|
+
new_soap_request.build
|
359
|
+
end
|
105
360
|
end
|
106
361
|
|
107
|
-
|
108
|
-
|
109
|
-
|
362
|
+
describe "ssl verify mode" do
|
363
|
+
it "is set when specified" do
|
364
|
+
globals.ssl_verify_mode(:none)
|
365
|
+
http_request.auth.ssl.expects(:verify_mode=).with(:none)
|
366
|
+
|
367
|
+
new_soap_request.build
|
368
|
+
end
|
369
|
+
|
370
|
+
it "is not set otherwise" do
|
371
|
+
http_request.auth.ssl.expects(:verify_mode=).never
|
372
|
+
new_soap_request.build
|
373
|
+
end
|
110
374
|
end
|
111
375
|
|
112
|
-
|
113
|
-
|
114
|
-
|
376
|
+
describe "ssl cert key file" do
|
377
|
+
it "is set when specified" do
|
378
|
+
cert_key = File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)
|
379
|
+
globals.ssl_cert_key_file(cert_key)
|
380
|
+
http_request.auth.ssl.expects(:cert_key_file=).with(cert_key)
|
115
381
|
|
116
|
-
|
382
|
+
new_soap_request.build
|
383
|
+
end
|
384
|
+
|
385
|
+
it "is not set otherwise" do
|
386
|
+
http_request.auth.ssl.expects(:cert_key_file=).never
|
387
|
+
new_soap_request.build
|
388
|
+
end
|
117
389
|
end
|
118
390
|
|
119
|
-
|
120
|
-
|
121
|
-
|
391
|
+
describe "ssl cert key password" do
|
392
|
+
it "is set when specified" do
|
393
|
+
the_pass = "secure-password!42"
|
394
|
+
globals.ssl_cert_key_password(the_pass)
|
395
|
+
http_request.auth.ssl.expects(:cert_key_password=).with(the_pass)
|
396
|
+
|
397
|
+
new_soap_request.build
|
398
|
+
end
|
122
399
|
|
123
|
-
|
400
|
+
it "is not set otherwise" do
|
401
|
+
http_request.auth.ssl.expects(:cert_key_password=).never
|
402
|
+
new_soap_request.build
|
403
|
+
end
|
124
404
|
end
|
125
405
|
|
126
|
-
|
127
|
-
|
128
|
-
|
406
|
+
describe "ssl cert file" do
|
407
|
+
it "is set when specified" do
|
408
|
+
cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
|
409
|
+
globals.ssl_cert_file(cert)
|
410
|
+
http_request.auth.ssl.expects(:cert_file=).with(cert)
|
411
|
+
|
412
|
+
new_soap_request.build
|
413
|
+
end
|
414
|
+
|
415
|
+
it "is not set otherwise" do
|
416
|
+
http_request.auth.ssl.expects(:cert_file=).never
|
417
|
+
new_soap_request.build
|
418
|
+
end
|
129
419
|
end
|
130
420
|
|
131
|
-
|
132
|
-
|
421
|
+
describe "ssl ca cert file" do
|
422
|
+
it "is set when specified" do
|
423
|
+
ca_cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
|
424
|
+
globals.ssl_ca_cert_file(ca_cert)
|
425
|
+
http_request.auth.ssl.expects(:ca_cert_file=).with(ca_cert)
|
426
|
+
|
427
|
+
new_soap_request.build
|
428
|
+
end
|
429
|
+
|
430
|
+
it "is not set otherwise" do
|
431
|
+
http_request.auth.ssl.expects(:ca_cert_file=).never
|
432
|
+
new_soap_request.build
|
433
|
+
end
|
133
434
|
end
|
134
435
|
|
135
|
-
|
136
|
-
|
137
|
-
|
436
|
+
describe "basic auth" do
|
437
|
+
it "is set when specified" do
|
438
|
+
globals.basic_auth("luke", "secret")
|
439
|
+
http_request.auth.expects(:basic).with("luke", "secret")
|
440
|
+
|
441
|
+
new_soap_request.build
|
442
|
+
end
|
443
|
+
|
444
|
+
it "is not set otherwise" do
|
445
|
+
http_request.auth.expects(:basic).never
|
446
|
+
new_soap_request.build
|
447
|
+
end
|
138
448
|
end
|
139
449
|
|
140
|
-
|
141
|
-
|
450
|
+
describe "digest auth" do
|
451
|
+
it "is set when specified" do
|
452
|
+
globals.digest_auth("lea", "top-secret")
|
453
|
+
http_request.auth.expects(:digest).with("lea", "top-secret")
|
454
|
+
|
455
|
+
new_soap_request.build
|
456
|
+
end
|
457
|
+
|
458
|
+
it "is not set otherwise" do
|
459
|
+
http_request.auth.expects(:digest).never
|
460
|
+
new_soap_request.build
|
461
|
+
end
|
142
462
|
end
|
143
463
|
end
|
144
464
|
|