savon 0.8.3 → 0.8.4
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/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
|