savon 0.8.0.beta.4 → 0.8.0

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.
Files changed (42) hide show
  1. data/CHANGELOG.md +95 -80
  2. data/lib/savon/core_ext/hash.rb +0 -87
  3. data/lib/savon/core_ext/object.rb +0 -10
  4. data/lib/savon/core_ext/string.rb +0 -17
  5. data/lib/savon/soap/xml.rb +28 -8
  6. data/lib/savon/version.rb +1 -1
  7. data/savon.gemspec +3 -1
  8. data/spec/fixtures/response/{xml/another_soap_fault.xml → another_soap_fault.xml} +0 -0
  9. data/spec/fixtures/response/{xml/authentication.xml → authentication.xml} +0 -0
  10. data/spec/fixtures/response/{xml/list.xml → list.xml} +0 -0
  11. data/spec/fixtures/response/{xml/multi_ref.xml → multi_ref.xml} +0 -0
  12. data/spec/fixtures/response/{xml/soap_fault.xml → soap_fault.xml} +0 -0
  13. data/spec/fixtures/response/{xml/soap_fault12.xml → soap_fault12.xml} +0 -0
  14. data/spec/fixtures/wsdl/{xml/authentication.xml → authentication.xml} +0 -0
  15. data/spec/fixtures/wsdl/{xml/geotrust.xml → geotrust.xml} +0 -0
  16. data/spec/fixtures/wsdl/{xml/namespaced_actions.xml → namespaced_actions.xml} +0 -0
  17. data/spec/fixtures/wsdl/{xml/no_namespace.xml → no_namespace.xml} +0 -0
  18. data/spec/savon/client_spec.rb +8 -8
  19. data/spec/savon/core_ext/hash_spec.rb +0 -126
  20. data/spec/savon/core_ext/object_spec.rb +0 -15
  21. data/spec/savon/core_ext/string_spec.rb +0 -22
  22. data/spec/savon/http/error_spec.rb +1 -1
  23. data/spec/savon/soap/fault_spec.rb +4 -4
  24. data/spec/savon/soap/request_spec.rb +1 -1
  25. data/spec/savon/soap/response_spec.rb +6 -5
  26. data/spec/savon/soap/xml_spec.rb +33 -5
  27. data/spec/savon/wsdl/document_spec.rb +3 -3
  28. data/spec/savon/wsdl/parser_spec.rb +1 -1
  29. data/spec/savon/wsdl/request_spec.rb +1 -1
  30. data/spec/spec_helper.rb +3 -9
  31. data/spec/support/fixture.rb +37 -0
  32. metadata +56 -39
  33. data/lib/savon/core_ext/array.rb +0 -45
  34. data/lib/savon/core_ext/datetime.rb +0 -19
  35. data/lib/savon/core_ext/symbol.rb +0 -16
  36. data/spec/fixtures/gzip/gzip_response_fixture.rb +0 -7
  37. data/spec/fixtures/response/response_fixture.rb +0 -40
  38. data/spec/fixtures/wsdl/wsdl_fixture.rb +0 -43
  39. data/spec/fixtures/wsdl/wsdl_fixture.yml +0 -42
  40. data/spec/savon/core_ext/array_spec.rb +0 -49
  41. data/spec/savon/core_ext/datetime_spec.rb +0 -21
  42. data/spec/savon/core_ext/symbol_spec.rb +0 -12
@@ -1,5 +1,3 @@
1
- require "savon/core_ext/datetime"
2
-
3
1
  module Savon
4
2
  module CoreExt
5
3
  module Object
@@ -9,14 +7,6 @@ module Savon
9
7
  respond_to?(:empty?) ? empty? : !self
10
8
  end unless defined? blank?
11
9
 
12
- # Returns the Object as a SOAP request compliant value.
13
- def to_soap_value
14
- return to_s unless respond_to? :to_datetime
15
- to_datetime.to_soap_value
16
- end
17
-
18
- alias_method :to_soap_value!, :to_soap_value
19
-
20
10
  end
21
11
  end
22
12
  end
@@ -1,5 +1,3 @@
1
- require "cgi"
2
-
3
1
  require "savon/soap"
4
2
 
5
3
  module Savon
@@ -52,21 +50,6 @@ module Savon
52
50
  self
53
51
  end
54
52
 
55
- # Returns the Object as a SOAP request compliant key.
56
- def to_soap_key
57
- self[-1, 1] == "!" ? chop : self
58
- end
59
-
60
- # Returns the String as a SOAP value. Escapes special characters for XML.
61
- def to_soap_value
62
- CGI.escapeHTML self
63
- end
64
-
65
- # Convert the String into a SOAP value without escaping special characters.
66
- def to_soap_value!
67
- self
68
- end
69
-
70
53
  end
71
54
  end
72
55
  end
@@ -1,5 +1,7 @@
1
1
  require "builder"
2
2
  require "crack/xml"
3
+ require "gyoku"
4
+
3
5
  require "savon/soap"
4
6
  require "savon/core_ext/hash"
5
7
 
@@ -54,12 +56,23 @@ module Savon
54
56
  @header ||= {}
55
57
  end
56
58
 
59
+ # Sets the SOAP envelope namespace.
60
+ attr_writer :env_namespace
61
+
62
+ # Returns the SOAP envelope namespace. Defaults to :env.
63
+ def env_namespace
64
+ @env_namespace ||= :env
65
+ end
66
+
57
67
  # Sets the +namespaces+ Hash.
58
68
  attr_writer :namespaces
59
69
 
60
- # Returns the +namespaces+. Defaults to a Hash containing the <tt>xmlns:env</tt> namespace.
70
+ # Returns the +namespaces+. Defaults to a Hash containing the SOAP envelope namespace.
61
71
  def namespaces
62
- @namespaces ||= { "xmlns:env" => SOAP::Namespace[version] }
72
+ @namespaces ||= begin
73
+ key = env_namespace.blank? ? "xmlns" : "xmlns:#{env_namespace}"
74
+ { key => SOAP::Namespace[version] }
75
+ end
63
76
  end
64
77
 
65
78
  # Sets the default namespace identifier.
@@ -76,7 +89,7 @@ module Savon
76
89
  # Accessor for the <tt>Savon::WSSE</tt> object.
77
90
  attr_accessor :wsse
78
91
 
79
- # Accessor for the SOAP +body+. Expected to be a Hash that can be translated to XML via Hash.to_soap_xml
92
+ # Accessor for the SOAP +body+. Expected to be a Hash that can be translated to XML via Gyoku.xml
80
93
  # or any other Object responding to to_s.
81
94
  attr_accessor :body
82
95
 
@@ -90,9 +103,9 @@ module Savon
90
103
 
91
104
  # Returns the XML for a SOAP request.
92
105
  def to_xml
93
- @xml ||= builder.env :Envelope, complete_namespaces do |xml|
94
- xml.env(:Header) { xml << header_for_xml } unless header_for_xml.empty?
95
- xml.env(:Body) { xml.tag!(*input) { xml << body_to_xml } }
106
+ @xml ||= tag(builder, :Envelope, complete_namespaces) do |xml|
107
+ tag(xml, :Header) { xml << header_for_xml } unless header_for_xml.empty?
108
+ tag(xml, :Body) { xml.tag!(*input) { xml << body_to_xml } }
96
109
  end
97
110
  end
98
111
 
@@ -105,6 +118,13 @@ module Savon
105
118
  builder
106
119
  end
107
120
 
121
+ # Expects a builder +xml+ instance, a tag +name+ and accepts optional +namespaces+
122
+ # and a block to create an XML tag.
123
+ def tag(xml, name, namespaces = {}, &block)
124
+ return xml.tag! name, namespaces, &block if env_namespace.blank?
125
+ xml.tag! env_namespace, name, namespaces, &block
126
+ end
127
+
108
128
  # Returns the complete Hash of namespaces.
109
129
  def complete_namespaces
110
130
  defaults = SchemaTypes.dup
@@ -114,7 +134,7 @@ module Savon
114
134
 
115
135
  # Returns the SOAP header as an XML String.
116
136
  def header_for_xml
117
- @header_for_xml ||= header.to_soap_xml + wsse_header
137
+ @header_for_xml ||= Gyoku.xml(header) + wsse_header
118
138
  end
119
139
 
120
140
  # Returns the WSSE header or an empty String in case WSSE was not set.
@@ -124,7 +144,7 @@ module Savon
124
144
 
125
145
  # Returns the SOAP body as an XML String.
126
146
  def body_to_xml
127
- body.respond_to?(:to_soap_xml) ? body.to_soap_xml : body.to_s
147
+ body.kind_of?(Hash) ? Gyoku.xml(body) : body.to_s
128
148
  end
129
149
 
130
150
  end
@@ -1,5 +1,5 @@
1
1
  module Savon
2
2
 
3
- Version = "0.8.0.beta.4"
3
+ Version = "0.8.0"
4
4
 
5
5
  end
@@ -16,9 +16,11 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_dependency "builder", "~> 2.1.2"
18
18
  s.add_dependency "crack", "~> 0.1.8"
19
- s.add_dependency "httpi", ">= 0.7.1"
19
+ s.add_dependency "httpi", ">= 0.7.4"
20
+ s.add_dependency "gyoku", ">= 0.1.0"
20
21
 
21
22
  s.add_development_dependency "rspec", "~> 2.0.0"
23
+ s.add_development_dependency "autotest"
22
24
  s.add_development_dependency "mocha", "~> 0.9.7"
23
25
 
24
26
  s.files = `git ls-files`.split("\n")
@@ -64,7 +64,7 @@ describe Savon::Client do
64
64
 
65
65
  describe "#request" do
66
66
  before do
67
- HTTPI.stubs(:get).returns(new_response(:body => WSDLFixture.load))
67
+ HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:authentication)))
68
68
  HTTPI.stubs(:post).returns(new_response)
69
69
  end
70
70
 
@@ -189,7 +189,7 @@ describe Savon::Client do
189
189
 
190
190
  context "with a remote WSDL document" do
191
191
  let(:client) { Savon::Client.new { wsdl.document = Endpoint.wsdl } }
192
- before { HTTPI.expects(:get).returns(new_response(:body => WSDLFixture.load)) }
192
+ before { HTTPI.expects(:get).returns(new_response(:body => Fixture.wsdl(:authentication))) }
193
193
 
194
194
  it "should return a list of available SOAP actions" do
195
195
  client.wsdl.soap_actions.should == [:authenticate]
@@ -208,12 +208,12 @@ describe Savon::Client do
208
208
  response = client.request(:authenticate)
209
209
 
210
210
  response.should be_a(Savon::SOAP::Response)
211
- response.to_xml.should == ResponseFixture.authentication
211
+ response.to_xml.should == Fixture.response(:authentication)
212
212
  end
213
213
  end
214
214
 
215
215
  context "with a local WSDL document" do
216
- let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/xml/authentication.xml" } }
216
+ let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/authentication.xml" } }
217
217
 
218
218
  before { HTTPI.expects(:get).never }
219
219
 
@@ -234,7 +234,7 @@ describe Savon::Client do
234
234
  response = client.request(:authenticate)
235
235
 
236
236
  response.should be_a(Savon::SOAP::Response)
237
- response.to_xml.should == ResponseFixture.authentication
237
+ response.to_xml.should == Fixture.response(:authentication)
238
238
  end
239
239
  end
240
240
 
@@ -265,7 +265,7 @@ describe Savon::Client do
265
265
  response = client.request(:authenticate)
266
266
 
267
267
  response.should be_a(Savon::SOAP::Response)
268
- response.to_xml.should == ResponseFixture.authentication
268
+ response.to_xml.should == Fixture.response(:authentication)
269
269
  end
270
270
  end
271
271
 
@@ -277,7 +277,7 @@ describe Savon::Client do
277
277
  end
278
278
  end
279
279
 
280
- before { HTTPI::expects(:post).returns(new_response(:code => 500, :body => ResponseFixture.soap_fault)) }
280
+ before { HTTPI::expects(:post).returns(new_response(:code => 500, :body => Fixture.response(:soap_fault))) }
281
281
 
282
282
  it "should raise a Savon::SOAP::Fault" do
283
283
  lambda { client.request :authenticate }.should raise_error(Savon::SOAP::Fault)
@@ -300,7 +300,7 @@ describe Savon::Client do
300
300
  end
301
301
 
302
302
  def new_response(options = {})
303
- defaults = { :code => 200, :headers => {}, :body => ResponseFixture.authentication }
303
+ defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
304
304
  response = defaults.merge options
305
305
 
306
306
  HTTPI::Response.new response[:code], response[:headers], response[:body]
@@ -14,132 +14,6 @@ describe Hash do
14
14
  end
15
15
  end
16
16
 
17
- describe "to_soap_xml" do
18
- describe "should return SOAP request compatible XML" do
19
- it "for a simple Hash" do
20
- hash, result = { :some => "user" }, "<some>user</some>"
21
- hash.to_soap_xml.should == result
22
- end
23
-
24
- it "for a nested Hash" do
25
- hash, result = { :some => { :new => "user" } }, "<some><new>user</new></some>"
26
- hash.to_soap_xml.should == result
27
- end
28
-
29
- it "for a Hash with multiple keys" do
30
- hash = { :all => "users", :before => "whatever" }
31
- hash.to_soap_xml.should include("<all>users</all>", "<before>whatever</before>")
32
- end
33
-
34
- it "for a Hash containing an Array" do
35
- hash, result = { :some => ["user", "gorilla"] }, "<some>user</some><some>gorilla</some>"
36
- hash.to_soap_xml.should == result
37
- end
38
-
39
- it "for a Hash containing an Array of Hashes" do
40
- hash = { :some => [{ :new => "user" }, { :old => "gorilla" }] }
41
- result = "<some><new>user</new></some><some><old>gorilla</old></some>"
42
-
43
- hash.to_soap_xml.should == result
44
- end
45
- end
46
-
47
- it "should convert Hash key Symbols to lowerCamelCase" do
48
- hash, result = { :find_or_create => "user" }, "<findOrCreate>user</findOrCreate>"
49
- hash.to_soap_xml.should == result
50
- end
51
-
52
- it "should not convert Hash key Strings" do
53
- hash, result = { "find_or_create" => "user" }, "<find_or_create>user</find_or_create>"
54
- hash.to_soap_xml.should == result
55
- end
56
-
57
- it "should convert DateTime objects to xs:dateTime compliant Strings" do
58
- hash = { :before => DateTime.new(2012, 03, 22, 16, 22, 33) }
59
- result = "<before>2012-03-22T16:22:33+00:00</before>"
60
-
61
- hash.to_soap_xml.should == result
62
- end
63
-
64
- it "should convert Objects responding to to_datetime to xs:dateTime compliant Strings" do
65
- singleton = Object.new
66
- def singleton.to_datetime
67
- DateTime.new(2012, 03, 22, 16, 22, 33)
68
- end
69
-
70
- hash, result = { :before => singleton }, "<before>2012-03-22T16:22:33+00:00</before>"
71
- hash.to_soap_xml.should == result
72
- end
73
-
74
- it "should call to_s on Strings even if they respond to to_datetime" do
75
- object = "gorilla"
76
- object.expects(:to_datetime).never
77
-
78
- hash, result = { :name => object }, "<name>gorilla</name>"
79
- hash.to_soap_xml.should == result
80
- end
81
-
82
- it "should properly serialize nil values" do
83
- { :some => nil }.to_soap_xml.should == '<some xsi:nil="true"/>'
84
- end
85
-
86
- it "should call to_s on any other Object" do
87
- [666, true, false].each do |object|
88
- { :some => object }.to_soap_xml.should == "<some>#{object}</some>"
89
- end
90
- end
91
-
92
- it "should default to escape special characters" do
93
- result = { :some => { :nested => "<tag />" }, :tag => "<tag />" }.to_soap_xml
94
- result.should include("<tag>&lt;tag /&gt;</tag>")
95
- result.should include("<some><nested>&lt;tag /&gt;</nested></some>")
96
- end
97
-
98
- it "should not escape special characters for keys marked with an exclamation mark" do
99
- result = { :some => { :nested! => "<tag />" }, :tag! => "<tag />" }.to_soap_xml
100
- result.should include("<tag><tag /></tag>")
101
- result.should include("<some><nested><tag /></nested></some>")
102
- end
103
-
104
- it "should preserve the order of Hash keys and values specified through :order!" do
105
- hash = { :find_user => { :name => "Lucy", :id => 666, :order! => [:id, :name] } }
106
- result = "<findUser><id>666</id><name>Lucy</name></findUser>"
107
- hash.to_soap_xml.should == result
108
-
109
- hash = { :find_user => { :mname => "in the", :lname => "Sky", :fname => "Lucy", :order! => [:fname, :mname, :lname] } }
110
- result = "<findUser><fname>Lucy</fname><mname>in the</mname><lname>Sky</lname></findUser>"
111
- hash.to_soap_xml.should == result
112
- end
113
-
114
- it "should raise an error if the :order! Array does not match the Hash keys" do
115
- hash = { :name => "Lucy", :id => 666, :order! => [:name] }
116
- lambda { hash.to_soap_xml }.should raise_error(ArgumentError)
117
-
118
- hash = { :by_name => { :name => "Lucy", :lname => "Sky", :order! => [:mname, :name] } }
119
- lambda { hash.to_soap_xml }.should raise_error(ArgumentError)
120
- end
121
-
122
- it "should add attributes to Hash keys specified through :attributes!" do
123
- hash = { :find_user => { :person => "Lucy", :attributes! => { :person => { :id => 666 } } } }
124
- result = '<findUser><person id="666">Lucy</person></findUser>'
125
- hash.to_soap_xml.should == result
126
-
127
- hash = { :find_user => { :person => "Lucy", :attributes! => { :person => { :id => 666, :city => "Hamburg" } } } }
128
- soap_xml = hash.to_soap_xml
129
- soap_xml.should include('id="666"', 'city="Hamburg"')
130
- end
131
-
132
- it "should add attributes to duplicate Hash keys specified through :attributes!" do
133
- hash = { :find_user => { :person => ["Lucy", "Anna"], :attributes! => { :person => { :id => [1, 3] } } } }
134
- result = '<findUser><person id="1">Lucy</person><person id="3">Anna</person></findUser>'
135
- hash.to_soap_xml.should == result
136
-
137
- hash = { :find_user => { :person => ["Lucy", "Anna"], :attributes! => { :person => { :active => "true" } } } }
138
- result = '<findUser><person active="true">Lucy</person><person active="true">Anna</person></findUser>'
139
- hash.to_soap_xml.should == result
140
- end
141
- end
142
-
143
17
  describe "map_soap_response" do
144
18
  it "should convert Hash key Strings to snake_case Symbols" do
145
19
  soap_response = { "userResponse" => { "accountStatus" => "active" } }
@@ -16,19 +16,4 @@ describe Object do
16
16
  end
17
17
  end
18
18
 
19
- describe "to_soap_value" do
20
- it "returns an xs:dateTime compliant String for Objects responding to to_datetime" do
21
- singleton = Object.new
22
- def singleton.to_datetime
23
- DateTime.new(2012, 03, 22, 16, 22, 33)
24
- end
25
-
26
- singleton.to_soap_value.should == "2012-03-22T16:22:33+00:00"
27
- end
28
-
29
- it "calls to_s unless the Object responds to to_datetime" do
30
- "value".to_soap_value.should == "value".to_s
31
- end
32
- end
33
-
34
19
  end
@@ -62,26 +62,4 @@ describe String do
62
62
  end
63
63
  end
64
64
 
65
- describe "to_soap_key" do
66
- it "removes exclamation marks from the end of the String" do
67
- "value".to_soap_key.should == "value"
68
- "value!".to_soap_key.should == "value"
69
- end
70
- end
71
-
72
- describe "to_soap_value" do
73
- it "should return the String value and escape special characters" do
74
- "string".to_soap_value.should == "string"
75
- "<tag>".to_soap_value.should == "&lt;tag&gt;"
76
- "at&t".to_soap_value.should == "at&amp;t"
77
- '"quotes"'.to_soap_value.should == "&quot;quotes&quot;"
78
- end
79
- end
80
-
81
- describe "to_soap_value!" do
82
- it "should just return the String value without escaping special characters" do
83
- "<tag>".to_soap_value!.should == "<tag>"
84
- end
85
- end
86
-
87
65
  end
@@ -43,7 +43,7 @@ describe Savon::HTTP::Error do
43
43
  end
44
44
 
45
45
  def new_response(options = {})
46
- defaults = { :code => 200, :headers => {}, :body => ResponseFixture.authentication }
46
+ defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
47
47
  response = defaults.merge options
48
48
 
49
49
  HTTPI::Response.new response[:code], response[:headers], response[:body]
@@ -1,9 +1,9 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Savon::SOAP::Fault do
4
- let(:soap_fault) { Savon::SOAP::Fault.new new_response(:body => ResponseFixture.soap_fault) }
5
- let(:soap_fault2) { Savon::SOAP::Fault.new new_response(:body => ResponseFixture.soap_fault12) }
6
- let(:another_soap_fault) { Savon::SOAP::Fault.new new_response(:body => ResponseFixture.another_soap_fault) }
4
+ let(:soap_fault) { Savon::SOAP::Fault.new new_response(:body => Fixture.response(:soap_fault)) }
5
+ let(:soap_fault2) { Savon::SOAP::Fault.new new_response(:body => Fixture.response(:soap_fault12)) }
6
+ let(:another_soap_fault) { Savon::SOAP::Fault.new new_response(:body => Fixture.response(:another_soap_fault)) }
7
7
  let(:no_fault) { Savon::SOAP::Fault.new new_response }
8
8
 
9
9
  it "should be a Savon::Error" do
@@ -80,7 +80,7 @@ describe Savon::SOAP::Fault do
80
80
  end
81
81
 
82
82
  def new_response(options = {})
83
- defaults = { :code => 200, :headers => {}, :body => ResponseFixture.authentication }
83
+ defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
84
84
  response = defaults.merge options
85
85
 
86
86
  HTTPI::Response.new response[:code], response[:headers], response[:body]