savon 0.8.0.beta.4 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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]