savon 0.7.6 → 0.7.7

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 CHANGED
@@ -1,5 +1,20 @@
1
+ == 0.7.7 (2010-05-09)
2
+ * SOAP requests now start with a proper XML declaration.
3
+ * Added support for gzipped requests and responses (http://github.com/lucascs). While gzipped SOAP
4
+ responses are decoded automatically, you have to manually instruct Savon to gzip SOAP requests:
5
+
6
+ client = Savon::Client.new "http://example.com/UserService?wsdl", :gzip => true
7
+
8
+ * Fix for issue #51. Added the :soap_endpoint option to Savon::Client.new which let's you specify a SOAP
9
+ endpoint per client instance:
10
+
11
+ client = Savon::Client.new "http://example.com/UserService?wsdl",
12
+ :soap_endpoint => "http://localhost/UserService"
13
+
14
+ * Fix for issue #50. Savon still escapes special characters in SOAP request Hash values, but you can now
15
+ append an exclamation mark to Hash keys specifying that it's value should not be escaped.
16
+
1
17
  == 0.7.6 (2010-03-21)
2
- * Renamed
3
18
  * Moved documentation from the Github Wiki to the actual class files and established a much nicer
4
19
  documentation combining examples and implementation (using Hanna) at: http://savon.rubiii.com
5
20
  * Added Savon::Client#call as a workaround for dispatching calls to SOAP actions named after
@@ -153,4 +168,3 @@
153
168
 
154
169
  == 0.5.0 (2009-11-29)
155
170
  * Complete rewrite.
156
-
@@ -16,7 +16,7 @@ Instantiate Savon::Client, passing in the WSDL of your service.
16
16
 
17
17
  client = Savon::Client.new "http://example.com/UserService?wsdl"
18
18
 
19
- For production, it is highly recommended to not use Savon::WSDL. Information on {how to disable the WSDL}[http://savon.rubiii.com/docs/latest/classes/Savon/WSDL.html].
19
+ For production, it is highly recommended to not use Savon::WSDL. Information on {how to disable the WSDL}[http://savon.rubiii.com/docs/0.7.7/classes/Savon/WSDL.html].
20
20
 
21
21
  == Calling a SOAP action
22
22
 
@@ -56,9 +56,9 @@ Savon::Response represents the HTTP and SOAP response. It contains and raises er
56
56
  == HTTP errors and SOAP faults
57
57
 
58
58
  Savon raises a Savon::SOAPFault in case of a SOAP fault and a Savon::HTTPError in case of an HTTP error.
59
- More information: {Errors}[http://savon.rubiii.com/docs/latest/classes/Savon/Response.html]
59
+ More information: {Errors}[http://savon.rubiii.com/docs/0.7.7/classes/Savon/Response.html]
60
60
 
61
61
  == Logging
62
62
 
63
63
  Savon logs each request and response to STDOUT. But there are a couple of options to change the default behavior.
64
- More information: {Logging}[http://savon.rubiii.com/docs/latest/classes/Savon/Request.html]
64
+ More information: {Logging}[http://savon.rubiii.com/docs/0.7.7/classes/Savon/Request.html]
data/Rakefile CHANGED
@@ -36,7 +36,6 @@ Spec::Rake::SpecTask.new(:run_integration_spec) do |spec|
36
36
  end
37
37
 
38
38
  begin
39
- $:.unshift File.join(File.dirname(__FILE__), "..", "hanna", "lib")
40
39
  require "hanna/rdoctask"
41
40
 
42
41
  Rake::RDocTask.new do |rdoc|
@@ -14,6 +14,9 @@ require "net/https"
14
14
  require "base64"
15
15
  require "digest/sha1"
16
16
  require "rexml/document"
17
+ require "stringio"
18
+ require "zlib"
19
+ require "cgi"
17
20
 
18
21
  # gem dependencies
19
22
  require "builder"
@@ -29,3 +32,4 @@ require "savon/response"
29
32
  require "savon/wsdl_stream"
30
33
  require "savon/wsdl"
31
34
  require "savon/client"
35
+ require "savon/version"
@@ -27,6 +27,19 @@ module Savon
27
27
  #
28
28
  # client = Savon::Client.new "http://example.com/UserService?wsdl", :proxy => "http://proxy.example.com"
29
29
  #
30
+ # == Forcing a particular SOAP endpoint
31
+ #
32
+ # In case you don't want to use the SOAP endpoint specified in the WSDL, you can tell Savon to use
33
+ # another SOAP endpoint.
34
+ #
35
+ # client = Savon::Client.new "http://example.com/UserService?wsdl", :soap_endpoint => "http://localhost/UserService"
36
+ #
37
+ # == Gzipped SOAP requests
38
+ #
39
+ # Sending gzipped SOAP requests can be specified per client instance.
40
+ #
41
+ # client = Savon::Client.new "http://example.com/UserService?wsdl", :gzip => true
42
+ #
30
43
  # == Savon::WSDL
31
44
  #
32
45
  # You can access Savon::WSDL via:
@@ -40,11 +53,17 @@ module Savon
40
53
  # client.request
41
54
  class Client
42
55
 
43
- # Expects a SOAP +endpoint+ string. Also accepts an optional hash of +options+ for specifying
44
- # a +:proxy+ server to use.
56
+ # Expects a SOAP +endpoint+ string. Also accepts a Hash of +options+.
57
+ #
58
+ # ==== Options:
59
+ #
60
+ # [proxy] the proxy server to use
61
+ # [gzip] whether to gzip SOAP requests
62
+ # [soap_endpoint] force to use this SOAP endpoint
45
63
  def initialize(endpoint, options = {})
64
+ soap_endpoint = options.delete(:soap_endpoint)
46
65
  @request = Request.new endpoint, options
47
- @wsdl = WSDL.new @request
66
+ @wsdl = WSDL.new @request, soap_endpoint
48
67
  end
49
68
 
50
69
  # Returns the Savon::WSDL.
@@ -1,14 +1,14 @@
1
1
  class Array
2
2
 
3
3
  # Translates the Array into SOAP compatible XML. See: Hash.to_soap_xml.
4
- def to_soap_xml(key, attributes = {})
4
+ def to_soap_xml(key, escape_xml = true, attributes = {})
5
5
  xml = Builder::XmlMarkup.new
6
6
 
7
7
  each_with_index do |item, index|
8
8
  attrs = tag_attributes attributes, index
9
9
  case item
10
10
  when Hash then xml.tag!(key, attrs) { xml << item.to_soap_xml }
11
- else xml.tag!(key, attrs) { xml << item.to_soap_value }
11
+ else xml.tag!(key, attrs) { xml << (escape_xml ? item.to_soap_value : item.to_soap_value!) }
12
12
  end
13
13
  end
14
14
 
@@ -5,4 +5,6 @@ class DateTime
5
5
  strftime Savon::SOAP::DateTimeFormat
6
6
  end
7
7
 
8
+ alias_method :to_soap_value!, :to_soap_value
9
+
8
10
  end
@@ -35,7 +35,11 @@ class Hash
35
35
  # <perform_at>2012-06-11T10:42:21</perform_at>
36
36
  # </magicRequest>
37
37
  #
38
- # ==== :order!
38
+ # ==== Escaped XML values
39
+ #
40
+ # By default, special characters in XML String values are escaped.
41
+ #
42
+ # ==== Fixed order of XML tags
39
43
  #
40
44
  # In case your service requires the tags to be in a specific order (parameterOrder), you have two
41
45
  # options. The first is to specify your body as an XML string. The second is to specify the order
@@ -44,7 +48,7 @@ class Hash
44
48
  # { :name => "Eve", :id => 123, :order! => [:id, :name] }.to_soap_xml
45
49
  # # => "<id>123</id><name>Eve</name>"
46
50
  #
47
- # ==== :attributes!
51
+ # ==== XML attributes
48
52
  #
49
53
  # If you need attributes, you could either go with an XML string or add another hash under the
50
54
  # +:attributes!+ key.
@@ -58,12 +62,13 @@ class Hash
58
62
  order.each do |key|
59
63
  attrs = attributes[key] || {}
60
64
  value = self[key]
65
+ escape_xml = key.to_s[-1, 1] != "!"
61
66
  key = key.to_soap_key
62
67
 
63
68
  case value
64
- when Array then xml << value.to_soap_xml(key, attrs)
69
+ when Array then xml << value.to_soap_xml(key, escape_xml, attrs)
65
70
  when Hash then xml.tag!(key, attrs) { xml << value.to_soap_xml }
66
- else xml.tag!(key, attrs) { xml << value.to_soap_value }
71
+ else xml.tag!(key, attrs) { xml << (escape_xml ? value.to_soap_value : value.to_soap_value!) }
67
72
  end
68
73
  end
69
74
 
@@ -5,15 +5,12 @@ class Object
5
5
  respond_to?(:empty?) ? empty? : !self
6
6
  end unless defined? blank?
7
7
 
8
- # Returns the Object as a SOAP request compliant key.
9
- def to_soap_key
10
- to_s
11
- end
12
-
13
8
  # Returns the Object as a SOAP request compliant value.
14
9
  def to_soap_value
15
10
  return to_s unless respond_to? :to_datetime
16
11
  to_datetime.to_soap_value
17
12
  end
18
13
 
14
+ alias_method :to_soap_value!, :to_soap_value
15
+
19
16
  end
@@ -51,16 +51,19 @@ class String
51
51
  self
52
52
  end
53
53
 
54
- # Returns the String as a SOAP request compliant value.
55
- # Escapes special characters for XML.
54
+ # Returns the Object as a SOAP request compliant key.
55
+ def to_soap_key
56
+ self[-1, 1] == "!" ? chop : self
57
+ end
58
+
59
+ # Returns the String as a SOAP value. Escapes special characters for XML.
56
60
  def to_soap_value
57
- str = dup
58
- str.gsub! "&", "&amp;"
59
- str.gsub! '"', "&quot;"
60
- str.gsub! "'", "&apos;"
61
- str.gsub! "<", "&lt;"
62
- str.gsub! ">", "&gt;"
63
- str
61
+ CGI.escapeHTML self
62
+ end
63
+
64
+ # Convert the String into a SOAP value without escaping special characters.
65
+ def to_soap_value!
66
+ self
64
67
  end
65
68
 
66
69
  end
@@ -2,7 +2,7 @@ class Symbol
2
2
 
3
3
  # Returns the Symbol as a lowerCamelCase String.
4
4
  def to_soap_key
5
- to_s.lower_camelcase
5
+ to_s.to_soap_key.lower_camelcase
6
6
  end
7
7
 
8
8
  end
@@ -46,11 +46,11 @@ module Savon
46
46
  # Content-Types by SOAP version.
47
47
  ContentType = { 1 => "text/xml;charset=UTF-8", 2 => "application/soap+xml;charset=UTF-8" }
48
48
 
49
- # Expects a SOAP +endpoint+ String. Also accepts an optional Hash
50
- # of +options+ for specifying a proxy server.
49
+ # Expects a WSDL or SOAP +endpoint+ and accepts a custom +proxy+ address.
51
50
  def initialize(endpoint, options = {})
52
51
  @endpoint = URI endpoint
53
- @proxy = options[:proxy] ? URI(options[:proxy]) : URI("")
52
+ @proxy = URI options[:proxy] || ""
53
+ headers["Accept-encoding"] = "gzip,deflate" if options[:gzip]
54
54
  end
55
55
 
56
56
  # Returns the endpoint URI.
@@ -135,3 +135,4 @@ module Savon
135
135
 
136
136
  end
137
137
  end
138
+
@@ -100,12 +100,12 @@ module Savon
100
100
 
101
101
  # Returns the SOAP response body as a Hash.
102
102
  def to_hash
103
- @body ||= (Crack::XML.parse(@http.body) rescue {}).find_soap_body
103
+ @hash ||= (Crack::XML.parse(body) rescue {}).find_soap_body
104
104
  end
105
105
 
106
106
  # Returns the SOAP response XML.
107
107
  def to_xml
108
- @http.body
108
+ body
109
109
  end
110
110
 
111
111
  # Returns the HTTP response object.
@@ -115,6 +115,24 @@ module Savon
115
115
 
116
116
  private
117
117
 
118
+ # Returns the response body.
119
+ def body
120
+ @body || gzipped_body? ? decoded_body : @http.body
121
+ end
122
+
123
+ # Returns whether the body is gzipped.
124
+ def gzipped_body?
125
+ @http["content-encoding"] == "gzip" || @http.body[0..1] == "\x1f\x8b"
126
+ end
127
+
128
+ # Returns the gzip decoded body.
129
+ def decoded_body
130
+ gz = Zlib::GzipReader.new StringIO.new(@http.body)
131
+ gz.read
132
+ ensure
133
+ gz.close
134
+ end
135
+
118
136
  # Handles SOAP faults. Raises a Savon::SOAPFault unless the default behavior of raising errors
119
137
  # was turned off.
120
138
  def handle_soap_fault
@@ -146,10 +164,11 @@ module Savon
146
164
  def handle_http_error
147
165
  if @http.code.to_i > MaxNonErrorResponseCode
148
166
  @http_error = "#{@http.message} (#{@http.code})"
149
- @http_error << ": #{@http.body}" unless @http.body.empty?
167
+ @http_error << ": #{body}" unless body.empty?
150
168
  raise Savon::HTTPError, http_error if self.class.raise_errors?
151
169
  end
152
170
  end
153
171
 
154
172
  end
155
173
  end
174
+
@@ -0,0 +1,5 @@
1
+ module Savon
2
+
3
+ Version = "0.7.7"
4
+
5
+ end
@@ -71,9 +71,9 @@ module Savon
71
71
  # end
72
72
  class WSDL
73
73
 
74
- # Initializer, expects a Savon::Request.
75
- def initialize(request)
76
- @request, @enabled = request, true
74
+ # Expects a Savon::Request and accepts a custom +soap_endpoint+.
75
+ def initialize(request, soap_endpoint = nil)
76
+ @request, @enabled, @soap_endpoint = request, true, soap_endpoint
77
77
  end
78
78
 
79
79
  # Sets whether to use the WSDL.
@@ -0,0 +1,7 @@
1
+ class GzipResponseFixture
2
+
3
+ def self.message
4
+ File.read(File.join(File.dirname(__FILE__), 'message.gz'))
5
+ end
6
+ end
7
+
@@ -14,6 +14,11 @@ describe Savon::Client do
14
14
  client.request.http.proxy_address == "http://proxy"
15
15
  end
16
16
 
17
+ it "should accept a SOAP endpoint via an optional Hash of options" do
18
+ client = Savon::Client.new EndpointHelper.wsdl_endpoint, :soap_endpoint => "http://localhost"
19
+ client.wsdl.soap_endpoint.should == "http://localhost"
20
+ end
21
+
17
22
  it "should have a method that returns the Savon::WSDL" do
18
23
  @client.wsdl.should be_a(Savon::WSDL)
19
24
  end
@@ -3,17 +3,47 @@ require "spec_helper"
3
3
  describe Array do
4
4
 
5
5
  describe "to_soap_xml" do
6
- describe "should return SOAP request compatible XML" do
7
- it "for an Array of Hashes" do
8
- hash, result = [{ :name => "Eve" }], "<findUser><name>Eve</name></findUser>"
9
- hash.to_soap_xml("findUser").should == result
10
- end
11
-
12
- it "for an Array of Strings and other Objects" do
13
- hash, result = [:id, :name], "<someValues>id</someValues><someValues>name</someValues>"
14
- hash.to_soap_xml("someValues").should == result
15
- end
6
+ it "should return the XML for an Array of Hashes" do
7
+ array = [{ :name => "adam" }, { :name => "eve" }]
8
+ result = "<user><name>adam</name></user><user><name>eve</name></user>"
9
+
10
+ array.to_soap_xml("user").should == result
11
+ end
12
+
13
+ it "should return the XML for an Array of different Objects" do
14
+ array = [:symbol, "string", 123]
15
+ result = "<value>symbol</value><value>string</value><value>123</value>"
16
+
17
+ array.to_soap_xml("value").should == result
18
+ end
19
+
20
+ it "should default to escape special characters" do
21
+ array = ["<tag />", "adam & eve"]
22
+ result = "<value>&lt;tag /&gt;</value><value>adam &amp; eve</value>"
23
+
24
+ array.to_soap_xml("value").should == result
25
+ end
26
+
27
+ it "should not escape special characters when told to" do
28
+ array = ["<tag />", "adam & eve"]
29
+ result = "<value><tag /></value><value>adam & eve</value>"
30
+
31
+ array.to_soap_xml("value", false).should == result
32
+ end
33
+
34
+ it "should add attributes to a given tag" do
35
+ array = ["adam", "eve"]
36
+ result = '<value active="true">adam</value><value active="true">eve</value>'
37
+
38
+ array.to_soap_xml("value", :escape_xml, :active => true).should == result
39
+ end
40
+
41
+ it "should add attributes to duplicate tags" do
42
+ array = ["adam", "eve"]
43
+ result = '<value id="1">adam</value><value id="2">eve</value>'
44
+
45
+ array.to_soap_xml("value", :escape_xml, :id => [1, 2]).should == result
16
46
  end
17
47
  end
18
48
 
19
- end
49
+ end
@@ -1,11 +1,20 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe DateTime do
4
+ before do
5
+ @datetime = DateTime.new 2012, 03, 22, 16, 22, 33
6
+ @datetime_string = "2012-03-22T16:22:33Z"
7
+ end
4
8
 
5
9
  describe "to_soap_value" do
6
- it "returns an xs:dateTime compliant String" do
7
- DateTime.new(2012, 03, 22, 16, 22, 33).to_soap_value.
8
- should == "2012-03-22T16:22:33Z"
10
+ it "should return an xs:dateTime compliant String" do
11
+ @datetime.to_soap_value.should == @datetime_string
12
+ end
13
+ end
14
+
15
+ describe "to_soap_value!" do
16
+ it "should act like :to_soap_value" do
17
+ @datetime.to_soap_value.should == @datetime_string
9
18
  end
10
19
  end
11
20
 
@@ -85,6 +85,18 @@ describe Hash do
85
85
  end
86
86
  end
87
87
 
88
+ it "should default to escape special characters" do
89
+ result = { :some => { :nested => "<tag />" }, :tag => "<tag />" }.to_soap_xml
90
+ result.should include("<tag>&lt;tag /&gt;</tag>")
91
+ result.should include("<some><nested>&lt;tag /&gt;</nested></some>")
92
+ end
93
+
94
+ it "should not escape special characters for keys marked with an exclamation mark" do
95
+ result = { :some => { :nested! => "<tag />" }, :tag! => "<tag />" }.to_soap_xml
96
+ result.should include("<tag><tag /></tag>")
97
+ result.should include("<some><nested><tag /></nested></some>")
98
+ end
99
+
88
100
  it "should preserve the order of Hash keys and values specified through :order!" do
89
101
  hash = { :find_user => { :name => "Lucy", :id => 666, :order! => [:id, :name] } }
90
102
  result = "<findUser><id>666</id><name>Lucy</name></findUser>"
@@ -16,12 +16,6 @@ describe Object do
16
16
  end
17
17
  end
18
18
 
19
- describe "to_soap_key" do
20
- it "calls to_s for every Object" do
21
- Object.to_soap_key.should == Object.to_s
22
- end
23
- end
24
-
25
19
  describe "to_soap_value" do
26
20
  it "returns an xs:dateTime compliant String for Objects responding to to_datetime" do
27
21
  singleton = Object.new
@@ -74,13 +74,25 @@ describe String do
74
74
  end
75
75
  end
76
76
 
77
+ describe "to_soap_key" do
78
+ it "removes exclamation marks from the end of the String" do
79
+ "value".to_soap_key.should == "value"
80
+ "value!".to_soap_key.should == "value"
81
+ end
82
+ end
83
+
77
84
  describe "to_soap_value" do
78
- it "should return the string value and escape special characters" do
85
+ it "should return the String value and escape special characters" do
79
86
  "string".to_soap_value.should == "string"
80
87
  "<tag>".to_soap_value.should == "&lt;tag&gt;"
81
88
  "at&t".to_soap_value.should == "at&amp;t"
82
89
  '"quotes"'.to_soap_value.should == "&quot;quotes&quot;"
83
- "'apos'".to_soap_value.should == "&apos;apos&apos;"
90
+ end
91
+ end
92
+
93
+ describe "to_soap_value!" do
94
+ it "should just return the String value without escaping special characters" do
95
+ "<tag>".to_soap_value!.should == "<tag>"
84
96
  end
85
97
  end
86
98
 
@@ -5,6 +5,7 @@ describe Symbol do
5
5
  describe "to_soap_key" do
6
6
  it "converts the Symbol from snake_case to a lowerCamelCase String" do
7
7
  :lower_camel_case.to_soap_key.should == "lowerCamelCase"
8
+ :lower_camel_case!.to_soap_key.should == "lowerCamelCase"
8
9
  end
9
10
  end
10
11
 
@@ -75,14 +75,38 @@ describe Savon::Request do
75
75
  wsdl_response.body.should == WSDLFixture.authentication
76
76
  end
77
77
 
78
- it "executes a SOAP request and returns the Net::HTTP response" do
79
- operation = WSDLFixture.authentication(:operations)[:authenticate]
80
- action, input = operation[:action], operation[:input]
81
- soap = Savon::SOAP.new action, input, EndpointHelper.soap_endpoint
82
- soap_response = @request.soap soap
83
78
 
84
- soap_response.should be_a(Net::HTTPResponse)
85
- soap_response.body.should == ResponseFixture.authentication
79
+ describe "when executing a SOAP request" do
80
+ before :each do
81
+ operation = WSDLFixture.authentication(:operations)[:authenticate]
82
+ action, input = operation[:action], operation[:input]
83
+ @soap = Savon::SOAP.new action, input, EndpointHelper.soap_endpoint
84
+ end
85
+
86
+ it "should return the Net::HTTP response" do
87
+ soap_response = @request.soap @soap
88
+
89
+ soap_response.should be_a(Net::HTTPResponse)
90
+ soap_response.body.should == ResponseFixture.authentication
91
+ end
92
+
93
+ it "should include Accept-Encoding gzip if it is enabled" do
94
+ @request = Savon::Request.new EndpointHelper.wsdl_endpoint, :gzip => true
95
+ a_post = Net::HTTP::Post.new(@soap.endpoint.request_uri, {})
96
+
97
+ Net::HTTP::Post.expects(:new).with(anything, has_entry("Accept-encoding" => "gzip,deflate")).returns(a_post)
98
+
99
+ @request.soap @soap
100
+ end
101
+
102
+ it "should not include Accept-Encoding gzip if it is not enabled" do
103
+ @request = Savon::Request.new EndpointHelper.wsdl_endpoint, :gzip => false
104
+ a_post = Net::HTTP::Post.new(@soap.endpoint.request_uri, {})
105
+
106
+ Net::HTTP::Post.expects(:new).with(anything, Not(has_entry("Accept-encoding" => "gzip,deflate"))).returns(a_post)
107
+
108
+ @request.soap @soap
109
+ end
86
110
  end
87
111
 
88
112
  it "should not include host when creating HTTP requests" do
@@ -90,4 +114,4 @@ describe Savon::Request do
90
114
  request.path.should_not include("example.com")
91
115
  end
92
116
 
93
- end
117
+ end
@@ -21,13 +21,13 @@ describe Savon::Response do
21
21
  it "raises a Savon::SOAPFault in case of a SOAP fault" do
22
22
  lambda { savon_response_with :soap_fault }.should raise_error(Savon::SOAPFault)
23
23
  end
24
-
24
+
25
25
  it "does not raise a Savon::SOAPFault in case the default is turned off" do
26
26
  Savon::Response.raise_errors = false
27
27
  savon_response_with :soap_fault
28
28
  Savon::Response.raise_errors = true
29
29
  end
30
-
30
+
31
31
  it "raises a Savon::HTTPError in case of an HTTP error" do
32
32
  lambda { savon_response_with :http_error }.should raise_error(Savon::HTTPError)
33
33
  end
@@ -102,7 +102,7 @@ describe Savon::Response do
102
102
  @response = Savon::Response.new http_response_mock(200, ResponseFixture.multi_ref, "OK")
103
103
 
104
104
  @response.to_hash[:list_response].should be_a(Hash)
105
- @response.to_hash[:multi_ref].should be_an(Array)
105
+ @response.to_hash[:multi_ref].should be_an(Array)
106
106
  end
107
107
 
108
108
  it "should return the raw SOAP response body" do
@@ -117,6 +117,44 @@ describe Savon::Response do
117
117
  @response.http.should respond_to(:body)
118
118
  end
119
119
 
120
+ describe "GZipped responses" do
121
+ it "should be decoded if Content-encoding header is gzip" do
122
+ @response = Savon::Response.new http_response_mock(200, body = "Encoded", "OK", 'content-encoding' => 'gzip')
123
+
124
+ should_decode_body body
125
+
126
+ @response.to_xml
127
+ end
128
+
129
+ # header logic extracted from http://dev.ctor.org/svn/soap4r/trunk/lib/soap/streamHandler.rb
130
+ it "should be decoded if body starts with gzip header" do
131
+ @response = Savon::Response.new http_response_mock(200, body = "\x1f\x8bEncoded", "OK")
132
+
133
+ should_decode_body body
134
+
135
+ @response.to_xml
136
+ end
137
+
138
+ it "should be decoded when header is set" do
139
+ @response = Savon::Response.new http_response_mock(200, GzipResponseFixture.message, "OK", 'content-encoding' => 'gzip')
140
+ @response.to_xml.should == "A short gzip encoded message\n"
141
+ end
142
+
143
+ it "should be decoded when header is not set" do
144
+ @response = Savon::Response.new http_response_mock(200, GzipResponseFixture.message, "OK")
145
+ @response.to_xml.should == "A short gzip encoded message\n"
146
+ end
147
+ end
148
+
149
+ def should_decode_body(body)
150
+ StringIO.expects(:new).with(body).returns(stream = mock("StringIO"))
151
+
152
+ Zlib::GzipReader.expects(:new).with(stream).returns(mock("Zlib::GzipReader") do
153
+ expects(:read)
154
+ expects(:close)
155
+ end)
156
+ end
157
+
120
158
  def savon_response_with(error_type)
121
159
  mock = case error_type
122
160
  when :soap_fault then http_response_mock 200, ResponseFixture.soap_fault
@@ -126,12 +164,16 @@ describe Savon::Response do
126
164
  Savon::Response.new mock
127
165
  end
128
166
 
129
- def http_response_mock(code = 200, body = nil, message = "OK")
167
+ def http_response_mock(code = 200, body = nil, message = "OK", headers = {})
130
168
  body ||= ResponseFixture.authentication
131
169
  mock = mock "Net::HTTPResponse"
132
- mock.stubs :code => code.to_s, :message => message,
133
- :content_type => "text/html", :body => body
170
+ mock.stubs :code => code.to_s, :message => message, :content_type => "text/html", :body => body
171
+
172
+ mock.stubs("[]").with(anything).returns(nil)
173
+ headers.each { |key, value| mock.stubs("[]").with(key).returns(value) }
174
+
134
175
  mock
135
176
  end
136
177
 
137
178
  end
179
+
@@ -49,7 +49,7 @@ describe Savon::SOAP do
49
49
  @namespace = { "xmlns:ns" => "http://example.com" }
50
50
  @namespace_string = 'xmlns:ns="http://example.com"'
51
51
  @namespaces = { "xmlns:ns" => "http://ns.example.com", "xmlns:ns2" => "http://ns2.example.com" }
52
-
52
+
53
53
  # reset to defaults
54
54
  Savon::SOAP.version = 1
55
55
  Savon::SOAP.header = {}
@@ -137,15 +137,15 @@ describe Savon::SOAP do
137
137
  it "should merge global and per request headers defined as Hashes" do
138
138
  Savon::SOAP.header = { :key => "value", :key2 => "global value" }
139
139
  @soap.header[:key2] = "request value"
140
- @soap.to_xml.should include(
141
- "<env:Header><key>value</key><key2>request value</key2></env:Header>"
140
+ @soap.to_xml.should match(
141
+ /<env:Header>(<key>value<\/key><key2>request value<\/key2>|<key2>request value<\/key2><key>value<\/key>)<\/env:Header>/
142
142
  )
143
143
  end
144
144
 
145
145
  it "should use the :header method from a given WSSE object to include a WSSE header" do
146
146
  wsse = "some compliant object"
147
147
  wsse.stubs(:header).returns("<wsse>authentication</wsse>")
148
-
148
+
149
149
  @soap.wsse = wsse
150
150
  @soap.to_xml.should include("<env:Header><wsse>authentication</wsse></env:Header>")
151
151
  end
@@ -195,7 +195,8 @@ describe Savon::SOAP do
195
195
  '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">' <<
196
196
  '<env:Body><wsdl:authenticate></wsdl:authenticate></env:Body>' <<
197
197
  '</env:Envelope>'
198
- )
198
+ )
199
199
  end
200
200
  end
201
- end
201
+ end
202
+
@@ -8,6 +8,11 @@ describe Savon::WSDL do
8
8
  Savon::WSDL.new Savon::Request.new(EndpointHelper.wsdl_endpoint)
9
9
  end
10
10
 
11
+ it "it accepts a custom SOAP endpoint" do
12
+ wsdl = Savon::WSDL.new Savon::Request.new(EndpointHelper.wsdl_endpoint), "http://localhost"
13
+ wsdl.soap_endpoint.should == "http://localhost"
14
+ end
15
+
11
16
  it "is enabled by default" do
12
17
  @wsdl.enabled?.should be_true
13
18
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 6
9
- version: 0.7.6
8
+ - 7
9
+ version: 0.7.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Daniel Harrington
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-21 00:00:00 +01:00
17
+ date: 2010-05-09 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -113,12 +113,14 @@ files:
113
113
  - lib/savon/request.rb
114
114
  - lib/savon/response.rb
115
115
  - lib/savon/soap.rb
116
+ - lib/savon/version.rb
116
117
  - lib/savon/wsdl.rb
117
118
  - lib/savon/wsdl_stream.rb
118
119
  - lib/savon/wsse.rb
119
120
  - lib/savon.rb
120
121
  - spec/basic_spec_helper.rb
121
122
  - spec/endpoint_helper.rb
123
+ - spec/fixtures/gzip/gzip_response_fixture.rb
122
124
  - spec/fixtures/response/response_fixture.rb
123
125
  - spec/fixtures/wsdl/wsdl_fixture.rb
124
126
  - spec/http_stubs.rb
@@ -147,6 +149,7 @@ files:
147
149
  - spec/fixtures/wsdl/xml/geotrust.xml
148
150
  - spec/fixtures/wsdl/xml/namespaced_actions.xml
149
151
  - spec/fixtures/wsdl/xml/no_namespace.xml
152
+ - spec/fixtures/gzip/message.gz
150
153
  has_rdoc: true
151
154
  homepage: http://github.com/rubiii/savon
152
155
  licenses: []
@@ -184,6 +187,7 @@ summary: Heavy metal Ruby SOAP client library
184
187
  test_files:
185
188
  - spec/basic_spec_helper.rb
186
189
  - spec/endpoint_helper.rb
190
+ - spec/fixtures/gzip/gzip_response_fixture.rb
187
191
  - spec/fixtures/response/response_fixture.rb
188
192
  - spec/fixtures/wsdl/wsdl_fixture.rb
189
193
  - spec/http_stubs.rb