savon 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -2
- data/lib/savon/client.rb +5 -4
- data/lib/savon/core_ext/hash.rb +18 -6
- data/lib/savon/soap/response.rb +11 -1
- data/lib/savon/soap/xml.rb +22 -6
- data/lib/savon/version.rb +1 -1
- data/lib/savon/wsdl/document.rb +5 -0
- data/lib/savon/wsdl/parser.rb +13 -1
- data/savon.gemspec +1 -1
- data/spec/fixtures/response/header.xml +13 -0
- data/spec/fixtures/wsdl/two_bindings.xml +25 -0
- data/spec/savon/client_spec.rb +27 -13
- data/spec/savon/core_ext/hash_spec.rb +17 -5
- data/spec/savon/soap/response_spec.rb +14 -0
- data/spec/savon/soap/xml_spec.rb +30 -6
- data/spec/savon/wsdl/document_spec.rb +22 -1
- data/spec/savon/wsdl/parser_spec.rb +30 -9
- metadata +9 -7
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,20 @@
|
|
1
|
-
## 0.8.
|
1
|
+
## 0.8.4 (2011-01-26)
|
2
|
+
|
3
|
+
* Fix for issues [issue #130](https://github.com/rubiii/savon/issues/130) and [#134](https://github.com/rubiii/savon/issues/134)
|
4
|
+
([4f9847](https://github.com/rubiii/savon/commit/4f9847)).
|
5
|
+
|
6
|
+
* Fix for [issue #91](https://github.com/rubiii/savon/issues/91) ([5c8ec1](https://github.com/rubiii/savon/commit/5c8ec1)).
|
7
|
+
|
8
|
+
* Fix for [issue #135](https://github.com/rubiii/savon/issues/135) ([c9261d](https://github.com/rubiii/savon/commit/c9261d)).
|
9
|
+
|
10
|
+
## 0.8.3 (2011-01-11)
|
2
11
|
|
3
12
|
* Moved implementation of `Savon::SOAP::Response#to_array` to a class method at `Savon::SOAP::XML.to_array`
|
4
13
|
([05a7d3](https://github.com/rubiii/savon/commit/05a7d3)).
|
5
14
|
|
6
15
|
* Fix for [issue #131](https://github.com/rubiii/savon/issues/131) ([4e57b3](https://github.com/rubiii/savon/commit/4e57b3)).
|
7
16
|
|
8
|
-
## 0.8.2 (
|
17
|
+
## 0.8.2 (2011-01-04)
|
9
18
|
|
10
19
|
* Fix for [issue #127](https://github.com/rubiii/savon/issues/127) ([0eb3da](https://github.com/rubiii/savon/commit/0eb3da4)).
|
11
20
|
|
data/lib/savon/client.rb
CHANGED
@@ -69,12 +69,12 @@ module Savon
|
|
69
69
|
# client.request(:get_user, "xmlns:wsdl" => "http://example.com")
|
70
70
|
def request(*args, &block)
|
71
71
|
raise ArgumentError, "Savon::Client#request requires at least one argument" if args.empty?
|
72
|
-
|
72
|
+
|
73
73
|
self.soap = SOAP::XML.new
|
74
74
|
preconfigure extract_options(args)
|
75
75
|
process &block if block
|
76
76
|
soap.wsse = wsse
|
77
|
-
|
77
|
+
|
78
78
|
response = SOAP::Request.new(http, soap).response
|
79
79
|
set_cookie response.http.headers
|
80
80
|
response
|
@@ -99,7 +99,7 @@ module Savon
|
|
99
99
|
attributes = Hash === args.last ? args.pop : {}
|
100
100
|
namespace = args.size > 1 ? args.shift.to_sym : nil
|
101
101
|
input = args.first
|
102
|
-
|
102
|
+
|
103
103
|
[namespace, input, attributes]
|
104
104
|
end
|
105
105
|
|
@@ -108,8 +108,9 @@ module Savon
|
|
108
108
|
soap.endpoint = wsdl.endpoint
|
109
109
|
soap.namespace_identifier = options[0]
|
110
110
|
soap.namespace = wsdl.namespace
|
111
|
+
soap.element_form_default = wsdl.element_form_default if wsdl.present?
|
111
112
|
soap.body = options[2].delete(:body) if options[2][:body]
|
112
|
-
|
113
|
+
|
113
114
|
set_soap_action options[1]
|
114
115
|
set_soap_input *options
|
115
116
|
end
|
data/lib/savon/core_ext/hash.rb
CHANGED
@@ -18,12 +18,16 @@ module Savon
|
|
18
18
|
self
|
19
19
|
end unless defined? deep_merge!
|
20
20
|
|
21
|
-
# Returns the values from the soap:
|
21
|
+
# Returns the values from the soap:Header element or an empty Hash in case the element could
|
22
|
+
# not be found.
|
23
|
+
def find_soap_header
|
24
|
+
find_soap_element /.+:Header/
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the values from the soap:Body element or an empty Hash in case the element could
|
22
28
|
# not be found.
|
23
29
|
def find_soap_body
|
24
|
-
|
25
|
-
body_key = envelope.keys.find { |key| /.+:Body/ =~ key } rescue nil
|
26
|
-
body_key ? envelope[body_key].map_soap_response : {}
|
30
|
+
find_soap_element /.+:Body/
|
27
31
|
end
|
28
32
|
|
29
33
|
# Maps keys and values of a Hash created from SOAP response XML to more convenient Ruby Objects.
|
@@ -34,13 +38,13 @@ module Savon
|
|
34
38
|
when ::Array then value.map { |val| val.map_soap_response rescue val }
|
35
39
|
when ::String then value.map_soap_response
|
36
40
|
end
|
37
|
-
|
41
|
+
|
38
42
|
new_key = if Savon.strip_namespaces?
|
39
43
|
key.strip_namespace.snakecase.to_sym
|
40
44
|
else
|
41
45
|
key.snakecase
|
42
46
|
end
|
43
|
-
|
47
|
+
|
44
48
|
if hash[new_key] # key already exists, value should be added as an Array
|
45
49
|
hash[new_key] = [hash[new_key], value].flatten
|
46
50
|
result = hash
|
@@ -51,6 +55,14 @@ module Savon
|
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
58
|
+
private
|
59
|
+
|
60
|
+
def find_soap_element(element)
|
61
|
+
envelope = self[keys.first] || {}
|
62
|
+
element_key = envelope.keys.find { |key| element =~ key } rescue nil
|
63
|
+
element_key ? envelope[element_key].map_soap_response : {}
|
64
|
+
end
|
65
|
+
|
54
66
|
end
|
55
67
|
end
|
56
68
|
end
|
data/lib/savon/soap/response.rb
CHANGED
@@ -43,9 +43,14 @@ module Savon
|
|
43
43
|
@http_error ||= HTTP::Error.new http
|
44
44
|
end
|
45
45
|
|
46
|
+
# Returns the SOAP response header as a Hash.
|
47
|
+
def header
|
48
|
+
@header_hash ||= basic_hash.find_soap_header
|
49
|
+
end
|
50
|
+
|
46
51
|
# Returns the SOAP response body as a Hash.
|
47
52
|
def to_hash
|
48
|
-
@hash ||= Savon::SOAP::XML.to_hash
|
53
|
+
@hash ||= Savon::SOAP::XML.to_hash basic_hash
|
49
54
|
end
|
50
55
|
|
51
56
|
# Returns the SOAP response body as an Array.
|
@@ -53,6 +58,11 @@ module Savon
|
|
53
58
|
Savon::SOAP::XML.to_array to_hash, *path
|
54
59
|
end
|
55
60
|
|
61
|
+
# Returns the complete SOAP response XML without normalization.
|
62
|
+
def basic_hash
|
63
|
+
@basic_hash ||= Savon::SOAP::XML.parse http.body
|
64
|
+
end
|
65
|
+
|
56
66
|
# Returns the SOAP response XML.
|
57
67
|
def to_xml
|
58
68
|
http.body
|
data/lib/savon/soap/xml.rb
CHANGED
@@ -20,9 +20,15 @@ module Savon
|
|
20
20
|
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
|
21
21
|
}
|
22
22
|
|
23
|
-
# Converts the given SOAP response +
|
24
|
-
def self.to_hash(
|
25
|
-
|
23
|
+
# Converts the given SOAP response +value+ (XML or Hash) into a normalized Hash.
|
24
|
+
def self.to_hash(value)
|
25
|
+
value = parse value unless value.kind_of? Hash
|
26
|
+
value.find_soap_body
|
27
|
+
end
|
28
|
+
|
29
|
+
# Converts a given SOAP response +xml+ to a Hash.
|
30
|
+
def self.parse(xml)
|
31
|
+
Crack::XML.parse(xml) rescue {}
|
26
32
|
end
|
27
33
|
|
28
34
|
# Expects a SOAP response XML or Hash, traverses it for a given +path+ of Hash keys
|
@@ -30,12 +36,12 @@ module Savon
|
|
30
36
|
# path does not exist or returns nil.
|
31
37
|
def self.to_array(object, *path)
|
32
38
|
hash = object.kind_of?(Hash) ? object : to_hash(object)
|
33
|
-
|
39
|
+
|
34
40
|
result = path.inject hash do |memo, key|
|
35
41
|
return [] unless memo[key]
|
36
42
|
memo[key]
|
37
43
|
end
|
38
|
-
|
44
|
+
|
39
45
|
result.kind_of?(Array) ? result.compact : [result].compact
|
40
46
|
end
|
41
47
|
|
@@ -98,6 +104,15 @@ module Savon
|
|
98
104
|
@namespace_identifier ||= :wsdl
|
99
105
|
end
|
100
106
|
|
107
|
+
# Returns whether all local elements should be namespaced. Might be set to :qualified,
|
108
|
+
# but defaults to :unqualified.
|
109
|
+
def element_form_default
|
110
|
+
@element_form_default ||= :unqualified
|
111
|
+
end
|
112
|
+
|
113
|
+
# Sets whether all local elements should be namespaced.
|
114
|
+
attr_writer :element_form_default
|
115
|
+
|
101
116
|
# Accessor for the default namespace URI.
|
102
117
|
attr_accessor :namespace
|
103
118
|
|
@@ -159,7 +174,8 @@ module Savon
|
|
159
174
|
|
160
175
|
# Returns the SOAP body as an XML String.
|
161
176
|
def body_to_xml
|
162
|
-
body.
|
177
|
+
return body.to_s unless body.kind_of? Hash
|
178
|
+
Gyoku.xml body, :element_form_default => element_form_default, :namespace => namespace_identifier
|
163
179
|
end
|
164
180
|
|
165
181
|
end
|
data/lib/savon/version.rb
CHANGED
data/lib/savon/wsdl/document.rb
CHANGED
@@ -61,6 +61,11 @@ module Savon
|
|
61
61
|
@operations ||= parser.operations
|
62
62
|
end
|
63
63
|
|
64
|
+
# Returns the elementFormDefault value.
|
65
|
+
def element_form_default
|
66
|
+
@element_form_default ||= parser.element_form_default
|
67
|
+
end
|
68
|
+
|
64
69
|
# Sets the location of the WSDL document to use. This can either be a URL
|
65
70
|
# or a path to a local file.
|
66
71
|
attr_writer :document
|
data/lib/savon/wsdl/parser.rb
CHANGED
@@ -13,7 +13,10 @@ module Savon
|
|
13
13
|
Sections = %w(definitions types message portType binding service)
|
14
14
|
|
15
15
|
def initialize
|
16
|
-
@path
|
16
|
+
@path = []
|
17
|
+
@operations = {}
|
18
|
+
@namespaces = {}
|
19
|
+
@element_form_default = :unqualified
|
17
20
|
end
|
18
21
|
|
19
22
|
# Returns the namespace URI.
|
@@ -25,6 +28,9 @@ module Savon
|
|
25
28
|
# Returns the SOAP endpoint.
|
26
29
|
attr_reader :endpoint
|
27
30
|
|
31
|
+
# Returns the elementFormDefault value.
|
32
|
+
attr_reader :element_form_default
|
33
|
+
|
28
34
|
# Hook method called when the stream parser encounters a starting tag.
|
29
35
|
def tag_start(tag, attrs)
|
30
36
|
# read xml namespaces if root element
|
@@ -33,6 +39,10 @@ module Savon
|
|
33
39
|
tag, namespace = tag.split(":").reverse
|
34
40
|
@path << tag
|
35
41
|
|
42
|
+
if @section == :types && tag == "schema"
|
43
|
+
@element_form_default = attrs["elementFormDefault"].to_sym if attrs["elementFormDefault"]
|
44
|
+
end
|
45
|
+
|
36
46
|
if @section == :binding && tag == "binding"
|
37
47
|
# ensure that we are in an wsdl/soap namespace
|
38
48
|
@section = nil unless @namespaces[namespace].starts_with? "http://schemas.xmlsoap.org/wsdl/soap"
|
@@ -66,6 +76,8 @@ module Savon
|
|
66
76
|
# no soapAction attribute found till now
|
67
77
|
operation_from tag, "soapAction" => @input
|
68
78
|
end
|
79
|
+
|
80
|
+
@section = :definitions if Sections.include?(tag) && depth <= 1
|
69
81
|
end
|
70
82
|
|
71
83
|
# Stores available operations from a given tag +name+ and +attrs+.
|
data/savon.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_dependency "builder", ">= 2.1.2"
|
18
18
|
s.add_dependency "crack", "~> 0.1.8"
|
19
19
|
s.add_dependency "httpi", ">= 0.7.8"
|
20
|
-
s.add_dependency "gyoku", ">= 0.
|
20
|
+
s.add_dependency "gyoku", ">= 0.3.0"
|
21
21
|
|
22
22
|
s.add_development_dependency "rspec", "~> 2.4.0"
|
23
23
|
s.add_development_dependency "autotest"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
3
|
+
<soap:Header xmlns="http://webservices.somewhere.com/definitions">
|
4
|
+
<SessionNumber>ABCD1234</SessionNumber>
|
5
|
+
</soap:Header>
|
6
|
+
<soap:Body>
|
7
|
+
<AuthenticateReply xmlns="http://xml.somewhere.com/ABCD">
|
8
|
+
<processStatus>
|
9
|
+
<statusCode>P</statusCode>
|
10
|
+
</processStatus>
|
11
|
+
</AuthenticateReply>
|
12
|
+
</soap:Body>
|
13
|
+
</soap:Envelope>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!-- Example of a WSDL with two <binding> tags ("sections" in Savon
|
3
|
+
parlance).
|
4
|
+
|
5
|
+
This is stripped down from a real example found in the wild, although
|
6
|
+
having different operations for the SOAP 1.1 and SOAP 1.2 bindings
|
7
|
+
is hypothetical (the real-world example I saw had the same operations
|
8
|
+
in each binding section). -->
|
9
|
+
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
10
|
+
<types>
|
11
|
+
</types>
|
12
|
+
<portType name="BlogSoap">
|
13
|
+
</portType>
|
14
|
+
<binding name="BlogSoap">
|
15
|
+
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
|
16
|
+
<operation name="Post" />
|
17
|
+
<operation name="Post11only" />
|
18
|
+
</binding>
|
19
|
+
<binding name="BlogSoap12">
|
20
|
+
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
|
21
|
+
<operation name="Post" />
|
22
|
+
<operation name="Post12only" />
|
23
|
+
</binding>
|
24
|
+
</definitions>
|
25
|
+
|
data/spec/savon/client_spec.rb
CHANGED
@@ -82,14 +82,14 @@ describe Savon::Client do
|
|
82
82
|
it "should set the target namespace with the default identifier" do
|
83
83
|
namespace = 'xmlns:wsdl="http://v1_0.ws.auth.order.example.com/"'
|
84
84
|
HTTPI::Request.any_instance.expects(:body=).with { |value| value.include? namespace }
|
85
|
-
|
85
|
+
|
86
86
|
client.request :get_user
|
87
87
|
end
|
88
88
|
|
89
89
|
it "should not set the target namespace if soap.namespace was set to nil" do
|
90
90
|
namespace = "http://v1_0.ws.auth.order.example.com/"
|
91
91
|
HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
|
92
|
-
|
92
|
+
|
93
93
|
client.request(:get_user) { soap.namespace = nil }
|
94
94
|
end
|
95
95
|
end
|
@@ -114,14 +114,14 @@ describe Savon::Client do
|
|
114
114
|
it "should set the target namespace with the given identifier" do
|
115
115
|
namespace = 'xmlns:v1="http://v1_0.ws.auth.order.example.com/"'
|
116
116
|
HTTPI::Request.any_instance.expects(:body=).with { |value| value.include? namespace }
|
117
|
-
|
117
|
+
|
118
118
|
client.request :v1, :get_user
|
119
119
|
end
|
120
120
|
|
121
121
|
it "should not set the target namespace if soap.namespace was set to nil" do
|
122
122
|
namespace = "http://v1_0.ws.auth.order.example.com/"
|
123
123
|
HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
|
124
|
-
|
124
|
+
|
125
125
|
client.request(:v1, :get_user) { soap.namespace = nil }
|
126
126
|
end
|
127
127
|
end
|
@@ -190,7 +190,7 @@ describe Savon::Client do
|
|
190
190
|
client.http.headers.expects(:[]=).with("Cookie", anything).never
|
191
191
|
client.http.headers.stubs(:[]=).with("SOAPAction", '"authenticate"')
|
192
192
|
client.http.headers.stubs(:[]=).with("Content-Type", "text/xml;charset=UTF-8")
|
193
|
-
|
193
|
+
|
194
194
|
client.request :authenticate
|
195
195
|
end
|
196
196
|
end
|
@@ -205,7 +205,7 @@ describe Savon::Client do
|
|
205
205
|
client.http.headers.expects(:[]=).with("Cookie", "some-cookie")
|
206
206
|
client.http.headers.stubs(:[]=).with("SOAPAction", '"authenticate"')
|
207
207
|
client.http.headers.stubs(:[]=).with("Content-Type", "text/xml;charset=UTF-8")
|
208
|
-
|
208
|
+
|
209
209
|
client.request :authenticate
|
210
210
|
end
|
211
211
|
end
|
@@ -220,7 +220,7 @@ describe Savon::Client do
|
|
220
220
|
|
221
221
|
it "adds a SOAPAction header containing the SOAP action name" do
|
222
222
|
HTTPI.stubs(:post).returns(new_response)
|
223
|
-
|
223
|
+
|
224
224
|
client.request :authenticate do
|
225
225
|
http.headers["SOAPAction"].should == %{"authenticate"}
|
226
226
|
end
|
@@ -229,7 +229,7 @@ describe Savon::Client do
|
|
229
229
|
it "should execute SOAP requests and return the response" do
|
230
230
|
HTTPI.expects(:post).returns(new_response)
|
231
231
|
response = client.request(:authenticate)
|
232
|
-
|
232
|
+
|
233
233
|
response.should be_a(Savon::SOAP::Response)
|
234
234
|
response.to_xml.should == Fixture.response(:authentication)
|
235
235
|
end
|
@@ -246,16 +246,23 @@ describe Savon::Client do
|
|
246
246
|
|
247
247
|
it "adds a SOAPAction header containing the SOAP action name" do
|
248
248
|
HTTPI.stubs(:post).returns(new_response)
|
249
|
-
|
249
|
+
|
250
250
|
client.request :authenticate do
|
251
251
|
http.headers["SOAPAction"].should == %{"authenticate"}
|
252
252
|
end
|
253
253
|
end
|
254
254
|
|
255
|
+
it "should get #element_form_default from the WSDL" do
|
256
|
+
HTTPI.stubs(:post).returns(new_response)
|
257
|
+
Savon::WSDL::Document.any_instance.expects(:element_form_default).returns(:qualified)
|
258
|
+
|
259
|
+
client.request :authenticate
|
260
|
+
end
|
261
|
+
|
255
262
|
it "should execute SOAP requests and return the response" do
|
256
263
|
HTTPI.expects(:post).returns(new_response)
|
257
264
|
response = client.request(:authenticate)
|
258
|
-
|
265
|
+
|
259
266
|
response.should be_a(Savon::SOAP::Response)
|
260
267
|
response.to_xml.should == Fixture.response(:authentication)
|
261
268
|
end
|
@@ -277,16 +284,23 @@ describe Savon::Client do
|
|
277
284
|
|
278
285
|
it "adds a SOAPAction header containing the SOAP action name" do
|
279
286
|
HTTPI.stubs(:post).returns(new_response)
|
280
|
-
|
287
|
+
|
281
288
|
client.request :authenticate do
|
282
289
|
http.headers["SOAPAction"].should == %{"authenticate"}
|
283
290
|
end
|
284
291
|
end
|
285
292
|
|
293
|
+
it "should not get #element_form_default from the WSDL" do
|
294
|
+
HTTPI.stubs(:post).returns(new_response)
|
295
|
+
Savon::WSDL::Document.any_instance.expects(:element_form_default).never
|
296
|
+
|
297
|
+
client.request :authenticate
|
298
|
+
end
|
299
|
+
|
286
300
|
it "should execute SOAP requests and return the response" do
|
287
301
|
HTTPI.expects(:post).returns(new_response)
|
288
302
|
response = client.request(:authenticate)
|
289
|
-
|
303
|
+
|
290
304
|
response.should be_a(Savon::SOAP::Response)
|
291
305
|
response.to_xml.should == Fixture.response(:authentication)
|
292
306
|
end
|
@@ -325,7 +339,7 @@ describe Savon::Client do
|
|
325
339
|
def new_response(options = {})
|
326
340
|
defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
|
327
341
|
response = defaults.merge options
|
328
|
-
|
342
|
+
|
329
343
|
HTTPI::Response.new response[:code], response[:headers], response[:body]
|
330
344
|
end
|
331
345
|
|
@@ -6,12 +6,24 @@ describe Hash do
|
|
6
6
|
it "should recursively merge two Hashes" do
|
7
7
|
hash = { :one => 1, "two" => { "three" => 3 } }
|
8
8
|
other_hash = { :four => 4, "two" => { "three" => "merge", :five => 5 } }
|
9
|
-
|
9
|
+
|
10
10
|
hash.merge!(other_hash).should == { :one => 1, :four => 4, "two" => { "three" => "merge", :five => 5 } }
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
describe "
|
14
|
+
describe "#find_soap_header" do
|
15
|
+
it "should return the content from the 'soap:Header' element" do
|
16
|
+
soap_header = { "soap:Envelope" => { "soap:Header" => "content" } }
|
17
|
+
soap_header.find_soap_header.should == "content"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return an empty Hash in case the 'soap:Header' element could not be found" do
|
21
|
+
soap_header = { "some_hash" => "content" }
|
22
|
+
soap_header.find_soap_header.should == {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#find_soap_body" do
|
15
27
|
it "should return the content from the 'soap:Body' element" do
|
16
28
|
soap_body = { "soap:Envelope" => { "soap:Body" => "content" } }
|
17
29
|
soap_body.find_soap_body.should == "content"
|
@@ -23,7 +35,7 @@ describe Hash do
|
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
26
|
-
describe "map_soap_response" do
|
38
|
+
describe "#map_soap_response" do
|
27
39
|
it "should convert Hash key Strings to snake_case Symbols" do
|
28
40
|
soap_response = { "userResponse" => { "accountStatus" => "active" } }
|
29
41
|
result = { :user_response => { :account_status => "active" } }
|
@@ -95,13 +107,13 @@ describe Hash do
|
|
95
107
|
"ns11:case" => { "ns11:name" => "another_name" }
|
96
108
|
}
|
97
109
|
}
|
98
|
-
|
110
|
+
|
99
111
|
result = {
|
100
112
|
:history => {
|
101
113
|
:case => [{ :name => "a_name" }, { :name => "another_name" }]
|
102
114
|
}
|
103
115
|
}
|
104
|
-
|
116
|
+
|
105
117
|
soap_response.map_soap_response.should == result
|
106
118
|
end
|
107
119
|
end
|
@@ -116,6 +116,13 @@ describe Savon::SOAP::Response do
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
+
describe "#header" do
|
120
|
+
it "should return the SOAP response header as a Hash" do
|
121
|
+
response = soap_response :body => Fixture.response(:header)
|
122
|
+
response.header.should include(:session_number => "ABCD1234")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
119
126
|
describe "#to_hash" do
|
120
127
|
it "should return the SOAP response body as a Hash" do
|
121
128
|
soap_response.to_hash[:authenticate_response][:return].should ==
|
@@ -130,6 +137,13 @@ describe Savon::SOAP::Response do
|
|
130
137
|
end
|
131
138
|
end
|
132
139
|
|
140
|
+
describe "#basic_hash" do
|
141
|
+
it "should return the complete SOAP response XML as a Hash" do
|
142
|
+
response = soap_response :body => Fixture.response(:header)
|
143
|
+
response.basic_hash["soap:Envelope"]["soap:Header"]["SessionNumber"].should == "ABCD1234"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
133
147
|
describe "#to_xml" do
|
134
148
|
it "should return the raw SOAP response body" do
|
135
149
|
soap_response.to_xml.should == Fixture.response(:authentication)
|
data/spec/savon/soap/xml_spec.rb
CHANGED
@@ -18,19 +18,26 @@ describe Savon::SOAP::XML do
|
|
18
18
|
|
19
19
|
it "should return a Hash for a SOAP multiRef response" do
|
20
20
|
hash = Savon::SOAP::XML.to_hash Fixture.response(:multi_ref)
|
21
|
-
|
21
|
+
|
22
22
|
hash[:list_response].should be_a(Hash)
|
23
23
|
hash[:multi_ref].should be_an(Array)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should add existing namespaced elements as an array" do
|
27
27
|
hash = Savon::SOAP::XML.to_hash Fixture.response(:list)
|
28
|
-
|
28
|
+
|
29
29
|
hash[:multi_namespaced_entry_response][:history].should be_a(Hash)
|
30
30
|
hash[:multi_namespaced_entry_response][:history][:case].should be_an(Array)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
describe ".parse" do
|
35
|
+
it "should convert the given XML into a Hash" do
|
36
|
+
hash = Savon::SOAP::XML.parse Fixture.response(:list)
|
37
|
+
hash["soapenv:Envelope"]["soapenv:Body"].should be_a(Hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
34
41
|
describe ".to_array" do
|
35
42
|
let(:response_hash) { Fixture.response_hash :authentication }
|
36
43
|
|
@@ -57,7 +64,7 @@ describe Savon::SOAP::XML do
|
|
57
64
|
describe ".new" do
|
58
65
|
it "should accept an endpoint, an input tag and a SOAP body" do
|
59
66
|
xml = Savon::SOAP::XML.new Endpoint.soap, :authentication, :id => 1
|
60
|
-
|
67
|
+
|
61
68
|
xml.endpoint.should == Endpoint.soap
|
62
69
|
xml.input.should == :authentication
|
63
70
|
xml.body.should == { :id => 1 }
|
@@ -86,7 +93,7 @@ describe Savon::SOAP::XML do
|
|
86
93
|
it "should default to the global default" do
|
87
94
|
Savon.soap_version = 2
|
88
95
|
xml.version.should == 2
|
89
|
-
|
96
|
+
|
90
97
|
reset_soap_version
|
91
98
|
end
|
92
99
|
|
@@ -224,7 +231,7 @@ describe Savon::SOAP::XML do
|
|
224
231
|
context "with the global SOAP version set to 1.2" do
|
225
232
|
it "should contain the namespace for SOAP 1.2" do
|
226
233
|
Savon.soap_version = 2
|
227
|
-
|
234
|
+
|
228
235
|
uri = "http://www.w3.org/2003/05/soap-envelope"
|
229
236
|
xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
|
230
237
|
reset_soap_version
|
@@ -235,7 +242,7 @@ describe Savon::SOAP::XML do
|
|
235
242
|
it "should contain the namespace for the request SOAP version" do
|
236
243
|
Savon.soap_version = 2
|
237
244
|
xml.version = 1
|
238
|
-
|
245
|
+
|
239
246
|
uri = "http://schemas.xmlsoap.org/soap/envelope/"
|
240
247
|
xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
|
241
248
|
reset_soap_version
|
@@ -257,6 +264,23 @@ describe Savon::SOAP::XML do
|
|
257
264
|
end
|
258
265
|
end
|
259
266
|
|
267
|
+
context "with :element_form_default set to :qualified and a :namespace" do
|
268
|
+
let :xml do
|
269
|
+
Savon::SOAP::XML.new Endpoint.soap, :authenticate, :user => { :id => 1, ":noNamespace" => true }
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should namespace the default elements" do
|
273
|
+
xml.element_form_default = :qualified
|
274
|
+
xml.namespace_identifier = :wsdl
|
275
|
+
|
276
|
+
xml.to_xml.should include(
|
277
|
+
"<wsdl:user>",
|
278
|
+
"<wsdl:id>1</wsdl:id>",
|
279
|
+
"<noNamespace>true</noNamespace>"
|
280
|
+
)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
260
284
|
context "with WSSE authentication" do
|
261
285
|
it "should containg a SOAP header with WSSE authentication details" do
|
262
286
|
xml.wsse = Savon::WSSE.new
|
@@ -64,11 +64,17 @@ describe Savon::WSDL::Document do
|
|
64
64
|
let(:wsdl) { Savon::WSDL::Document.new HTTPI::Request.new, Endpoint.wsdl }
|
65
65
|
|
66
66
|
before do
|
67
|
-
response = HTTPI::Response.new
|
67
|
+
response = HTTPI::Response.new 200, {}, Fixture.wsdl(:authentication)
|
68
68
|
HTTPI.stubs(:get).returns(response)
|
69
69
|
end
|
70
70
|
|
71
71
|
it_should_behave_like "a WSDL document"
|
72
|
+
|
73
|
+
describe "#element_form_default" do
|
74
|
+
it "should return :unqualified" do
|
75
|
+
wsdl.element_form_default.should == :unqualified
|
76
|
+
end
|
77
|
+
end
|
72
78
|
end
|
73
79
|
|
74
80
|
context "with a local document" do
|
@@ -108,4 +114,19 @@ describe Savon::WSDL::Document do
|
|
108
114
|
end
|
109
115
|
end
|
110
116
|
|
117
|
+
context "with a WSDL document containing elementFormDefault='qualified'" do
|
118
|
+
let(:wsdl) { Savon::WSDL::Document.new HTTPI::Request.new, Endpoint.wsdl }
|
119
|
+
|
120
|
+
before do
|
121
|
+
response = HTTPI::Response.new 200, {}, Fixture.wsdl(:geotrust)
|
122
|
+
HTTPI.stubs(:get).returns(response)
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#element_form_default" do
|
126
|
+
it "should return :qualified" do
|
127
|
+
wsdl.element_form_default.should == :qualified
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
111
132
|
end
|
@@ -5,60 +5,81 @@ describe Savon::WSDL::Parser do
|
|
5
5
|
context "with namespaced_actions.xml" do
|
6
6
|
let(:parser) { new_parser :namespaced_actions }
|
7
7
|
|
8
|
-
it "should
|
8
|
+
it "should return the target namespace" do
|
9
9
|
parser.namespace.should == "http://api.example.com/api/"
|
10
10
|
end
|
11
11
|
|
12
|
-
it "should
|
12
|
+
it "should return the SOAP endpoint" do
|
13
13
|
parser.endpoint.should == URI("https://api.example.com/api/api.asmx")
|
14
14
|
end
|
15
15
|
|
16
|
-
it "should
|
16
|
+
it "should return the available SOAP operations" do
|
17
17
|
parser.operations.should match_operations(
|
18
18
|
:get_api_key => { :input => "GetApiKey", :action => "http://api.example.com/api/User.GetApiKey" },
|
19
19
|
:delete_client => { :input => "DeleteClient", :action => "http://api.example.com/api/Client.Delete" },
|
20
20
|
:get_clients => { :input => "GetClients", :action => "http://api.example.com/api/User.GetClients" }
|
21
21
|
)
|
22
22
|
end
|
23
|
+
|
24
|
+
it "should return that :element_form_default is set to :qualified" do
|
25
|
+
parser.element_form_default.should == :qualified
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
context "with no_namespace.xml" do
|
26
30
|
let(:parser) { new_parser :no_namespace }
|
27
31
|
|
28
|
-
it "should
|
32
|
+
it "should return the target namespace" do
|
29
33
|
parser.namespace.should == "urn:ActionWebService"
|
30
34
|
end
|
31
35
|
|
32
|
-
it "should
|
36
|
+
it "should return the SOAP endpoint" do
|
33
37
|
parser.endpoint.should == URI("http://example.com/api/api")
|
34
38
|
end
|
35
39
|
|
36
|
-
it "should
|
40
|
+
it "should return the available SOAP operations" do
|
37
41
|
parser.operations.should match_operations(
|
38
42
|
:search_user => { :input => "SearchUser", :action => "/api/api/SearchUser" },
|
39
43
|
:get_user_login_by_id => { :input => "GetUserLoginById", :action => "/api/api/GetUserLoginById" },
|
40
44
|
:get_all_contacts => { :input => "GetAllContacts", :action => "/api/api/GetAllContacts" }
|
41
45
|
)
|
42
46
|
end
|
47
|
+
|
48
|
+
it "should return that :element_form_default is set to :unqualified" do
|
49
|
+
parser.element_form_default.should == :unqualified
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
53
|
context "with geotrust.xml" do
|
46
54
|
let(:parser) { new_parser :geotrust }
|
47
55
|
|
48
|
-
it "should
|
56
|
+
it "should return the target namespace" do
|
49
57
|
parser.namespace.should == "http://api.geotrust.com/webtrust/query"
|
50
58
|
end
|
51
59
|
|
52
|
-
it "should
|
60
|
+
it "should return the SOAP endpoint" do
|
53
61
|
parser.endpoint.should == URI("https://test-api.geotrust.com/webtrust/query.jws")
|
54
62
|
end
|
55
63
|
|
56
|
-
it "should
|
64
|
+
it "should return the available SOAP operations" do
|
57
65
|
parser.operations.should match_operations(
|
58
66
|
:get_quick_approver_list => { :input => "GetQuickApproverList", :action => "GetQuickApproverList" },
|
59
67
|
:hello => { :input => "hello", :action => "hello" }
|
60
68
|
)
|
61
69
|
end
|
70
|
+
|
71
|
+
it "should return that :element_form_default is set to :qualified" do
|
72
|
+
parser.element_form_default.should == :qualified
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with two_bindings.xml" do
|
77
|
+
let(:parser) { new_parser :two_bindings }
|
78
|
+
|
79
|
+
it "should merge operations from all binding sections (until we have an example where it makes sense to do otherwise)" do
|
80
|
+
parser.operations.keys.map(&:to_s).sort.should ==
|
81
|
+
%w{post post11only post12only}
|
82
|
+
end
|
62
83
|
end
|
63
84
|
|
64
85
|
RSpec::Matchers.define :match_operations do |expected|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: savon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 55
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 4
|
10
|
+
version: 0.8.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel Harrington
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-26 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -74,12 +74,12 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
hash:
|
77
|
+
hash: 19
|
78
78
|
segments:
|
79
79
|
- 0
|
80
|
-
-
|
80
|
+
- 3
|
81
81
|
- 0
|
82
|
-
version: 0.
|
82
|
+
version: 0.3.0
|
83
83
|
type: :runtime
|
84
84
|
version_requirements: *id004
|
85
85
|
- !ruby/object:Gem::Dependency
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- spec/fixtures/gzip/message.gz
|
185
185
|
- spec/fixtures/response/another_soap_fault.xml
|
186
186
|
- spec/fixtures/response/authentication.xml
|
187
|
+
- spec/fixtures/response/header.xml
|
187
188
|
- spec/fixtures/response/list.xml
|
188
189
|
- spec/fixtures/response/multi_ref.xml
|
189
190
|
- spec/fixtures/response/soap_fault.xml
|
@@ -192,6 +193,7 @@ files:
|
|
192
193
|
- spec/fixtures/wsdl/geotrust.xml
|
193
194
|
- spec/fixtures/wsdl/namespaced_actions.xml
|
194
195
|
- spec/fixtures/wsdl/no_namespace.xml
|
196
|
+
- spec/fixtures/wsdl/two_bindings.xml
|
195
197
|
- spec/savon/client_spec.rb
|
196
198
|
- spec/savon/core_ext/hash_spec.rb
|
197
199
|
- spec/savon/core_ext/object_spec.rb
|