savon 0.7.9 → 0.8.0.beta.1

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 (74) hide show
  1. data/.gitignore +9 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +2 -0
  4. data/CHANGELOG.md +332 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +20 -0
  7. data/README.md +37 -0
  8. data/Rakefile +28 -39
  9. data/autotest/discover.rb +1 -0
  10. data/lib/savon.rb +10 -31
  11. data/lib/savon/client.rb +116 -98
  12. data/lib/savon/core_ext/array.rb +36 -22
  13. data/lib/savon/core_ext/datetime.rb +15 -6
  14. data/lib/savon/core_ext/hash.rb +122 -94
  15. data/lib/savon/core_ext/object.rb +19 -11
  16. data/lib/savon/core_ext/string.rb +62 -57
  17. data/lib/savon/core_ext/symbol.rb +13 -5
  18. data/lib/savon/error.rb +6 -0
  19. data/lib/savon/global.rb +75 -0
  20. data/lib/savon/http/error.rb +42 -0
  21. data/lib/savon/soap.rb +8 -283
  22. data/lib/savon/soap/fault.rb +48 -0
  23. data/lib/savon/soap/request.rb +61 -0
  24. data/lib/savon/soap/response.rb +65 -0
  25. data/lib/savon/soap/xml.rb +132 -0
  26. data/lib/savon/version.rb +2 -2
  27. data/lib/savon/wsdl/document.rb +107 -0
  28. data/lib/savon/wsdl/parser.rb +90 -0
  29. data/lib/savon/wsdl/request.rb +35 -0
  30. data/lib/savon/wsse.rb +42 -104
  31. data/savon.gemspec +26 -0
  32. data/spec/fixtures/response/response_fixture.rb +26 -26
  33. data/spec/fixtures/response/xml/list.xml +18 -0
  34. data/spec/fixtures/wsdl/wsdl_fixture.rb +6 -0
  35. data/spec/fixtures/wsdl/wsdl_fixture.yml +4 -4
  36. data/spec/savon/client_spec.rb +274 -51
  37. data/spec/savon/core_ext/datetime_spec.rb +1 -1
  38. data/spec/savon/core_ext/hash_spec.rb +40 -4
  39. data/spec/savon/core_ext/object_spec.rb +1 -1
  40. data/spec/savon/core_ext/string_spec.rb +0 -12
  41. data/spec/savon/http/error_spec.rb +52 -0
  42. data/spec/savon/savon_spec.rb +90 -0
  43. data/spec/savon/soap/fault_spec.rb +80 -0
  44. data/spec/savon/soap/request_spec.rb +45 -0
  45. data/spec/savon/soap/response_spec.rb +153 -0
  46. data/spec/savon/soap/xml_spec.rb +249 -0
  47. data/spec/savon/soap_spec.rb +4 -177
  48. data/spec/savon/{wsdl_spec.rb → wsdl/document_spec.rb} +54 -17
  49. data/spec/savon/wsdl/request_spec.rb +15 -0
  50. data/spec/savon/wsse_spec.rb +123 -92
  51. data/spec/spec_helper.rb +19 -4
  52. data/spec/support/endpoint.rb +25 -0
  53. metadata +97 -97
  54. data/.autotest +0 -5
  55. data/CHANGELOG +0 -176
  56. data/README.rdoc +0 -64
  57. data/lib/savon/core_ext.rb +0 -8
  58. data/lib/savon/core_ext/net_http.rb +0 -19
  59. data/lib/savon/core_ext/uri.rb +0 -10
  60. data/lib/savon/logger.rb +0 -56
  61. data/lib/savon/request.rb +0 -138
  62. data/lib/savon/response.rb +0 -174
  63. data/lib/savon/wsdl.rb +0 -137
  64. data/lib/savon/wsdl_stream.rb +0 -85
  65. data/spec/basic_spec_helper.rb +0 -11
  66. data/spec/endpoint_helper.rb +0 -23
  67. data/spec/http_stubs.rb +0 -26
  68. data/spec/integration/http_basic_auth_spec.rb +0 -16
  69. data/spec/integration/server.rb +0 -51
  70. data/spec/savon/core_ext/net_http_spec.rb +0 -38
  71. data/spec/savon/core_ext/uri_spec.rb +0 -19
  72. data/spec/savon/request_spec.rb +0 -117
  73. data/spec/savon/response_spec.rb +0 -179
  74. data/spec/spec.opts +0 -4
@@ -1,16 +0,0 @@
1
- require "basic_spec_helper"
2
-
3
- describe Savon do
4
- before { @client = Savon::Client.new "http://localhost:8080/http-basic-auth" }
5
-
6
- it "should be able to handle HTTP basic authentication" do
7
- @client.request.basic_auth "user", "password"
8
- response = @client.do_something!
9
- response.to_hash[:authenticate_response][:return][:success].should == true
10
- end
11
-
12
- it "should raise a Savon::HTTPError in case authentication failed" do
13
- lambda { @client.do_something! }.should raise_error(Savon::HTTPError)
14
- end
15
-
16
- end
@@ -1,51 +0,0 @@
1
- require "webrick"
2
-
3
- include WEBrick
4
-
5
- # Run WEBrick. Yields the server to a given block.
6
- def run_webrick(config = {})
7
- config.update :Port => 8080
8
- server = HTTPServer.new config
9
- yield server if block_given?
10
- ["INT", "TERM"].each { |signal| trap(signal) { server.shutdown } }
11
- server.start
12
- end
13
-
14
- # Returns the SOAP response fixture for a given +file+.
15
- def respond_with(file)
16
- response_path = File.dirname(__FILE__) + "/../fixtures/response/xml"
17
- File.read "#{response_path}/#{file}.xml"
18
- end
19
-
20
- # Returns HTML links for a given Hash of link URI's and names.
21
- def link_to(links)
22
- links.map { |link| "<a href='#{link[:uri]}'>#{link[:name]}</a>" }.join("<br>")
23
- end
24
-
25
- run_webrick do |server|
26
- user, password, realm = "user", "password", "realm"
27
-
28
- htdigest = HTTPAuth::Htdigest.new "/tmp/webrick-htdigest"
29
- htdigest.set_passwd realm, user, password
30
- authenticator = HTTPAuth::DigestAuth.new :UserDB => htdigest, :Realm => realm
31
-
32
- # Homepage including links to subpages.
33
- server.mount_proc("/") do |request, response|
34
- response.body = link_to [
35
- { :uri => "http-basic-auth", :name => "HTTP basic auth" },
36
- { :uri => "http-digest-auth", :name => "HTTP digest auth" }
37
- ]
38
- end
39
-
40
- # HTTP basic authentication.
41
- server.mount_proc("/http-basic-auth") do |request, response|
42
- HTTPAuth.basic_auth(request, response, realm) { |u, p| u == user && p == password }
43
- response.body = respond_with :authentication
44
- end
45
-
46
- # HTTP digest authentication.
47
- server.mount_proc("/http-digest-auth") do |request, response|
48
- authenticator.authenticate request, response
49
- response.body = "HTTP digest authentication successfull"
50
- end
51
- end
@@ -1,38 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Net::HTTP do
4
- before do
5
- @some_uri = URI "http://example.com"
6
- @another_uri = URI "http://example.org"
7
- @http = Net::HTTP.new @some_uri.host, @some_uri.port
8
- end
9
-
10
- describe "endpoint" do
11
- it "changes the address and port of a Net::HTTP object" do
12
- @http.address.should == @some_uri.host
13
- @http.port.should == @some_uri.port
14
-
15
- @http.endpoint @another_uri.host, @another_uri.port
16
- @http.address.should == @another_uri.host
17
- @http.port.should == @another_uri.port
18
- end
19
- end
20
-
21
- describe "ssl_client_auth" do
22
- it "accepts a Hash of options for SSL client authentication" do
23
- @http.cert.should be_nil
24
- @http.key.should be_nil
25
- @http.ca_file.should be_nil
26
- @http.verify_mode.should be_nil
27
-
28
- @http.ssl_client_auth :cert => "cert", :key => "key",
29
- :ca_file => "ca_file", :verify_mode => OpenSSL::SSL::VERIFY_PEER
30
-
31
- @http.cert.should == "cert"
32
- @http.key.should == "key"
33
- @http.ca_file.should == "ca_file"
34
- @http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
35
- end
36
- end
37
-
38
- end
@@ -1,19 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe URI::HTTP do
4
-
5
- describe "ssl?" do
6
- it "returns true for https URI's" do
7
- URI("https://example.com").ssl?.should be_true
8
- end
9
-
10
- it "returns false for non-https URI's" do
11
- URI("http://example.com").ssl?.should be_false
12
- end
13
-
14
- it "returns nil for invalid URI's without a scheme" do
15
- URI("example").ssl?.should be_nil
16
- end
17
- end
18
-
19
- end
@@ -1,117 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::Request do
4
- before { @request = Savon::Request.new EndpointHelper.wsdl_endpoint }
5
-
6
- it "contains the ContentType for each supported SOAP version" do
7
- content_type = { 1 => "text/xml;charset=UTF-8", 2 => "application/soap+xml;charset=UTF-8" }
8
- content_type.each { |version, type| Savon::Request::ContentType[version].should == type }
9
- end
10
-
11
- # defaults to log request and response. disabled for spec execution
12
-
13
- it "has both getter and setter for whether to log (global setting)" do
14
- Savon::Request.log = true
15
- Savon::Request.log?.should be_true
16
- Savon::Request.log = false
17
- Savon::Request.log?.should be_false
18
- end
19
-
20
- it "defaults to use a Logger instance for logging" do
21
- Savon::Request.logger.should be_a(Logger)
22
- end
23
-
24
- it "has both getter and setter for the logger to use (global setting)" do
25
- Savon::Request.logger = {}
26
- Savon::Request.logger.should be_a(Hash)
27
- Savon::Request.logger = Logger.new STDOUT
28
- end
29
-
30
- it "defaults to :debug for logging" do
31
- Savon::Request.log_level.should == :debug
32
- end
33
-
34
- it "has both getter and setter for the log level to use (global setting)" do
35
- Savon::Request.log_level = :info
36
- Savon::Request.log_level.should == :info
37
- Savon::Request.log_level = :debug
38
- end
39
-
40
- it "is initialized with a SOAP endpoint String" do
41
- Savon::Request.new EndpointHelper.wsdl_endpoint
42
- end
43
-
44
- it "has a getter for the SOAP endpoint URI" do
45
- @request.endpoint.should == URI(EndpointHelper.wsdl_endpoint)
46
- end
47
-
48
- it "should have a getter for the proxy URI" do
49
- @request.proxy.should == URI("")
50
- end
51
-
52
- it "should have a getter for the HTTP headers which defaults to an empty Hash" do
53
- @request.headers.should == {}
54
- end
55
-
56
- it "should have a setter for the HTTP headers" do
57
- headers = { "some" => "thing" }
58
-
59
- @request.headers = headers
60
- @request.headers.should == headers
61
- end
62
-
63
- it "should return the Net::HTTP object" do
64
- @request.http.should be_kind_of(Net::HTTP)
65
- end
66
-
67
- it "should have a method for setting HTTP basic auth credentials" do
68
- @request.basic_auth "user", "password"
69
- end
70
-
71
- it "retrieves the WSDL document and returns the Net::HTTP response" do
72
- wsdl_response = @request.wsdl
73
-
74
- wsdl_response.should be_a(Net::HTTPResponse)
75
- wsdl_response.body.should == WSDLFixture.authentication
76
- end
77
-
78
-
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
110
- end
111
-
112
- it "should not include host when creating HTTP requests" do
113
- request = @request.send(:request, :wsdl)
114
- request.path.should_not include("example.com")
115
- end
116
-
117
- end
@@ -1,179 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::Response do
4
- before { @response = Savon::Response.new http_response_mock }
5
-
6
- it "defaults to raises both Savon::SOAPFault and Savon::HTTPError" do
7
- Savon::Response.raise_errors?.should be_true
8
- end
9
-
10
- it "has both getter and setter for whether to raise errors (global setting)" do
11
- Savon::Response.raise_errors = false
12
- Savon::Response.raise_errors?.should == false
13
- Savon::Response.raise_errors = true
14
- end
15
-
16
- describe "initialize" do
17
- it "expects a Net::HTTPResponse" do
18
- Savon::Response.new http_response_mock
19
- end
20
-
21
- it "raises a Savon::SOAPFault in case of a SOAP fault" do
22
- lambda { savon_response_with :soap_fault }.should raise_error(Savon::SOAPFault)
23
- end
24
-
25
- it "does not raise a Savon::SOAPFault in case the default is turned off" do
26
- Savon::Response.raise_errors = false
27
- savon_response_with :soap_fault
28
- Savon::Response.raise_errors = true
29
- end
30
-
31
- it "raises a Savon::HTTPError in case of an HTTP error" do
32
- lambda { savon_response_with :http_error }.should raise_error(Savon::HTTPError)
33
- end
34
-
35
- it "does not raise a Savon::HTTPError in case the default is turned off" do
36
- Savon::Response.raise_errors = false
37
- savon_response_with :http_error
38
- Savon::Response.raise_errors = true
39
- end
40
- end
41
-
42
- describe "soap_fault?" do
43
- before { Savon::Response.raise_errors = false }
44
-
45
- it "does not return true in case the response seems to be ok" do
46
- @response.soap_fault?.should_not be_true
47
- end
48
-
49
- it "returns true in case of a SOAP fault" do
50
- savon_response_with(:soap_fault).soap_fault?.should be_true
51
- end
52
-
53
- after { Savon::Response.raise_errors = true }
54
- end
55
-
56
- describe "soap_fault" do
57
- before { Savon::Response.raise_errors = false }
58
-
59
- it "returns the SOAP fault message in case of a SOAP fault" do
60
- savon_response_with(:soap_fault).soap_fault.
61
- should == "(soap:Server) Fault occurred while processing."
62
- end
63
-
64
- it "returns the SOAP fault message in case of a SOAP 1.2 fault" do
65
- savon_response_with(:soap_fault12).soap_fault.
66
- should == "(soap:Sender) Sender Timeout"
67
- end
68
-
69
- after { Savon::Response.raise_errors = true }
70
- end
71
-
72
- describe "http_error?" do
73
- before { Savon::Response.raise_errors = false }
74
-
75
- it "does not return true in case the response seems to be ok" do
76
- @response.http_error?.should_not be_true
77
- end
78
-
79
- it "returns true in case of an HTTP error" do
80
- savon_response_with(:http_error).http_error?.should be_true
81
- end
82
-
83
- after { Savon::Response.raise_errors = true }
84
- end
85
-
86
- describe "http_error" do
87
- before { Savon::Response.raise_errors = false }
88
-
89
- it "returns the HTTP error message in case of an HTTP error" do
90
- savon_response_with(:http_error).http_error.should == "Not found (404)"
91
- end
92
-
93
- after { Savon::Response.raise_errors = true }
94
- end
95
-
96
- it "should return the SOAP response body as a Hash" do
97
- @response.to_hash[:authenticate_response][:return].should ==
98
- ResponseFixture.authentication(:to_hash)
99
- end
100
-
101
- it "should return a Hash for a SOAP multiRef response" do
102
- @response = Savon::Response.new http_response_mock(200, ResponseFixture.multi_ref, "OK")
103
-
104
- @response.to_hash[:list_response].should be_a(Hash)
105
- @response.to_hash[:multi_ref].should be_an(Array)
106
- end
107
-
108
- it "should return the raw SOAP response body" do
109
- @response.to_xml.should == ResponseFixture.authentication
110
- @response.to_s.should == ResponseFixture.authentication
111
- end
112
-
113
- it "should return the Net::HTTP response object" do
114
- @response.http.should be_a(Mocha::Mock)
115
- @response.http.should respond_to(:code)
116
- @response.http.should respond_to(:message)
117
- @response.http.should respond_to(:body)
118
- end
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
-
158
- def savon_response_with(error_type)
159
- mock = case error_type
160
- when :soap_fault then http_response_mock 200, ResponseFixture.soap_fault
161
- when :soap_fault12 then http_response_mock 200, ResponseFixture.soap_fault12
162
- when :http_error then http_response_mock 404, "", "Not found"
163
- end
164
- Savon::Response.new mock
165
- end
166
-
167
- def http_response_mock(code = 200, body = nil, message = "OK", headers = {})
168
- body ||= ResponseFixture.authentication
169
- mock = mock "Net::HTTPResponse"
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
-
175
- mock
176
- end
177
-
178
- end
179
-
@@ -1,4 +0,0 @@
1
- --colour
2
- --format progress
3
- --loadby mtime
4
- --reverse