savon 0.9.5 → 0.9.6
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 +13 -0
- data/Rakefile +3 -1
- data/lib/savon/client.rb +20 -12
- data/lib/savon/soap/xml.rb +58 -2
- data/lib/savon/version.rb +1 -1
- data/savon.gemspec +1 -1
- data/spec/fixtures/wsdl/lower_camel.xml +52 -0
- data/spec/fixtures/wsdl/multiple_namespaces.xml +61 -0
- data/spec/fixtures/wsdl/multiple_types.xml +60 -0
- data/spec/savon/client_spec.rb +106 -5
- data/spec/savon/soap/request_spec.rb +1 -1
- data/spec/savon/soap/xml_spec.rb +8 -8
- metadata +10 -7
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 0.9.6 (2011-07-07)
|
2
|
+
|
3
|
+
* Improvement/Fix: Updated Savon to use the latest version of [Wasabi](http://rubygems.org/gems/wasabi).
|
4
|
+
This should fix [issue 155](https://github.com/rubiii/savon/issues/155) - Savon can automatically add namespaces
|
5
|
+
to SOAP requests based on the WSDL. Users shouldn't need to do anything differently or even notice whether their WSDL
|
6
|
+
hits this case; the intention is that this will "Just Work" and follow the WSDL. The SOAP details are that if
|
7
|
+
elementFormDefault is specified as qualified, Savon will automatically prepend the correct XML namespaces to the
|
8
|
+
elements in a SOAP request.
|
9
|
+
|
10
|
+
Thanks to [jkingdon](https://github.com/jkingdon) for this.
|
11
|
+
|
12
|
+
* Fix: [issue 143](https://github.com/rubiii/savon/issues/143) - Updating Wasabi should solve this issue.
|
13
|
+
|
1
14
|
## 0.9.5 (2011-07-03)
|
2
15
|
|
3
16
|
* Refactoring: Extracted WSSE authentication out into the [akami](http://rubygems.org/gems/akami) gem.
|
data/Rakefile
CHANGED
data/lib/savon/client.rb
CHANGED
@@ -104,30 +104,38 @@ module Savon
|
|
104
104
|
[namespace, input, attributes]
|
105
105
|
end
|
106
106
|
|
107
|
-
# Expects
|
108
|
-
def preconfigure(
|
107
|
+
# Expects an Array of +args+ to preconfigure the system.
|
108
|
+
def preconfigure(args)
|
109
109
|
soap.endpoint = wsdl.endpoint
|
110
|
-
soap.namespace_identifier =
|
110
|
+
soap.namespace_identifier = args[0]
|
111
111
|
soap.namespace = wsdl.namespace
|
112
112
|
soap.element_form_default = wsdl.element_form_default if wsdl.document?
|
113
|
-
soap.body =
|
113
|
+
soap.body = args[2].delete(:body)
|
114
114
|
|
115
|
-
|
116
|
-
|
115
|
+
wsdl.type_namespaces.each do |path, uri|
|
116
|
+
soap.use_namespace(path, uri)
|
117
|
+
end
|
118
|
+
|
119
|
+
wsdl.type_definitions.each do |path, type|
|
120
|
+
soap.types[path] = type
|
121
|
+
end
|
122
|
+
|
123
|
+
set_soap_action args[1]
|
124
|
+
set_soap_input *args
|
117
125
|
end
|
118
126
|
|
119
127
|
# Expects an +input+ and sets the +SOAPAction+ HTTP headers.
|
120
|
-
def set_soap_action(
|
121
|
-
soap_action = wsdl.soap_action(
|
122
|
-
soap_action ||= Gyoku::XMLKey.create(
|
128
|
+
def set_soap_action(input_tag)
|
129
|
+
soap_action = wsdl.soap_action(input_tag.to_sym) if wsdl.document?
|
130
|
+
soap_action ||= Gyoku::XMLKey.create(input_tag).to_sym
|
123
131
|
http.headers["SOAPAction"] = %{"#{soap_action}"}
|
124
132
|
end
|
125
133
|
|
126
134
|
# Expects a +namespace+, +input+ and +attributes+ and sets the SOAP input.
|
127
135
|
def set_soap_input(namespace, input, attributes)
|
128
|
-
|
129
|
-
|
130
|
-
soap.input = [namespace,
|
136
|
+
new_input_tag = wsdl.soap_input(input.to_sym) if wsdl.document?
|
137
|
+
new_input_tag ||= Gyoku::XMLKey.create(input)
|
138
|
+
soap.input = [namespace, new_input_tag.to_sym, attributes]
|
131
139
|
end
|
132
140
|
|
133
141
|
# Processes a given +block+. Yields objects if the block expects any arguments.
|
data/lib/savon/soap/xml.rb
CHANGED
@@ -75,6 +75,33 @@ module Savon
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
def namespace_by_uri(uri)
|
79
|
+
namespaces.each do |candidate_identifier, candidate_uri|
|
80
|
+
return candidate_identifier.gsub(/^xmlns:/, '') if candidate_uri == uri
|
81
|
+
end
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def used_namespaces
|
86
|
+
@used_namespaces ||= {}
|
87
|
+
end
|
88
|
+
|
89
|
+
def use_namespace(path, uri)
|
90
|
+
@internal_namespace_count ||= 0
|
91
|
+
|
92
|
+
unless identifier = namespace_by_uri(uri)
|
93
|
+
identifier = "ins#{@internal_namespace_count}"
|
94
|
+
namespaces["xmlns:#{identifier}"] = uri
|
95
|
+
@internal_namespace_count += 1
|
96
|
+
end
|
97
|
+
|
98
|
+
used_namespaces[path] = identifier
|
99
|
+
end
|
100
|
+
|
101
|
+
def types
|
102
|
+
@types ||= {}
|
103
|
+
end
|
104
|
+
|
78
105
|
# Sets the default namespace identifier.
|
79
106
|
attr_writer :namespace_identifier
|
80
107
|
|
@@ -114,7 +141,12 @@ module Savon
|
|
114
141
|
def to_xml
|
115
142
|
@xml ||= tag(builder, :Envelope, complete_namespaces) do |xml|
|
116
143
|
tag(xml, :Header) { xml << header_for_xml } unless header_for_xml.empty?
|
117
|
-
|
144
|
+
|
145
|
+
if input.nil?
|
146
|
+
tag(xml, :Body)
|
147
|
+
else
|
148
|
+
tag(xml, :Body) { xml.tag!(*add_namespace_to_input) { xml << body_to_xml } }
|
149
|
+
end
|
118
150
|
end
|
119
151
|
end
|
120
152
|
|
@@ -154,7 +186,31 @@ module Savon
|
|
154
186
|
# Returns the SOAP body as an XML String.
|
155
187
|
def body_to_xml
|
156
188
|
return body.to_s unless body.kind_of? Hash
|
157
|
-
Gyoku.xml body, :element_form_default => element_form_default, :namespace => namespace_identifier
|
189
|
+
Gyoku.xml add_namespaces_to_body(body), :element_form_default => element_form_default, :namespace => namespace_identifier
|
190
|
+
end
|
191
|
+
|
192
|
+
def add_namespaces_to_body(hash, path = [input[1].to_s])
|
193
|
+
return unless hash
|
194
|
+
return hash.to_s unless hash.kind_of? Hash
|
195
|
+
|
196
|
+
hash.inject({}) do |newhash, (key, value)|
|
197
|
+
camelcased_key = Gyoku::XMLKey.create(key)
|
198
|
+
newpath = path + [camelcased_key]
|
199
|
+
|
200
|
+
if used_namespaces[newpath]
|
201
|
+
newhash.merge(
|
202
|
+
"#{used_namespaces[newpath]}:#{camelcased_key}" =>
|
203
|
+
add_namespaces_to_body(value, types[newpath] ? [types[newpath]] : newpath)
|
204
|
+
)
|
205
|
+
else
|
206
|
+
newhash.merge(key => value)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def add_namespace_to_input
|
212
|
+
return input.compact unless used_namespaces[[input[1].to_s]]
|
213
|
+
[used_namespaces[[input[1].to_s]], input[1], input[2]]
|
158
214
|
end
|
159
215
|
|
160
216
|
end
|
data/lib/savon/version.rb
CHANGED
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 "nori", "~> 1.0"
|
19
19
|
s.add_dependency "httpi", "~> 0.9"
|
20
|
-
s.add_dependency "wasabi", "~>
|
20
|
+
s.add_dependency "wasabi", "~> 2.0"
|
21
21
|
s.add_dependency "akami", "~> 1.0"
|
22
22
|
s.add_dependency "gyoku", ">= 0.4.0"
|
23
23
|
s.add_dependency "nokogiri", ">= 1.4.0"
|
@@ -0,0 +1,52 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<definitions
|
3
|
+
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
4
|
+
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
5
|
+
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
|
6
|
+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
7
|
+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
8
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
9
|
+
xmlns:s="http://www.w3.org/2001/XMLSchema"
|
10
|
+
xmlns:actions="http://example.com/actions"
|
11
|
+
targetNamespace="http://example.com/topLevelNamespace">
|
12
|
+
<types>
|
13
|
+
<s:schema elementFormDefault="qualified" targetNamespace="http://example.com/actions">
|
14
|
+
<s:element name="Save">
|
15
|
+
<s:complexType>
|
16
|
+
<s:sequence>
|
17
|
+
<s:element name="lowerCamel" type="s:string"/>
|
18
|
+
</s:sequence>
|
19
|
+
</s:complexType>
|
20
|
+
</s:element>
|
21
|
+
</s:schema>
|
22
|
+
</types>
|
23
|
+
<message name="SaveSoapIn">
|
24
|
+
<part name="parameters" element="actions:Save"/>
|
25
|
+
</message>
|
26
|
+
<message name="SaveSoapOut">
|
27
|
+
<part name="parameters" element="actions:SaveResponse"/>
|
28
|
+
</message>
|
29
|
+
<portType name="ArticleSoap">
|
30
|
+
<operation name="Save">
|
31
|
+
<input message="actions:SaveSoapIn"/>
|
32
|
+
<output message="actions:SaveSoapOut"/>
|
33
|
+
</operation>
|
34
|
+
</portType>
|
35
|
+
<binding name="ArticleSoap" type="actions:ArticleSoap">
|
36
|
+
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
|
37
|
+
<operation name="Save">
|
38
|
+
<soap:operation soapAction="http://example.com/actions.Save" style="document"/>
|
39
|
+
<input>
|
40
|
+
<soap:body use="literal"/>
|
41
|
+
</input>
|
42
|
+
<output>
|
43
|
+
<soap:body use="literal"/>
|
44
|
+
</output>
|
45
|
+
</operation>
|
46
|
+
</binding>
|
47
|
+
<service name="StudyMDL">
|
48
|
+
<port name="StudyMDLSoap" binding="actions:StudyMDLSoap">
|
49
|
+
<soap:address location="http://example.com:1234/soap"/>
|
50
|
+
</port>
|
51
|
+
</service>
|
52
|
+
</definitions>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<definitions
|
3
|
+
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
4
|
+
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
5
|
+
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
|
6
|
+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
7
|
+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
8
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
9
|
+
xmlns:s="http://www.w3.org/2001/XMLSchema"
|
10
|
+
xmlns:article="http://example.com/article"
|
11
|
+
xmlns:actions="http://example.com/actions"
|
12
|
+
targetNamespace="http://example.com/actions">
|
13
|
+
<types>
|
14
|
+
<s:schema elementFormDefault="qualified" targetNamespace="http://example.com/actions">
|
15
|
+
<s:element name="Save">
|
16
|
+
<s:complexType>
|
17
|
+
<s:sequence>
|
18
|
+
<s:element name="article" type="article:Article"/>
|
19
|
+
</s:sequence>
|
20
|
+
</s:complexType>
|
21
|
+
</s:element>
|
22
|
+
</s:schema>
|
23
|
+
<s:schema elementFormDefault="qualified" targetNamespace="http://example.com/article">
|
24
|
+
<s:complexType name="Article">
|
25
|
+
<s:sequence>
|
26
|
+
<s:element minOccurs="0" name="Author" type="s:string"/>
|
27
|
+
<s:element minOccurs="0" name="Title" type="s:string"/>
|
28
|
+
</s:sequence>
|
29
|
+
</s:complexType>
|
30
|
+
</s:schema>
|
31
|
+
</types>
|
32
|
+
<message name="SaveSoapIn">
|
33
|
+
<part name="parameters" element="actions:Save"/>
|
34
|
+
</message>
|
35
|
+
<message name="SaveSoapOut">
|
36
|
+
<part name="parameters" element="actions:SaveResponse"/>
|
37
|
+
</message>
|
38
|
+
<portType name="ArticleSoap">
|
39
|
+
<operation name="Save">
|
40
|
+
<input message="actions:SaveSoapIn"/>
|
41
|
+
<output message="actions:SaveSoapOut"/>
|
42
|
+
</operation>
|
43
|
+
</portType>
|
44
|
+
<binding name="ArticleSoap" type="actions:ArticleSoap">
|
45
|
+
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
|
46
|
+
<operation name="Save">
|
47
|
+
<soap:operation soapAction="http://example.com/actions.Save" style="document"/>
|
48
|
+
<input>
|
49
|
+
<soap:body use="literal"/>
|
50
|
+
</input>
|
51
|
+
<output>
|
52
|
+
<soap:body use="literal"/>
|
53
|
+
</output>
|
54
|
+
</operation>
|
55
|
+
</binding>
|
56
|
+
<service name="StudyMDL">
|
57
|
+
<port name="StudyMDLSoap" binding="actions:StudyMDLSoap">
|
58
|
+
<soap:address location="http://example.com:1234/soap"/>
|
59
|
+
</port>
|
60
|
+
</service>
|
61
|
+
</definitions>
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<definitions
|
3
|
+
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
4
|
+
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
5
|
+
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
|
6
|
+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
7
|
+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
8
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
9
|
+
xmlns:s="http://www.w3.org/2001/XMLSchema"
|
10
|
+
xmlns:article="http://example.com/article"
|
11
|
+
xmlns:actions="http://example.com/actions"
|
12
|
+
targetNamespace="http://example.com/actions">
|
13
|
+
<types>
|
14
|
+
<s:schema elementFormDefault="qualified" targetNamespace="http://example.com/actions">
|
15
|
+
<s:element name="Save">
|
16
|
+
<s:complexType>
|
17
|
+
<s:sequence>
|
18
|
+
<s:element name="article" type="s:string"/>
|
19
|
+
</s:sequence>
|
20
|
+
</s:complexType>
|
21
|
+
</s:element>
|
22
|
+
<s:element name="Get">
|
23
|
+
<s:complexType>
|
24
|
+
<s:sequence>
|
25
|
+
<s:element name="articleId" type="s:long"/>
|
26
|
+
</s:sequence>
|
27
|
+
</s:complexType>
|
28
|
+
</s:element>
|
29
|
+
</s:schema>
|
30
|
+
</types>
|
31
|
+
<message name="SaveSoapIn">
|
32
|
+
<part name="parameters" element="actions:Save"/>
|
33
|
+
</message>
|
34
|
+
<message name="SaveSoapOut">
|
35
|
+
<part name="parameters" element="actions:SaveResponse"/>
|
36
|
+
</message>
|
37
|
+
<portType name="ArticleSoap">
|
38
|
+
<operation name="Save">
|
39
|
+
<input message="actions:SaveSoapIn"/>
|
40
|
+
<output message="actions:SaveSoapOut"/>
|
41
|
+
</operation>
|
42
|
+
</portType>
|
43
|
+
<binding name="ArticleSoap" type="actions:ArticleSoap">
|
44
|
+
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
|
45
|
+
<operation name="Save">
|
46
|
+
<soap:operation soapAction="http://example.com/actions.Save" style="document"/>
|
47
|
+
<input>
|
48
|
+
<soap:body use="literal"/>
|
49
|
+
</input>
|
50
|
+
<output>
|
51
|
+
<soap:body use="literal"/>
|
52
|
+
</output>
|
53
|
+
</operation>
|
54
|
+
</binding>
|
55
|
+
<service name="StudyMDL">
|
56
|
+
<port name="StudyMDLSoap" binding="actions:StudyMDLSoap">
|
57
|
+
<soap:address location="http://example.com:1234/soap"/>
|
58
|
+
</port>
|
59
|
+
</service>
|
60
|
+
</definitions>
|
data/spec/savon/client_spec.rb
CHANGED
@@ -84,7 +84,7 @@ describe Savon::Client do
|
|
84
84
|
|
85
85
|
context "with a single argument (Symbol)" do
|
86
86
|
it "should set the input tag to result in <getUser>" do
|
87
|
-
client.request(:get_user) { soap.input.should == [:getUser, {}] }
|
87
|
+
client.request(:get_user) { soap.input.should == [nil, :getUser, {}] }
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should set the target namespace with the default identifier" do
|
@@ -95,7 +95,7 @@ describe Savon::Client do
|
|
95
95
|
end
|
96
96
|
|
97
97
|
it "should not set the target namespace if soap.namespace was set to nil" do
|
98
|
-
namespace = "http://v1_0.ws.auth.order.example.com/"
|
98
|
+
namespace = 'wsdl="http://v1_0.ws.auth.order.example.com/"'
|
99
99
|
HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
|
100
100
|
|
101
101
|
client.request(:get_user) { soap.namespace = nil }
|
@@ -104,13 +104,13 @@ describe Savon::Client do
|
|
104
104
|
|
105
105
|
context "with a single argument (String)" do
|
106
106
|
it "should set the input tag to result in <get_user>" do
|
107
|
-
client.request("get_user") { soap.input.should == [:get_user, {}] }
|
107
|
+
client.request("get_user") { soap.input.should == [nil, :get_user, {}] }
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
111
|
context "with a Symbol and a Hash" do
|
112
112
|
it "should set the input tag to result in <getUser active='true'>" do
|
113
|
-
client.request(:get_user, :active => true) { soap.input.should == [:getUser, { :active => true }] }
|
113
|
+
client.request(:get_user, :active => true) { soap.input.should == [nil, :getUser, { :active => true }] }
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -127,7 +127,7 @@ describe Savon::Client do
|
|
127
127
|
end
|
128
128
|
|
129
129
|
it "should not set the target namespace if soap.namespace was set to nil" do
|
130
|
-
namespace = "http://v1_0.ws.auth.order.example.com/"
|
130
|
+
namespace = 'xmlns:v1="http://v1_0.ws.auth.order.example.com/"'
|
131
131
|
HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
|
132
132
|
|
133
133
|
client.request(:v1, :get_user) { soap.namespace = nil }
|
@@ -261,6 +261,107 @@ describe Savon::Client do
|
|
261
261
|
end
|
262
262
|
end
|
263
263
|
|
264
|
+
context "when the WSDL specifies multiple namespaces" do
|
265
|
+
before do
|
266
|
+
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:multiple_namespaces)))
|
267
|
+
HTTPI.stubs(:post).returns(new_response)
|
268
|
+
end
|
269
|
+
|
270
|
+
it "qualifies each element with the appropriate namespace" do
|
271
|
+
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
272
|
+
xml = Nokogiri::XML(value)
|
273
|
+
|
274
|
+
title = xml.at_xpath(
|
275
|
+
".//actions:Save/actions:article/article:Title/text()",
|
276
|
+
"article" => "http://example.com/article",
|
277
|
+
"actions" => "http://example.com/actions").to_s
|
278
|
+
author = xml.at_xpath(
|
279
|
+
".//actions:Save/actions:article/article:Author/text()",
|
280
|
+
"article" => "http://example.com/article",
|
281
|
+
"actions" => "http://example.com/actions").to_s
|
282
|
+
|
283
|
+
title == "Hamlet" && author == "Shakespeare"
|
284
|
+
end
|
285
|
+
|
286
|
+
client.request :save do
|
287
|
+
soap.body = { :article => { "Title" => "Hamlet", "Author" => "Shakespeare" } }
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it "still sends nil as xsi:nil as in the non-namespaced case" do
|
292
|
+
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
293
|
+
xml = Nokogiri::XML(value)
|
294
|
+
|
295
|
+
attribute = xml.at_xpath(".//article:Title/@xsi:nil",
|
296
|
+
"xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
297
|
+
"article" => "http://example.com/article").to_s
|
298
|
+
|
299
|
+
attribute == "true"
|
300
|
+
end
|
301
|
+
|
302
|
+
client.request(:save) { soap.body = { :article => { "Title" => nil } } }
|
303
|
+
end
|
304
|
+
|
305
|
+
it "translates between symbol :save and string 'Save'" do
|
306
|
+
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
307
|
+
xml = Nokogiri::XML(value)
|
308
|
+
!!xml.at_xpath(".//actions:Save", "actions" => "http://example.com/actions")
|
309
|
+
end
|
310
|
+
|
311
|
+
client.request :save do
|
312
|
+
soap.body = { :article => { :title => "Hamlet", :author => "Shakespeare" } }
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
it "qualifies Save with the appropriate namespace" do
|
317
|
+
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
318
|
+
xml = Nokogiri::XML(value)
|
319
|
+
!!xml.at_xpath(".//actions:Save", "actions" => "http://example.com/actions")
|
320
|
+
end
|
321
|
+
|
322
|
+
client.request "Save" do
|
323
|
+
soap.body = { :article => { :title => "Hamlet", :author => "Shakespeare" } }
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context "when the WSDL has a lowerCamel name" do
|
329
|
+
before do
|
330
|
+
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:lower_camel)))
|
331
|
+
HTTPI.stubs(:post).returns(new_response)
|
332
|
+
end
|
333
|
+
|
334
|
+
it "appends namespace when name is specified explicitly" do
|
335
|
+
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
336
|
+
xml = Nokogiri::XML(value)
|
337
|
+
!!xml.at_xpath(".//actions:Save/actions:lowerCamel", "actions" => "http://example.com/actions")
|
338
|
+
end
|
339
|
+
|
340
|
+
client.request("Save") { soap.body = { 'lowerCamel' => 'theValue' } }
|
341
|
+
end
|
342
|
+
|
343
|
+
it "still appends namespace when converting from symbol" do
|
344
|
+
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
345
|
+
xml = Nokogiri::XML(value)
|
346
|
+
!!xml.at_xpath(".//actions:Save/actions:lowerCamel", "actions" => "http://example.com/actions")
|
347
|
+
end
|
348
|
+
|
349
|
+
client.request("Save") { soap.body = { :lower_camel => 'theValue' } }
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "with multiple types" do
|
354
|
+
before do
|
355
|
+
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:multiple_types)))
|
356
|
+
HTTPI.stubs(:post).returns(new_response)
|
357
|
+
end
|
358
|
+
|
359
|
+
it "does not blow up" do
|
360
|
+
HTTPI::Request.any_instance.expects(:body=).with { |value| value.include?("Save") }
|
361
|
+
client.request(:save) { soap.body = {} }
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
264
365
|
context "without a WSDL document" do
|
265
366
|
let(:client) do
|
266
367
|
Savon::Client.new do
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Savon::SOAP::Request do
|
4
4
|
let(:request) { Savon::SOAP::Request.new HTTPI::Request.new, soap }
|
5
|
-
let(:soap) { Savon::SOAP::XML.new Endpoint.soap, :get_user, :id => 1 }
|
5
|
+
let(:soap) { Savon::SOAP::XML.new Endpoint.soap, [nil, :get_user, {}], :id => 1 }
|
6
6
|
|
7
7
|
it "contains the content type for each supported SOAP version" do
|
8
8
|
content_type = Savon::SOAP::Request::ContentType
|
data/spec/savon/soap/xml_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Savon::SOAP::XML do
|
4
|
-
let(:xml) { Savon::SOAP::XML.new Endpoint.soap, :authenticate, :id => 1 }
|
4
|
+
let(:xml) { Savon::SOAP::XML.new Endpoint.soap, [nil, :authenticate, {}], :id => 1 }
|
5
5
|
|
6
6
|
describe ".new" do
|
7
7
|
it "should accept an endpoint, an input tag and a SOAP body" do
|
8
|
-
xml = Savon::SOAP::XML.new Endpoint.soap, :authentication, :id => 1
|
8
|
+
xml = Savon::SOAP::XML.new Endpoint.soap, [nil, :authentication, {}], :id => 1
|
9
9
|
|
10
10
|
xml.endpoint.should == Endpoint.soap
|
11
|
-
xml.input.should == :authentication
|
11
|
+
xml.input.should == [nil, :authentication, {}]
|
12
12
|
xml.body.should == { :id => 1 }
|
13
13
|
end
|
14
14
|
end
|
@@ -218,7 +218,7 @@ describe Savon::SOAP::XML do
|
|
218
218
|
|
219
219
|
context "with :element_form_default set to :qualified and a :namespace" do
|
220
220
|
let :xml do
|
221
|
-
Savon::SOAP::XML.new Endpoint.soap, :authenticate, :user => { :id => 1, ":noNamespace" => true }
|
221
|
+
Savon::SOAP::XML.new Endpoint.soap, [nil, :authenticate, {}], :user => { :id => 1, ":noNamespace" => true }
|
222
222
|
end
|
223
223
|
|
224
224
|
it "should namespace the default elements" do
|
@@ -246,28 +246,28 @@ describe Savon::SOAP::XML do
|
|
246
246
|
|
247
247
|
context "with a simple input tag (Symbol)" do
|
248
248
|
it "should just add the input tag" do
|
249
|
-
xml.input = :simple
|
249
|
+
xml.input = [nil, :simple, {}]
|
250
250
|
xml.to_xml.should include('<simple><id>1</id></simple>')
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
254
|
context "with a simple input tag (Array)" do
|
255
255
|
it "should just add the input tag" do
|
256
|
-
xml.input = :simple
|
256
|
+
xml.input = [nil, :simple, {}]
|
257
257
|
xml.to_xml.should include('<simple><id>1</id></simple>')
|
258
258
|
end
|
259
259
|
end
|
260
260
|
|
261
261
|
context "with an input tag and a namespace Hash (Array)" do
|
262
262
|
it "should contain the input tag with namespaces" do
|
263
|
-
xml.input = [:getUser, { "active" => true }]
|
263
|
+
xml.input = [nil, :getUser, { "active" => true }]
|
264
264
|
xml.to_xml.should include('<getUser active="true"><id>1</id></getUser>')
|
265
265
|
end
|
266
266
|
end
|
267
267
|
|
268
268
|
context "with a prefixed input tag (Array)" do
|
269
269
|
it "should contain a prefixed input tag" do
|
270
|
-
xml.input = [:wsdl, :getUser]
|
270
|
+
xml.input = [:wsdl, :getUser, {}]
|
271
271
|
xml.to_xml.should include('<wsdl:getUser><id>1</id></wsdl:getUser>')
|
272
272
|
end
|
273
273
|
end
|
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
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 6
|
10
|
+
version: 0.9.6
|
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-07-
|
18
|
+
date: 2011-07-07 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: builder
|
@@ -71,11 +71,11 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - ~>
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
hash:
|
74
|
+
hash: 3
|
75
75
|
segments:
|
76
|
-
-
|
76
|
+
- 2
|
77
77
|
- 0
|
78
|
-
version: "
|
78
|
+
version: "2.0"
|
79
79
|
type: :runtime
|
80
80
|
version_requirements: *id004
|
81
81
|
- !ruby/object:Gem::Dependency
|
@@ -245,6 +245,9 @@ files:
|
|
245
245
|
- spec/fixtures/response/soap_fault.xml
|
246
246
|
- spec/fixtures/response/soap_fault12.xml
|
247
247
|
- spec/fixtures/wsdl/authentication.xml
|
248
|
+
- spec/fixtures/wsdl/lower_camel.xml
|
249
|
+
- spec/fixtures/wsdl/multiple_namespaces.xml
|
250
|
+
- spec/fixtures/wsdl/multiple_types.xml
|
248
251
|
- spec/savon/client_spec.rb
|
249
252
|
- spec/savon/core_ext/object_spec.rb
|
250
253
|
- spec/savon/core_ext/string_spec.rb
|