savon 0.7.9 → 0.8.0.beta.1

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