savon 0.9.10 → 0.9.11
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 +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
|