savon 0.9.10 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +34 -0
- data/README.md +1 -1
- data/lib/savon/client.rb +30 -3
- data/lib/savon/soap/request.rb +14 -1
- data/lib/savon/soap/xml.rb +30 -9
- data/lib/savon/version.rb +1 -1
- data/savon.gemspec +2 -2
- data/spec/savon/client_spec.rb +30 -7
- data/spec/savon/soap/request_spec.rb +22 -10
- data/spec/savon/soap/xml_spec.rb +47 -17
- metadata +9 -9
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
## 0.9.11 (2012-06-06)
|
2
|
+
|
3
|
+
* Feature: [#264](https://github.com/rubiii/savon/pull/264) - Thanks to @hoverlover, Savon and Akami now support
|
4
|
+
signed messages through WSSE.
|
5
|
+
|
6
|
+
* Fix: [#275](https://github.com/rubiii/savon/pull/275) - Add namespaces to keys in both the SOAP body hash as well
|
7
|
+
as any keys specified in a :order! Array instead of having to define them manually.
|
8
|
+
|
9
|
+
* Fix: [#257](https://github.com/rubiii/savon/issues/257) - Add ability to accept and send multiple cookies.
|
10
|
+
|
11
|
+
* Improvement: [#277](https://github.com/rubiii/savon/pull/277) automatically namespace the SOAP input tag.
|
12
|
+
Here's an example from the pull request:
|
13
|
+
|
14
|
+
``` ruby
|
15
|
+
client.request :authenticate
|
16
|
+
```
|
17
|
+
|
18
|
+
Note the automatic namespace identifier on the authenticate element, as well as the proper namespace inclusion
|
19
|
+
in the document:
|
20
|
+
|
21
|
+
``` xml
|
22
|
+
<env:Envelope
|
23
|
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
24
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
25
|
+
xmlns:tns="http://v1_0.ws.auth.order.example.com/"
|
26
|
+
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
|
27
|
+
|
28
|
+
<tns:authenticate>
|
29
|
+
<tns:user>username</tns:user>
|
30
|
+
<tns:password>password</tns:password>
|
31
|
+
</tns:authenticate>
|
32
|
+
</env:Envelope>
|
33
|
+
```
|
34
|
+
|
1
35
|
## 0.9.10 (2012-06-06)
|
2
36
|
|
3
37
|
* Feature: [#289](https://github.com/rubiii/savon/pull/289) - Allow the SOAP envelope header to be set as a String.
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Introduction
|
|
22
22
|
require "savon"
|
23
23
|
|
24
24
|
# create a client for your SOAP service
|
25
|
-
client = Savon
|
25
|
+
client = Savon.client("http://service.example.com?wsdl")
|
26
26
|
|
27
27
|
client.wsdl.soap_actions
|
28
28
|
# => [:create_user, :get_user, :get_all_users]
|
data/lib/savon/client.rb
CHANGED
@@ -83,6 +83,11 @@ module Savon
|
|
83
83
|
|
84
84
|
response = SOAP::Request.new(config, http, soap).response
|
85
85
|
set_cookie response.http.headers
|
86
|
+
|
87
|
+
if wsse.verify_response
|
88
|
+
WSSE::VerifySignature.new(response.http.body).verify!
|
89
|
+
end
|
90
|
+
|
86
91
|
response
|
87
92
|
end
|
88
93
|
|
@@ -96,7 +101,19 @@ module Savon
|
|
96
101
|
|
97
102
|
# Passes a cookie from the last request +headers+ to the next one.
|
98
103
|
def set_cookie(headers)
|
99
|
-
|
104
|
+
if headers["Set-Cookie"]
|
105
|
+
@cookies ||= {}
|
106
|
+
#handle single or multiple Set-Cookie Headers as returned by Rack::Utils::HeaderHash in HTTPI
|
107
|
+
set_cookies = [headers["Set-Cookie"]].flatten
|
108
|
+
set_cookies.each do |set_cookie|
|
109
|
+
# use the cookie name as the key to the hash to allow for cookie updates and seperation
|
110
|
+
# set the value to name=value (for easy joining), stopping when we hit the Cookie options
|
111
|
+
@cookies[set_cookie.split('=').first] = set_cookie.split(';').first
|
112
|
+
end
|
113
|
+
|
114
|
+
http.headers["Cookie"] = @cookies.values.join(';')
|
115
|
+
end
|
116
|
+
|
100
117
|
end
|
101
118
|
|
102
119
|
# Expects an Array of +args+ and returns an Array containing the namespace (might be +nil+),
|
@@ -112,8 +129,6 @@ module Savon
|
|
112
129
|
# Expects an Array of +args+ to preconfigure the system.
|
113
130
|
def preconfigure(args)
|
114
131
|
soap.endpoint = wsdl.endpoint
|
115
|
-
soap.namespace_identifier = args[0]
|
116
|
-
soap.namespace = wsdl.namespace
|
117
132
|
soap.element_form_default = wsdl.element_form_default
|
118
133
|
|
119
134
|
body = args[2].delete(:body)
|
@@ -129,6 +144,18 @@ module Savon
|
|
129
144
|
|
130
145
|
soap_action = args[2].delete(:soap_action) || args[1]
|
131
146
|
set_soap_action soap_action
|
147
|
+
|
148
|
+
if wsdl.document? && (operation = wsdl.operations[args[1]]) && operation[:namespace_identifier]
|
149
|
+
soap.namespace_identifier = operation[:namespace_identifier].to_sym
|
150
|
+
soap.namespace = wsdl.parser.namespaces[soap.namespace_identifier.to_s]
|
151
|
+
|
152
|
+
# Override nil namespace with one specified in WSDL
|
153
|
+
args[0] = soap.namespace_identifier unless args[0]
|
154
|
+
else
|
155
|
+
soap.namespace_identifier = args[0]
|
156
|
+
soap.namespace = wsdl.namespace
|
157
|
+
end
|
158
|
+
|
132
159
|
set_soap_input *args
|
133
160
|
end
|
134
161
|
|
data/lib/savon/soap/request.rb
CHANGED
@@ -41,7 +41,20 @@ module Savon
|
|
41
41
|
# Configures a given +http+ from the +soap+ object.
|
42
42
|
def configure(http)
|
43
43
|
http.url = soap.endpoint
|
44
|
-
|
44
|
+
|
45
|
+
if soap.signature?
|
46
|
+
# First generate the document so that Signature can digest sections
|
47
|
+
soap.wsse.signature.document = soap.to_xml(true)
|
48
|
+
|
49
|
+
# Then re-generate the document so that Signature can sign the digest
|
50
|
+
soap.wsse.signature.document = soap.to_xml(true)
|
51
|
+
|
52
|
+
# The third time we generate the document, we should have a signature
|
53
|
+
http.body = soap.to_xml(true)
|
54
|
+
else
|
55
|
+
http.body = soap.to_xml
|
56
|
+
end
|
57
|
+
|
45
58
|
http.headers["Content-Type"] = ContentType[soap.version]
|
46
59
|
http.headers["Content-Length"] = soap.to_xml.bytesize.to_s
|
47
60
|
http
|
data/lib/savon/soap/xml.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "builder"
|
2
2
|
require "gyoku"
|
3
|
+
require "rexml/document"
|
3
4
|
require "nori"
|
4
5
|
|
5
6
|
require "savon/soap"
|
@@ -24,12 +25,9 @@ module Savon
|
|
24
25
|
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
|
25
26
|
}
|
26
27
|
|
27
|
-
#
|
28
|
-
def initialize(config
|
28
|
+
# Expects a +config+ object.
|
29
|
+
def initialize(config)
|
29
30
|
self.config = config
|
30
|
-
self.endpoint = endpoint if endpoint
|
31
|
-
self.input = input if input
|
32
|
-
self.body = body if body
|
33
31
|
end
|
34
32
|
|
35
33
|
attr_accessor :config
|
@@ -123,6 +121,10 @@ module Savon
|
|
123
121
|
# Accessor for the <tt>Savon::WSSE</tt> object.
|
124
122
|
attr_accessor :wsse
|
125
123
|
|
124
|
+
def signature?
|
125
|
+
wsse.respond_to?(:signature?) && wsse.signature?
|
126
|
+
end
|
127
|
+
|
126
128
|
# Returns the SOAP request encoding. Defaults to "UTF-8".
|
127
129
|
def encoding
|
128
130
|
@encoding ||= "UTF-8"
|
@@ -152,14 +154,23 @@ module Savon
|
|
152
154
|
attr_writer :xml
|
153
155
|
|
154
156
|
# Returns the XML for a SOAP request.
|
155
|
-
def to_xml
|
157
|
+
def to_xml(clear_cache = false)
|
158
|
+
if clear_cache
|
159
|
+
@xml = nil
|
160
|
+
@header_for_xml = nil
|
161
|
+
end
|
162
|
+
|
156
163
|
@xml ||= tag(builder, :Envelope, complete_namespaces) do |xml|
|
157
164
|
tag(xml, :Header) { xml << header_for_xml } unless header_for_xml.empty?
|
158
165
|
|
166
|
+
# TODO: Maybe there should be some sort of plugin architecture where
|
167
|
+
# classes like WSSE::Signature can hook into this process.
|
168
|
+
body_attributes = (signature? ? wsse.signature.body_attributes : {})
|
169
|
+
|
159
170
|
if input.nil?
|
160
|
-
tag(xml, :Body)
|
171
|
+
tag(xml, :Body, body_attributes)
|
161
172
|
else
|
162
|
-
tag(xml, :Body) { xml.tag!(*add_namespace_to_input) { xml << body_to_xml } }
|
173
|
+
tag(xml, :Body, body_attributes) { xml.tag!(*add_namespace_to_input) { xml << body_to_xml } }
|
163
174
|
end
|
164
175
|
end
|
165
176
|
end
|
@@ -203,7 +214,8 @@ module Savon
|
|
203
214
|
# Returns the SOAP body as an XML String.
|
204
215
|
def body_to_xml
|
205
216
|
return body.to_s unless body.kind_of? Hash
|
206
|
-
|
217
|
+
body_to_xml = element_form_default == :qualified ? add_namespaces_to_body(body) : body
|
218
|
+
Gyoku.xml body_to_xml, :element_form_default => element_form_default, :namespace => namespace_identifier
|
207
219
|
end
|
208
220
|
|
209
221
|
def add_namespaces_to_body(hash, path = [input[1].to_s])
|
@@ -221,6 +233,7 @@ module Savon
|
|
221
233
|
add_namespaces_to_body(value, types[newpath] ? [types[newpath]] : newpath)
|
222
234
|
)
|
223
235
|
else
|
236
|
+
add_namespaces_to_values(value, path) if key == :order!
|
224
237
|
newhash.merge(key => value)
|
225
238
|
end
|
226
239
|
end
|
@@ -231,6 +244,14 @@ module Savon
|
|
231
244
|
[used_namespaces[[input[1].to_s]], input[1], input[2]]
|
232
245
|
end
|
233
246
|
|
247
|
+
def add_namespaces_to_values(values, path)
|
248
|
+
values.collect! { |value|
|
249
|
+
camelcased_value = Gyoku::XMLKey.create(value)
|
250
|
+
namespace_path = path + [camelcased_value.to_s]
|
251
|
+
namespace = used_namespaces[namespace_path]
|
252
|
+
"#{namespace.blank? ? '' : namespace + ":"}#{camelcased_value}"
|
253
|
+
}
|
254
|
+
end
|
234
255
|
end
|
235
256
|
end
|
236
257
|
end
|
data/lib/savon/version.rb
CHANGED
data/savon.gemspec
CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_dependency "builder", ">= 2.1.2"
|
19
19
|
s.add_dependency "nori", "~> 1.1"
|
20
20
|
s.add_dependency "httpi", "~> 0.9"
|
21
|
-
s.add_dependency "wasabi", "~> 2.
|
22
|
-
s.add_dependency "akami", "~> 1.
|
21
|
+
s.add_dependency "wasabi", "~> 2.2"
|
22
|
+
s.add_dependency "akami", "~> 1.1"
|
23
23
|
s.add_dependency "gyoku", ">= 0.4.0"
|
24
24
|
s.add_dependency "nokogiri", ">= 1.4.0"
|
25
25
|
|
data/spec/savon/client_spec.rb
CHANGED
@@ -100,6 +100,24 @@ describe Savon::Client do
|
|
100
100
|
|
101
101
|
client.request(:get_user) { soap.namespace = nil }
|
102
102
|
end
|
103
|
+
|
104
|
+
context "when the wsdl's operation namespace identifier matches a document identifier" do
|
105
|
+
before do
|
106
|
+
client.wsdl.operations[:authenticate][:namespace_identifier] = "tns"
|
107
|
+
end
|
108
|
+
|
109
|
+
it "sets the soap's namespace identifier to the matching operation's namespace identifier" do
|
110
|
+
client.request(:authenticate) { soap.namespace_identifier.should == :tns }
|
111
|
+
end
|
112
|
+
|
113
|
+
it "sets the soap's namespace to the namspace matching the identifier" do
|
114
|
+
client.request(:authenticate) { soap.namespace.should == "http://v1_0.ws.auth.order.example.com/" }
|
115
|
+
end
|
116
|
+
|
117
|
+
it "sets the input tag to result in <tns:authenticate>" do
|
118
|
+
client.request(:authenticate) { soap.input.should == [:tns, :authenticate, {}] }
|
119
|
+
end
|
120
|
+
end
|
103
121
|
end
|
104
122
|
|
105
123
|
context "with a single argument (String)" do
|
@@ -206,7 +224,7 @@ describe Savon::Client do
|
|
206
224
|
client.http.headers.expects(:[]=).with("Cookie", anything).never
|
207
225
|
client.http.headers.stubs(:[]=).with("SOAPAction", '"authenticate"')
|
208
226
|
client.http.headers.stubs(:[]=).with("Content-Type", "text/xml;charset=UTF-8")
|
209
|
-
client.http.headers.stubs(:[]=).with("Content-Length", "
|
227
|
+
client.http.headers.stubs(:[]=).with("Content-Length", "383")
|
210
228
|
|
211
229
|
client.request :authenticate
|
212
230
|
end
|
@@ -215,17 +233,22 @@ describe Savon::Client do
|
|
215
233
|
context "#request with a Set-Cookie response header" do
|
216
234
|
before do
|
217
235
|
HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:authentication)))
|
218
|
-
HTTPI.stubs(:post).returns(new_response(:headers => { "Set-Cookie" => "some-cookie" }))
|
236
|
+
HTTPI.stubs(:post).returns(new_response(:headers => { "Set-Cookie" => "some-cookie=choc-chip; Path=/; HttpOnly" }))
|
219
237
|
end
|
220
238
|
|
221
239
|
it "should set the Cookie header for the next request" do
|
222
|
-
client.
|
223
|
-
client.http.headers
|
224
|
-
|
225
|
-
client.http.headers.stubs(:[]=).with("Content-Length", "384")
|
240
|
+
client.request :authenticate
|
241
|
+
client.http.headers["Cookie"].should == "some-cookie=choc-chip"
|
242
|
+
end
|
226
243
|
|
244
|
+
it "should set additional cookies when new cookies are found in subsequent requests" do
|
227
245
|
client.request :authenticate
|
246
|
+
HTTPI.stubs(:post).returns(new_response(:headers => { "Set-Cookie" => "second-cookie=oatmeal; Path=/; HttpOnly" }))
|
247
|
+
client.request :nibble
|
248
|
+
|
249
|
+
client.http.headers["Cookie"].should == "some-cookie=choc-chip;second-cookie=oatmeal"
|
228
250
|
end
|
251
|
+
|
229
252
|
end
|
230
253
|
|
231
254
|
context "with a remote WSDL document" do
|
@@ -382,7 +405,7 @@ describe Savon::Client do
|
|
382
405
|
|
383
406
|
it "should namespaces each Array item as expected" do
|
384
407
|
HTTPI::Request.any_instance.expects(:body=).with do |value|
|
385
|
-
value.include?("<ins0:cartItems><ins0:CartItem>") && value.include?("<
|
408
|
+
value.include?("<ins0:cartItems><ins0:CartItem>") && value.include?("<tns:ItemID>SKU-TEST</tns:ItemID>")
|
386
409
|
end
|
387
410
|
|
388
411
|
address = { "Address1" => "888 6th Ave", "Address2" => nil, "City" => "New York", "State" => "NY", "Zip5" => "10001", "Zip4" => nil }
|
@@ -1,11 +1,23 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Savon::SOAP::Request do
|
4
|
-
|
4
|
+
|
5
|
+
let(:soap_request) { Savon::SOAP::Request.new(config, http_request, soap_xml) }
|
5
6
|
let(:http_request) { HTTPI::Request.new }
|
6
|
-
let(:soap) { Savon::SOAP::XML.new config, Endpoint.soap, [nil, :get_user, {}], :id => 1 }
|
7
7
|
let(:config) { Savon::Config.default }
|
8
8
|
|
9
|
+
def soap_xml(*args)
|
10
|
+
@soap_xml ||= soap_xml!(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def soap_xml!(endpoint = nil, input = nil, body = nil)
|
14
|
+
soap = Savon::SOAP::XML.new(config)
|
15
|
+
soap.endpoint = endpoint || Endpoint.soap
|
16
|
+
soap.input = input || [nil, :get_user, {}]
|
17
|
+
soap.body = body || { :id => 1 }
|
18
|
+
soap
|
19
|
+
end
|
20
|
+
|
9
21
|
it "contains the content type for each supported SOAP version" do
|
10
22
|
content_type = Savon::SOAP::Request::ContentType
|
11
23
|
content_type[1].should == "text/xml;charset=UTF-8"
|
@@ -15,18 +27,18 @@ describe Savon::SOAP::Request do
|
|
15
27
|
describe ".execute" do
|
16
28
|
it "executes a SOAP request and returns the response" do
|
17
29
|
HTTPI.expects(:post).returns(HTTPI::Response.new 200, {}, Fixture.response(:authentication))
|
18
|
-
response = Savon::SOAP::Request.execute config, http_request,
|
30
|
+
response = Savon::SOAP::Request.execute config, http_request, soap_xml
|
19
31
|
response.should be_a(Savon::SOAP::Response)
|
20
32
|
end
|
21
33
|
end
|
22
34
|
|
23
35
|
describe ".new" do
|
24
36
|
it "uses the SOAP endpoint for the request" do
|
25
|
-
soap_request.http.url.should == URI(
|
37
|
+
soap_request.http.url.should == URI(soap_xml.endpoint)
|
26
38
|
end
|
27
39
|
|
28
40
|
it "sets the SOAP body for the request" do
|
29
|
-
soap_request.http.body.should ==
|
41
|
+
soap_request.http.body.should == soap_xml.to_xml
|
30
42
|
end
|
31
43
|
|
32
44
|
it "sets the Content-Type header for SOAP 1.1" do
|
@@ -34,21 +46,21 @@ describe Savon::SOAP::Request do
|
|
34
46
|
end
|
35
47
|
|
36
48
|
it "sets the Content-Type header for SOAP 1.2" do
|
37
|
-
|
49
|
+
soap_xml.version = 2
|
38
50
|
soap_request.http.headers["Content-Type"].should == Savon::SOAP::Request::ContentType[2]
|
39
51
|
end
|
40
52
|
|
41
53
|
it "sets the Content-Length header" do
|
42
|
-
soap_request.http.headers["Content-Length"].should ==
|
54
|
+
soap_request.http.headers["Content-Length"].should == soap_xml.to_xml.length.to_s
|
43
55
|
end
|
44
56
|
|
45
57
|
it "sets the Content-Length header for every request" do
|
46
58
|
http = HTTPI::Request.new
|
47
|
-
soap_request = Savon::SOAP::Request.new(config, http,
|
59
|
+
soap_request = Savon::SOAP::Request.new(config, http, soap_xml)
|
48
60
|
http.headers.should include("Content-Length" => "272")
|
49
61
|
|
50
|
-
|
51
|
-
soap_request = Savon::SOAP::Request.new(config, http,
|
62
|
+
soap_xml = soap_xml!(Endpoint.soap, [nil, :create_user, {}], :id => 123)
|
63
|
+
soap_request = Savon::SOAP::Request.new(config, http, soap_xml)
|
52
64
|
http.headers.should include("Content-Length" => "280")
|
53
65
|
end
|
54
66
|
end
|
data/spec/savon/soap/xml_spec.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Savon::SOAP::XML do
|
4
|
-
let(:xml) { Savon::SOAP::XML.new(config, Endpoint.soap, [nil, :authenticate, {}], :id => 1) }
|
5
|
-
let(:config) { Savon::Config.default }
|
6
|
-
|
7
|
-
describe ".new" do
|
8
|
-
it "should accept an endpoint, an input tag and a SOAP body" do
|
9
|
-
xml = Savon::SOAP::XML.new(config, Endpoint.soap, [nil, :authentication, {}], :id => 1)
|
10
4
|
|
11
|
-
|
12
|
-
|
13
|
-
xml
|
5
|
+
def xml(endpoint = nil, input = nil, body = nil)
|
6
|
+
@xml ||= begin
|
7
|
+
xml = Savon::SOAP::XML.new(config)
|
8
|
+
xml.endpoint = endpoint || Endpoint.soap
|
9
|
+
xml.input = input || [nil, :authenticate, {}]
|
10
|
+
xml.body = body || { :id => 1 }
|
11
|
+
xml
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
15
|
+
let(:config) { Savon::Config.default }
|
16
|
+
|
17
17
|
describe "#input" do
|
18
18
|
it "should set the input tag" do
|
19
19
|
xml.input = :test
|
@@ -260,19 +260,22 @@ describe Savon::SOAP::XML do
|
|
260
260
|
end
|
261
261
|
|
262
262
|
context "with :element_form_default set to :qualified and a :namespace" do
|
263
|
-
|
264
|
-
|
263
|
+
it "should namespace the default elements" do
|
264
|
+
xml = xml(Endpoint.soap, [nil, :authenticate, {}], :user => { :id => 1, ":noNamespace" => true })
|
265
|
+
xml.element_form_default = :qualified
|
266
|
+
xml.namespace_identifier = :wsdl
|
267
|
+
|
268
|
+
xml.to_xml.should include("<wsdl:user>", "<wsdl:id>1</wsdl:id>", "<noNamespace>true</noNamespace>")
|
265
269
|
end
|
270
|
+
end
|
266
271
|
|
272
|
+
context "with :element_form_default set to :unqualified and a :namespace" do
|
267
273
|
it "should namespace the default elements" do
|
268
|
-
xml
|
274
|
+
xml = xml(Endpoint.soap, [nil, :authenticate, {}], :user => { :id => 1, ":noNamespace" => true })
|
275
|
+
xml.element_form_default = :unqualified
|
269
276
|
xml.namespace_identifier = :wsdl
|
270
277
|
|
271
|
-
xml.to_xml.should include(
|
272
|
-
"<wsdl:user>",
|
273
|
-
"<wsdl:id>1</wsdl:id>",
|
274
|
-
"<noNamespace>true</noNamespace>"
|
275
|
-
)
|
278
|
+
xml.to_xml.should include("<user>", "<id>1</id>", "<noNamespace>true</noNamespace>")
|
276
279
|
end
|
277
280
|
end
|
278
281
|
|
@@ -323,5 +326,32 @@ describe Savon::SOAP::XML do
|
|
323
326
|
end
|
324
327
|
end
|
325
328
|
|
329
|
+
describe "#add_namespaces_to_body" do
|
330
|
+
before :each do
|
331
|
+
xml.used_namespaces.merge!({
|
332
|
+
["authenticate", "id"] =>"ns0",
|
333
|
+
["authenticate", "name"] =>"ns1",
|
334
|
+
["authenticate", "name", "firstName"] =>"ns2"
|
335
|
+
})
|
336
|
+
end
|
337
|
+
|
338
|
+
it "adds namespaces" do
|
339
|
+
body = {:id => 1, :name => {:first_name => 'Bob'}}
|
340
|
+
xml.send(:add_namespaces_to_body, body).should == {"ns0:id" => "1", "ns1:name" => {"ns2:firstName" => "Bob"}}
|
341
|
+
end
|
342
|
+
|
343
|
+
it "adds namespaces to order! list" do
|
344
|
+
body = {:id => 1, :name => {:first_name => 'Bob', :order! => [:first_name]}, :order! => [:id, :name]}
|
345
|
+
xml.send(:add_namespaces_to_body, body).should == {
|
346
|
+
"ns0:id" => "1",
|
347
|
+
"ns1:name" => {
|
348
|
+
"ns2:firstName" => "Bob",
|
349
|
+
:order! => ["ns2:firstName"]
|
350
|
+
},
|
351
|
+
:order! => ["ns0:id", "ns1:name"]
|
352
|
+
}
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
326
356
|
end
|
327
357
|
|
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: 45
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 11
|
10
|
+
version: 0.9.11
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel Harrington
|
@@ -69,11 +69,11 @@ dependencies:
|
|
69
69
|
requirements:
|
70
70
|
- - ~>
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
hash:
|
72
|
+
hash: 7
|
73
73
|
segments:
|
74
74
|
- 2
|
75
|
-
-
|
76
|
-
version: "2.
|
75
|
+
- 2
|
76
|
+
version: "2.2"
|
77
77
|
name: wasabi
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
@@ -84,11 +84,11 @@ dependencies:
|
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
hash:
|
87
|
+
hash: 13
|
88
88
|
segments:
|
89
89
|
- 1
|
90
|
-
-
|
91
|
-
version: "1.
|
90
|
+
- 1
|
91
|
+
version: "1.1"
|
92
92
|
name: akami
|
93
93
|
type: :runtime
|
94
94
|
prerelease: false
|