savon 2.2.0 → 2.12.1
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 +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +20 -9
- data/CHANGELOG.md +157 -10
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +10 -2
- data/README.md +38 -13
- data/donate.png +0 -0
- data/lib/savon/builder.rb +81 -15
- data/lib/savon/client.rb +6 -2
- data/lib/savon/core_ext/string.rb +0 -1
- data/lib/savon/header.rb +68 -17
- data/lib/savon/log_message.rb +7 -3
- data/lib/savon/message.rb +6 -7
- data/lib/savon/mock/expectation.rb +12 -2
- data/lib/savon/model.rb +4 -0
- data/lib/savon/operation.rb +45 -38
- data/lib/savon/options.rb +149 -22
- data/lib/savon/qualified_message.rb +31 -25
- data/lib/savon/request.rb +24 -4
- data/lib/savon/request_logger.rb +48 -0
- data/lib/savon/response.rb +35 -18
- data/lib/savon/soap_fault.rb +11 -11
- data/lib/savon/version.rb +1 -3
- data/savon.gemspec +12 -11
- data/spec/fixtures/response/empty_soap_fault.xml +13 -0
- data/spec/fixtures/response/f5.xml +39 -0
- data/spec/fixtures/response/no_body.xml +1 -0
- data/spec/fixtures/response/soap_fault_funky.xml +8 -0
- data/spec/fixtures/wsdl/brand.xml +624 -0
- data/spec/fixtures/wsdl/elements_in_types.xml +43 -0
- data/spec/fixtures/wsdl/no_message_tag.xml +1267 -0
- data/spec/fixtures/wsdl/vies.xml +176 -0
- data/spec/integration/centra_spec.rb +67 -0
- data/spec/integration/email_example_spec.rb +1 -1
- data/spec/integration/random_quote_spec.rb +23 -0
- data/spec/integration/stockquote_example_spec.rb +7 -1
- data/spec/integration/support/application.rb +1 -1
- data/spec/integration/zipcode_example_spec.rb +1 -1
- data/spec/savon/builder_spec.rb +50 -0
- data/spec/savon/client_spec.rb +78 -0
- data/spec/savon/core_ext/string_spec.rb +9 -9
- data/spec/savon/features/message_tag_spec.rb +5 -0
- data/spec/savon/http_error_spec.rb +2 -2
- data/spec/savon/log_message_spec.rb +18 -1
- data/spec/savon/message_spec.rb +70 -0
- data/spec/savon/mock_spec.rb +31 -0
- data/spec/savon/model_spec.rb +28 -0
- data/spec/savon/operation_spec.rb +69 -3
- data/spec/savon/options_spec.rb +515 -87
- data/spec/savon/qualified_message_spec.rb +101 -0
- data/spec/savon/request_logger_spec.rb +37 -0
- data/spec/savon/request_spec.rb +85 -10
- data/spec/savon/response_spec.rb +118 -27
- data/spec/savon/soap_fault_spec.rb +25 -5
- data/spec/savon/softlayer_spec.rb +27 -0
- data/spec/spec_helper.rb +5 -2
- data/spec/support/adapters.rb +48 -0
- data/spec/support/integration.rb +1 -1
- metadata +76 -93
@@ -0,0 +1,101 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Savon
|
4
|
+
describe QualifiedMessage, "#to_hash" do
|
5
|
+
|
6
|
+
context "if a key ends with !" do
|
7
|
+
let(:used_namespaces) { {} }
|
8
|
+
let(:key_converter) { :camelcase }
|
9
|
+
let(:types) { {} }
|
10
|
+
|
11
|
+
it "restores the ! in a key" do
|
12
|
+
message = described_class.new(types, used_namespaces, key_converter)
|
13
|
+
resulting_hash = message.to_hash({:Metal! => "<Nice/>"}, ["Rock"])
|
14
|
+
|
15
|
+
expect(resulting_hash).to eq({ :Metal! => "<Nice/>" })
|
16
|
+
end
|
17
|
+
|
18
|
+
it "properly handles special keys when namespaces are present" do
|
19
|
+
used_namespaces = {
|
20
|
+
%w(tns Foo) => 'ns',
|
21
|
+
%w(tns Foo Bar) => 'ns'
|
22
|
+
}
|
23
|
+
|
24
|
+
hash = {
|
25
|
+
:foo => {
|
26
|
+
:bar => {
|
27
|
+
:zing => 'pow'
|
28
|
+
},
|
29
|
+
:cash => {
|
30
|
+
:@attr1 => 'val1',
|
31
|
+
:content! => 'Chunky Bacon'
|
32
|
+
},
|
33
|
+
:attributes! => {
|
34
|
+
:bar => { :attr2 => 'val2' },
|
35
|
+
},
|
36
|
+
:"self_closing/" => '',
|
37
|
+
:order! => [:cash, :bar, :"self_closing/"]
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
good_result = {
|
42
|
+
"ns:Foo" => {
|
43
|
+
'ns:Bar' => { :zing => "pow" },
|
44
|
+
:cash => {
|
45
|
+
:@attr1 => "val1",
|
46
|
+
:content! => "Chunky Bacon"
|
47
|
+
},
|
48
|
+
:attributes! => {
|
49
|
+
'ns:Bar' => { :attr2 => 'val2' }
|
50
|
+
},
|
51
|
+
:"self_closing/" => '',
|
52
|
+
:order! => [:cash, 'ns:Bar', :"self_closing/"]
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
good_xml = %(<ns:Foo><Cash attr1="val1">Chunky Bacon</Cash><ns:Bar attr2="val2"><Zing>pow</Zing></ns:Bar><SelfClosing/></ns:Foo>)
|
57
|
+
|
58
|
+
message = described_class.new(types, used_namespaces, key_converter)
|
59
|
+
resulting_hash = message.to_hash(hash, ['tns'])
|
60
|
+
xml = Gyoku.xml(resulting_hash, key_converter: key_converter)
|
61
|
+
|
62
|
+
expect(resulting_hash).to eq good_result
|
63
|
+
expect(xml).to eq good_xml
|
64
|
+
end
|
65
|
+
|
66
|
+
it "properly handles boolean false" do
|
67
|
+
used_namespaces = {
|
68
|
+
%w(tns Foo) => 'ns'
|
69
|
+
}
|
70
|
+
|
71
|
+
hash = {
|
72
|
+
:foo => {
|
73
|
+
:falsey => {
|
74
|
+
:@attr1 => false,
|
75
|
+
:content! => false
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
good_result = {
|
81
|
+
"ns:Foo" => {
|
82
|
+
:falsey => {
|
83
|
+
:@attr1 => false,
|
84
|
+
:content! => false
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
good_xml = %(<ns:Foo><Falsey attr1="false">false</Falsey></ns:Foo>)
|
90
|
+
|
91
|
+
message = described_class.new(types, used_namespaces, key_converter)
|
92
|
+
resulting_hash = message.to_hash(hash, ['tns'])
|
93
|
+
xml = Gyoku.xml(resulting_hash, key_converter: key_converter)
|
94
|
+
|
95
|
+
expect(resulting_hash).to eq good_result
|
96
|
+
expect(xml).to eq good_xml
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Savon::RequestLogger do
|
4
|
+
|
5
|
+
subject { described_class.new(globals) }
|
6
|
+
let(:globals) { Savon::GlobalOptions.new(:log => true, :pretty_print_xml => true) }
|
7
|
+
let(:request) {
|
8
|
+
stub('Request',
|
9
|
+
:url => 'http://example.com',
|
10
|
+
:headers => [],
|
11
|
+
:body => '<TestRequest />'
|
12
|
+
)
|
13
|
+
}
|
14
|
+
|
15
|
+
let(:response) {
|
16
|
+
stub('Response',
|
17
|
+
:code => 200,
|
18
|
+
:body => '<TestResponse />'
|
19
|
+
)
|
20
|
+
}
|
21
|
+
|
22
|
+
before(:each) {
|
23
|
+
globals[:logger].level = Logger::DEBUG
|
24
|
+
}
|
25
|
+
|
26
|
+
describe '#log_request / #log_response' do
|
27
|
+
it 'does not prepare log messages when no logging is needed' do
|
28
|
+
begin
|
29
|
+
globals[:logger].level = Logger::FATAL
|
30
|
+
|
31
|
+
Savon::LogMessage.expects(:new).never
|
32
|
+
subject.log(request) { response }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/spec/savon/request_spec.rb
CHANGED
@@ -5,6 +5,7 @@ describe Savon::WSDLRequest do
|
|
5
5
|
|
6
6
|
let(:globals) { Savon::GlobalOptions.new }
|
7
7
|
let(:http_request) { HTTPI::Request.new }
|
8
|
+
let(:ciphers) { OpenSSL::Cipher.ciphers }
|
8
9
|
|
9
10
|
def new_wsdl_request
|
10
11
|
Savon::WSDLRequest.new(globals, http_request)
|
@@ -16,6 +17,20 @@ describe Savon::WSDLRequest do
|
|
16
17
|
expect(wsdl_request.build).to be_an(HTTPI::Request)
|
17
18
|
end
|
18
19
|
|
20
|
+
describe "headers" do
|
21
|
+
it "are set when specified" do
|
22
|
+
globals.headers("Proxy-Authorization" => "Basic auth")
|
23
|
+
configured_http_request = new_wsdl_request.build
|
24
|
+
|
25
|
+
expect(configured_http_request.headers["Proxy-Authorization"]).to eq("Basic auth")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "are not set otherwise" do
|
29
|
+
configured_http_request = new_wsdl_request.build
|
30
|
+
expect(configured_http_request.headers).to_not include("Proxy-Authorization")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
19
34
|
describe "proxy" do
|
20
35
|
it "is set when specified" do
|
21
36
|
globals.proxy("http://proxy.example.com")
|
@@ -60,8 +75,8 @@ describe Savon::WSDLRequest do
|
|
60
75
|
|
61
76
|
describe "ssl version" do
|
62
77
|
it "is set when specified" do
|
63
|
-
globals.ssl_version(:
|
64
|
-
http_request.auth.ssl.expects(:ssl_version=).with(:
|
78
|
+
globals.ssl_version(:TLSv1)
|
79
|
+
http_request.auth.ssl.expects(:ssl_version=).with(:TLSv1)
|
65
80
|
|
66
81
|
new_wsdl_request.build
|
67
82
|
end
|
@@ -74,8 +89,8 @@ describe Savon::WSDLRequest do
|
|
74
89
|
|
75
90
|
describe "ssl verify mode" do
|
76
91
|
it "is set when specified" do
|
77
|
-
globals.ssl_verify_mode(:
|
78
|
-
http_request.auth.ssl.expects(:verify_mode=).with(:
|
92
|
+
globals.ssl_verify_mode(:peer)
|
93
|
+
http_request.auth.ssl.expects(:verify_mode=).with(:peer)
|
79
94
|
|
80
95
|
new_wsdl_request.build
|
81
96
|
end
|
@@ -86,6 +101,20 @@ describe Savon::WSDLRequest do
|
|
86
101
|
end
|
87
102
|
end
|
88
103
|
|
104
|
+
describe "ssl ciphers" do
|
105
|
+
it "is set when specified" do
|
106
|
+
globals.ssl_ciphers(ciphers)
|
107
|
+
http_request.auth.ssl.expects(:ciphers=).with(ciphers)
|
108
|
+
|
109
|
+
new_wsdl_request.build
|
110
|
+
end
|
111
|
+
|
112
|
+
it "is not set otherwise" do
|
113
|
+
http_request.auth.ssl.expects(:ciphers=).never
|
114
|
+
new_wsdl_request.build
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
89
118
|
describe "ssl cert key file" do
|
90
119
|
it "is set when specified" do
|
91
120
|
cert_key = File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)
|
@@ -129,12 +158,15 @@ describe Savon::WSDLRequest do
|
|
129
158
|
|
130
159
|
new_wsdl_request.build
|
131
160
|
|
132
|
-
expect { http_request.auth.ssl.cert_key }.to raise_error
|
161
|
+
expect { http_request.auth.ssl.cert_key }.to raise_error
|
133
162
|
end
|
134
163
|
end
|
135
164
|
|
136
165
|
describe "set with a valid decrypting password" do
|
137
166
|
it "handles SSL private keys properly" do
|
167
|
+
if RUBY_ENGINE == 'jruby'
|
168
|
+
pending("find out why this fails with a null pointer exception on jruby")
|
169
|
+
end
|
138
170
|
pass = "secure-password!42"
|
139
171
|
key = File.expand_path("../../fixtures/ssl/client_encrypted_key.pem", __FILE__)
|
140
172
|
cert = File.expand_path("../../fixtures/ssl/client_encrypted_key_cert.pem", __FILE__)
|
@@ -145,7 +177,7 @@ describe Savon::WSDLRequest do
|
|
145
177
|
|
146
178
|
new_wsdl_request.build
|
147
179
|
|
148
|
-
http_request.auth.ssl.cert_key.to_s.
|
180
|
+
expect(http_request.auth.ssl.cert_key.to_s).to match(/BEGIN RSA PRIVATE KEY/)
|
149
181
|
end
|
150
182
|
end
|
151
183
|
end
|
@@ -207,6 +239,20 @@ describe Savon::WSDLRequest do
|
|
207
239
|
new_wsdl_request.build
|
208
240
|
end
|
209
241
|
end
|
242
|
+
|
243
|
+
describe "ntlm auth" do
|
244
|
+
it "is set when specified" do
|
245
|
+
globals.ntlm("han", "super-secret")
|
246
|
+
http_request.auth.expects(:ntlm).with("han", "super-secret")
|
247
|
+
|
248
|
+
new_wsdl_request.build
|
249
|
+
end
|
250
|
+
|
251
|
+
it "is not set otherwise" do
|
252
|
+
http_request.auth.expects(:ntlm).never
|
253
|
+
new_wsdl_request.build
|
254
|
+
end
|
255
|
+
end
|
210
256
|
end
|
211
257
|
|
212
258
|
end
|
@@ -215,6 +261,7 @@ describe Savon::SOAPRequest do
|
|
215
261
|
|
216
262
|
let(:globals) { Savon::GlobalOptions.new }
|
217
263
|
let(:http_request) { HTTPI::Request.new }
|
264
|
+
let(:ciphers) { OpenSSL::Cipher.ciphers }
|
218
265
|
|
219
266
|
def new_soap_request
|
220
267
|
Savon::SOAPRequest.new(globals, http_request)
|
@@ -347,8 +394,8 @@ describe Savon::SOAPRequest do
|
|
347
394
|
|
348
395
|
describe "ssl version" do
|
349
396
|
it "is set when specified" do
|
350
|
-
globals.ssl_version(:
|
351
|
-
http_request.auth.ssl.expects(:ssl_version=).with(:
|
397
|
+
globals.ssl_version(:TLSv1)
|
398
|
+
http_request.auth.ssl.expects(:ssl_version=).with(:TLSv1)
|
352
399
|
|
353
400
|
new_soap_request.build
|
354
401
|
end
|
@@ -361,8 +408,8 @@ describe Savon::SOAPRequest do
|
|
361
408
|
|
362
409
|
describe "ssl verify mode" do
|
363
410
|
it "is set when specified" do
|
364
|
-
globals.ssl_verify_mode(:
|
365
|
-
http_request.auth.ssl.expects(:verify_mode=).with(:
|
411
|
+
globals.ssl_verify_mode(:peer)
|
412
|
+
http_request.auth.ssl.expects(:verify_mode=).with(:peer)
|
366
413
|
|
367
414
|
new_soap_request.build
|
368
415
|
end
|
@@ -373,6 +420,20 @@ describe Savon::SOAPRequest do
|
|
373
420
|
end
|
374
421
|
end
|
375
422
|
|
423
|
+
describe "ssl ciphers" do
|
424
|
+
it "is set when specified" do
|
425
|
+
globals.ssl_ciphers(ciphers)
|
426
|
+
http_request.auth.ssl.expects(:ciphers=).with(ciphers)
|
427
|
+
|
428
|
+
new_soap_request.build
|
429
|
+
end
|
430
|
+
|
431
|
+
it "is not set otherwise" do
|
432
|
+
http_request.auth.ssl.expects(:ciphers=).never
|
433
|
+
new_soap_request.build
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
376
437
|
describe "ssl cert key file" do
|
377
438
|
it "is set when specified" do
|
378
439
|
cert_key = File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)
|
@@ -460,6 +521,20 @@ describe Savon::SOAPRequest do
|
|
460
521
|
new_soap_request.build
|
461
522
|
end
|
462
523
|
end
|
524
|
+
|
525
|
+
describe "ntlm auth" do
|
526
|
+
it "is set when specified" do
|
527
|
+
globals.ntlm("han", "super-secret")
|
528
|
+
http_request.auth.expects(:ntlm).with("han", "super-secret")
|
529
|
+
|
530
|
+
new_soap_request.build
|
531
|
+
end
|
532
|
+
|
533
|
+
it "is not set otherwise" do
|
534
|
+
http_request.auth.expects(:ntlm).never
|
535
|
+
new_soap_request.build
|
536
|
+
end
|
537
|
+
end
|
463
538
|
end
|
464
539
|
|
465
540
|
end
|
data/spec/savon/response_spec.rb
CHANGED
@@ -7,16 +7,16 @@ describe Savon::Response do
|
|
7
7
|
|
8
8
|
describe ".new" do
|
9
9
|
it "should raise a Savon::Fault in case of a SOAP fault" do
|
10
|
-
|
10
|
+
expect { soap_fault_response }.to raise_error(Savon::SOAPFault)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should not raise a Savon::Fault in case the default is turned off" do
|
14
14
|
globals[:raise_errors] = false
|
15
|
-
|
15
|
+
expect { soap_fault_response }.not_to raise_error
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should raise a Savon::HTTP::Error in case of an HTTP error" do
|
19
|
-
|
19
|
+
expect { soap_response :code => 500 }.to raise_error(Savon::HTTPError)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should not raise a Savon::HTTP::Error in case the default is turned off" do
|
@@ -29,15 +29,15 @@ describe Savon::Response do
|
|
29
29
|
before { globals[:raise_errors] = false }
|
30
30
|
|
31
31
|
it "should return true if the request was successful" do
|
32
|
-
soap_response.
|
32
|
+
expect(soap_response).to be_a_success
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should return false if there was a SOAP fault" do
|
36
|
-
soap_fault_response.
|
36
|
+
expect(soap_fault_response).not_to be_a_success
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should return false if there was an HTTP error" do
|
40
|
-
http_error_response.
|
40
|
+
expect(http_error_response).not_to be_a_success
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -45,11 +45,23 @@ describe Savon::Response do
|
|
45
45
|
before { globals[:raise_errors] = false }
|
46
46
|
|
47
47
|
it "should not return true in case the response seems to be ok" do
|
48
|
-
soap_response.soap_fault
|
48
|
+
expect(soap_response.soap_fault?).to be_falsey
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should return true in case of a SOAP fault" do
|
52
|
-
soap_fault_response.soap_fault
|
52
|
+
expect(soap_fault_response.soap_fault?).to be_truthy
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#soap_fault" do
|
57
|
+
before { globals[:raise_errors] = false }
|
58
|
+
|
59
|
+
it "should return nil in case the response seems to be ok" do
|
60
|
+
expect(soap_response.soap_fault).to be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return a SOAPFault in case of a SOAP fault" do
|
64
|
+
expect(soap_fault_response.soap_fault).to be_a(Savon::SOAPFault)
|
53
65
|
end
|
54
66
|
end
|
55
67
|
|
@@ -57,44 +69,108 @@ describe Savon::Response do
|
|
57
69
|
before { globals[:raise_errors] = false }
|
58
70
|
|
59
71
|
it "should not return true in case the response seems to be ok" do
|
60
|
-
soap_response.http_error
|
72
|
+
expect(soap_response.http_error?).not_to be_truthy
|
61
73
|
end
|
62
74
|
|
63
75
|
it "should return true in case of an HTTP error" do
|
64
|
-
soap_response(:code => 500).http_error
|
76
|
+
expect(soap_response(:code => 500).http_error?).to be_truthy
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#http_error" do
|
81
|
+
before { globals[:raise_errors] = false }
|
82
|
+
|
83
|
+
it "should return nil in case the response seems to be ok" do
|
84
|
+
expect(soap_response.http_error).to be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return a HTTPError in case of an HTTP error" do
|
88
|
+
expect(soap_response(:code => 500).http_error).to be_a(Savon::HTTPError)
|
65
89
|
end
|
66
90
|
end
|
67
91
|
|
68
92
|
describe "#header" do
|
69
93
|
it "should return the SOAP response header as a Hash" do
|
70
94
|
response = soap_response :body => Fixture.response(:header)
|
71
|
-
response.header.
|
95
|
+
expect(response.header).to include(:session_number => "ABCD1234")
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'respects the global :strip_namespaces option' do
|
99
|
+
globals[:strip_namespaces] = false
|
100
|
+
|
101
|
+
response_with_header = soap_response(:body => Fixture.response(:header))
|
102
|
+
header = response_with_header.header
|
103
|
+
|
104
|
+
expect(header).to be_a(Hash)
|
105
|
+
|
106
|
+
# notice: :session_number is a snake_case Symbol without namespaces,
|
107
|
+
# but the Envelope and Header elements are qualified.
|
108
|
+
expect(header.keys).to include(:session_number)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'respects the global :convert_response_tags_to option' do
|
112
|
+
globals[:convert_response_tags_to] = lambda { |key| key.upcase }
|
113
|
+
|
114
|
+
response_with_header = soap_response(:body => Fixture.response(:header))
|
115
|
+
header = response_with_header.header
|
116
|
+
|
117
|
+
expect(header).to be_a(Hash)
|
118
|
+
expect(header.keys).to include('SESSIONNUMBER')
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'respects the global :convert_attributes_to option' do
|
122
|
+
globals[:convert_attributes_to] = lambda { |k,v| [] }
|
123
|
+
|
124
|
+
response_with_header = soap_response(:body => Fixture.response(:header))
|
125
|
+
header = response_with_header.header
|
126
|
+
|
127
|
+
expect(header).to be_a(Hash)
|
128
|
+
expect(header.keys).to include(:session_number)
|
72
129
|
end
|
73
130
|
|
74
131
|
it "should throw an exception when the response header isn't parsable" do
|
75
|
-
|
132
|
+
expect { invalid_soap_response.header }.to raise_error Savon::InvalidResponseError
|
76
133
|
end
|
77
134
|
end
|
78
135
|
|
79
136
|
%w(body to_hash).each do |method|
|
80
137
|
describe "##{method}" do
|
81
138
|
it "should return the SOAP response body as a Hash" do
|
82
|
-
soap_response.send(method)[:authenticate_response][:return].
|
139
|
+
expect(soap_response.send(method)[:authenticate_response][:return]).to eq(
|
83
140
|
Fixture.response_hash(:authentication)[:authenticate_response][:return]
|
141
|
+
)
|
84
142
|
end
|
85
143
|
|
86
144
|
it "should return a Hash for a SOAP multiRef response" do
|
87
145
|
hash = soap_response(:body => Fixture.response(:multi_ref)).send(method)
|
88
146
|
|
89
|
-
hash[:list_response].
|
90
|
-
hash[:multi_ref].
|
147
|
+
expect(hash[:list_response]).to be_a(Hash)
|
148
|
+
expect(hash[:multi_ref]).to be_an(Array)
|
91
149
|
end
|
92
150
|
|
93
151
|
it "should add existing namespaced elements as an array" do
|
94
152
|
hash = soap_response(:body => Fixture.response(:list)).send(method)
|
95
153
|
|
96
|
-
hash[:multi_namespaced_entry_response][:history].
|
97
|
-
hash[:multi_namespaced_entry_response][:history][:case].
|
154
|
+
expect(hash[:multi_namespaced_entry_response][:history]).to be_a(Hash)
|
155
|
+
expect(hash[:multi_namespaced_entry_response][:history][:case]).to be_an(Array)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'respects the global :strip_namespaces option' do
|
159
|
+
globals[:strip_namespaces] = false
|
160
|
+
|
161
|
+
body = soap_response.body
|
162
|
+
|
163
|
+
expect(body).to be_a(Hash)
|
164
|
+
expect(body.keys).to include(:"ns2:authenticate_response")
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'respects the global :convert_response_tags_to option' do
|
168
|
+
globals[:convert_response_tags_to] = lambda { |key| key.upcase }
|
169
|
+
|
170
|
+
body = soap_response.body
|
171
|
+
|
172
|
+
expect(body).to be_a(Hash)
|
173
|
+
expect(body.keys).to include('AUTHENTICATERESPONSE')
|
98
174
|
end
|
99
175
|
end
|
100
176
|
end
|
@@ -102,25 +178,26 @@ describe Savon::Response do
|
|
102
178
|
describe "#to_array" do
|
103
179
|
context "when the given path exists" do
|
104
180
|
it "should return an Array containing the path value" do
|
105
|
-
soap_response.to_array(:authenticate_response, :return).
|
181
|
+
expect(soap_response.to_array(:authenticate_response, :return)).to eq(
|
106
182
|
[Fixture.response_hash(:authentication)[:authenticate_response][:return]]
|
183
|
+
)
|
107
184
|
end
|
108
185
|
|
109
186
|
it "should properly return FalseClass values [#327]" do
|
110
187
|
body = Gyoku.xml(:envelope => { :body => { :return => { :success => false } } })
|
111
|
-
soap_response(:body => body).to_array(:return, :success).
|
188
|
+
expect(soap_response(:body => body).to_array(:return, :success)).to eq([false])
|
112
189
|
end
|
113
190
|
end
|
114
191
|
|
115
192
|
context "when the given path returns nil" do
|
116
193
|
it "should return an empty Array" do
|
117
|
-
soap_response.to_array(:authenticate_response, :undefined).
|
194
|
+
expect(soap_response.to_array(:authenticate_response, :undefined)).to eq([])
|
118
195
|
end
|
119
196
|
end
|
120
197
|
|
121
198
|
context "when the given path does not exist at all" do
|
122
199
|
it "should return an empty Array" do
|
123
|
-
soap_response.to_array(:authenticate_response, :some, :undefined, :path).
|
200
|
+
expect(soap_response.to_array(:authenticate_response, :some, :undefined, :path)).to eq([])
|
124
201
|
end
|
125
202
|
end
|
126
203
|
end
|
@@ -128,32 +205,46 @@ describe Savon::Response do
|
|
128
205
|
describe "#hash" do
|
129
206
|
it "should return the complete SOAP response XML as a Hash" do
|
130
207
|
response = soap_response :body => Fixture.response(:header)
|
131
|
-
response.hash[:envelope][:header][:session_number].
|
208
|
+
expect(response.hash[:envelope][:header][:session_number]).to eq("ABCD1234")
|
132
209
|
end
|
133
210
|
end
|
134
211
|
|
135
212
|
describe "#to_xml" do
|
136
213
|
it "should return the raw SOAP response body" do
|
137
|
-
soap_response.to_xml.
|
214
|
+
expect(soap_response.to_xml).to eq(Fixture.response(:authentication))
|
138
215
|
end
|
139
216
|
end
|
140
217
|
|
141
218
|
describe "#doc" do
|
142
219
|
it "returns a Nokogiri::XML::Document for the SOAP response XML" do
|
143
|
-
soap_response.doc.
|
220
|
+
expect(soap_response.doc).to be_a(Nokogiri::XML::Document)
|
144
221
|
end
|
145
222
|
end
|
146
223
|
|
147
224
|
describe "#xpath" do
|
148
225
|
it "permits XPath access to elements in the request" do
|
149
|
-
soap_response.xpath("//client").first.inner_text.
|
150
|
-
soap_response.xpath("//ns2:authenticateResponse/return/success").first.inner_text.
|
226
|
+
expect(soap_response.xpath("//client").first.inner_text).to eq("radclient")
|
227
|
+
expect(soap_response.xpath("//ns2:authenticateResponse/return/success").first.inner_text).to eq("true")
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#find' do
|
232
|
+
it 'delegates to Nori#find to find child elements inside the Envelope' do
|
233
|
+
result = soap_response.find('Body', 'authenticateResponse', 'return')
|
234
|
+
|
235
|
+
expect(result).to be_a(Hash)
|
236
|
+
expect(result.keys).to include(:authentication_value)
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'fails correctly when envelope contains only string' do
|
240
|
+
response = soap_response({ :body => Fixture.response(:no_body) })
|
241
|
+
expect { response.find('Body') }.to raise_error Savon::InvalidResponseError
|
151
242
|
end
|
152
243
|
end
|
153
244
|
|
154
245
|
describe "#http" do
|
155
246
|
it "should return the HTTPI::Response" do
|
156
|
-
soap_response.http.
|
247
|
+
expect(soap_response.http).to be_an(HTTPI::Response)
|
157
248
|
end
|
158
249
|
end
|
159
250
|
|