julianmorrison-savon 0.6.8

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 +92 -0
  2. data/README.textile +71 -0
  3. data/Rakefile +27 -0
  4. data/lib/savon.rb +34 -0
  5. data/lib/savon/client.rb +84 -0
  6. data/lib/savon/core_ext.rb +3 -0
  7. data/lib/savon/core_ext/datetime.rb +8 -0
  8. data/lib/savon/core_ext/hash.rb +78 -0
  9. data/lib/savon/core_ext/object.rb +21 -0
  10. data/lib/savon/core_ext/string.rb +47 -0
  11. data/lib/savon/core_ext/symbol.rb +8 -0
  12. data/lib/savon/core_ext/uri.rb +10 -0
  13. data/lib/savon/request.rb +159 -0
  14. data/lib/savon/response.rb +108 -0
  15. data/lib/savon/soap.rb +138 -0
  16. data/lib/savon/wsdl.rb +122 -0
  17. data/lib/savon/wsse.rb +122 -0
  18. data/spec/endpoint_helper.rb +22 -0
  19. data/spec/fixtures/response/response_fixture.rb +32 -0
  20. data/spec/fixtures/response/xml/authentication.xml +14 -0
  21. data/spec/fixtures/response/xml/soap_fault.xml +8 -0
  22. data/spec/fixtures/response/xml/soap_fault12.xml +18 -0
  23. data/spec/fixtures/wsdl/wsdl_fixture.rb +37 -0
  24. data/spec/fixtures/wsdl/xml/authentication.xml +63 -0
  25. data/spec/fixtures/wsdl/xml/namespaced_actions.xml +307 -0
  26. data/spec/fixtures/wsdl/xml/no_namespace.xml +115 -0
  27. data/spec/http_stubs.rb +23 -0
  28. data/spec/savon/client_spec.rb +83 -0
  29. data/spec/savon/core_ext/datetime_spec.rb +12 -0
  30. data/spec/savon/core_ext/hash_spec.rb +134 -0
  31. data/spec/savon/core_ext/object_spec.rb +40 -0
  32. data/spec/savon/core_ext/string_spec.rb +68 -0
  33. data/spec/savon/core_ext/symbol_spec.rb +11 -0
  34. data/spec/savon/core_ext/uri_spec.rb +15 -0
  35. data/spec/savon/request_spec.rb +124 -0
  36. data/spec/savon/response_spec.rb +122 -0
  37. data/spec/savon/savon_spec.rb +23 -0
  38. data/spec/savon/soap_spec.rb +131 -0
  39. data/spec/savon/wsdl_spec.rb +84 -0
  40. data/spec/savon/wsse_spec.rb +132 -0
  41. data/spec/spec_helper.rb +16 -0
  42. metadata +166 -0
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe Symbol do
4
+
5
+ describe "to_soap_key" do
6
+ it "converts the Symbol from snake_case to a lowerCamelCase String" do
7
+ :lower_camel_case.to_soap_key.should == "lowerCamelCase"
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,15 @@
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
+ end
14
+
15
+ end
@@ -0,0 +1,124 @@
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
+ Savon::SOAPVersions.each do |soap_version|
8
+ Savon::Request::ContentType[soap_version].should be_a(String)
9
+ Savon::Request::ContentType[soap_version].should_not be_empty
10
+ end
11
+ end
12
+
13
+ # defaults to log request and response. disabled for spec execution
14
+
15
+ it "has both getter and setter for whether to log (global setting)" do
16
+ Savon::Request.log = true
17
+ Savon::Request.log?.should be_true
18
+ Savon::Request.log = false
19
+ Savon::Request.log?.should be_false
20
+ end
21
+
22
+ it "defaults to use a Logger instance for logging" do
23
+ Savon::Request.logger.should be_a(Logger)
24
+ end
25
+
26
+ it "has both getter and setter for the logger to use (global setting)" do
27
+ Savon::Request.logger = nil
28
+ Savon::Request.logger.should be_nil
29
+ Savon::Request.logger = Logger.new STDOUT
30
+ end
31
+
32
+ it "defaults to :debug for logging" do
33
+ Savon::Request.log_level.should == :debug
34
+ end
35
+
36
+ it "has both getter and setter for the log level to use (global setting)" do
37
+ Savon::Request.log_level = :info
38
+ Savon::Request.log_level.should == :info
39
+ Savon::Request.log_level = :debug
40
+ end
41
+
42
+ it "is initialized with a SOAP endpoint String" do
43
+ Savon::Request.new EndpointHelper.wsdl_endpoint
44
+ end
45
+
46
+ it "ccepts an optional proxy URI passed in via options" do
47
+ Savon::Request.new EndpointHelper.wsdl_endpoint, :proxy => "http://localhost:8080"
48
+ end
49
+
50
+ it "has a getter for the SOAP endpoint URI" do
51
+ @request.endpoint.should == URI(EndpointHelper.wsdl_endpoint)
52
+ end
53
+
54
+ it "should have a getter for the proxy URI" do
55
+ @request.proxy.should == URI("")
56
+ end
57
+
58
+ it "has a setter for specifying an open_timeout" do
59
+ @request.open_timeout = 30
60
+ end
61
+
62
+ it "has a setter for specifying a read_timeout" do
63
+ @request.read_timeout = 30
64
+ end
65
+
66
+ it "retrieves the WSDL document and returns the Net::HTTPResponse" do
67
+ wsdl_response = @request.wsdl
68
+
69
+ wsdl_response.should be_a(Net::HTTPResponse)
70
+ wsdl_response.body.should == WSDLFixture.authentication
71
+ end
72
+
73
+ it "executes a SOAP request and returns the Net::HTTPResponse" do
74
+ soap = Savon::SOAP.new
75
+ soap.endpoint = URI EndpointHelper.wsdl_endpoint
76
+ soap_response = @request.soap soap
77
+
78
+ soap_response.should be_a(Net::HTTPResponse)
79
+ soap_response.body.should == ResponseFixture.authentication
80
+ end
81
+
82
+ describe "Savon::Request SSL" do
83
+ before { @request.class.class_eval { public "http" } }
84
+
85
+ it "defaults to not setting ssl parameters" do
86
+ http = @request.http
87
+ http.cert.should be_nil
88
+ http.key.should be_nil
89
+ http.ca_file.should be_nil
90
+ http.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
91
+ end
92
+
93
+ it "sets client cert in http object when set in request constructor" do
94
+ request = Savon::Request.new(EndpointHelper.wsdl_endpoint, :ssl => {
95
+ :client_cert => "client cert"
96
+ })
97
+ request.http.cert.should == "client cert"
98
+ end
99
+
100
+ it "sets ca cert in http object when set in request constructor" do
101
+ request = Savon::Request.new(EndpointHelper.wsdl_endpoint, :ssl => {
102
+ :client_key => "client key"
103
+ })
104
+ request.http.key.should == "client key"
105
+ end
106
+
107
+ it "sets client cert in http object when set in request constructor" do
108
+ request = Savon::Request.new(EndpointHelper.wsdl_endpoint, :ssl => {
109
+ :ca_file => "ca file"
110
+ })
111
+ request.http.ca_file.should == "ca file"
112
+ end
113
+
114
+ it "sets client cert in http object when set in request constructor" do
115
+ request = Savon::Request.new(EndpointHelper.wsdl_endpoint, :ssl => {
116
+ :verify => OpenSSL::SSL::VERIFY_PEER
117
+ })
118
+ request.http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
119
+ end
120
+
121
+ after { @request.class.class_eval { private "http" } }
122
+ end
123
+
124
+ end
@@ -0,0 +1,122 @@
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 "can return the SOAP response body as a Hash" do
97
+ @response.to_hash[:return].should == ResponseFixture.authentication(:to_hash)
98
+ end
99
+
100
+ it "can return the raw SOAP response body" do
101
+ @response.to_xml.should == ResponseFixture.authentication
102
+ @response.to_s.should == ResponseFixture.authentication
103
+ end
104
+
105
+ def savon_response_with(error_type)
106
+ mock = case error_type
107
+ when :soap_fault then http_response_mock 200, ResponseFixture.soap_fault
108
+ when :soap_fault12 then http_response_mock 200, ResponseFixture.soap_fault12
109
+ when :http_error then http_response_mock 404, "", "Not found"
110
+ end
111
+ Savon::Response.new mock
112
+ end
113
+
114
+ def http_response_mock(code = 200, body = nil, message = "OK")
115
+ body ||= ResponseFixture.authentication
116
+ mock = mock "Net::HTTPResponse"
117
+ mock.stubs :code => code.to_s, :message => message,
118
+ :content_type => "text/html", :body => body
119
+ mock
120
+ end
121
+
122
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon do
4
+
5
+ it "contains an Array of supported SOAP versions" do
6
+ Savon::SOAPVersions.should be_an(Array)
7
+ Savon::SOAPVersions.should_not be_empty
8
+ end
9
+
10
+ it "contains the xs:dateTime format" do
11
+ Savon::SOAPDateTimeFormat.should be_a(String)
12
+ Savon::SOAPDateTimeFormat.should_not be_empty
13
+
14
+ DateTime.new(2012, 03, 22, 16, 22, 33).strftime(Savon::SOAPDateTimeFormat).
15
+ should == "2012-03-22T16:22:33"
16
+ end
17
+
18
+ it "contains a Regexp matching the xs:dateTime format" do
19
+ Savon::SOAPDateTimeRegexp.should be_a(Regexp)
20
+ (Savon::SOAPDateTimeRegexp === "2012-03-22T16:22:33").should be_true
21
+ end
22
+
23
+ end
@@ -0,0 +1,131 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::SOAP do
4
+ before do
5
+ @soap = Savon::SOAP.new
6
+ @soap.action = WSDLFixture.authentication(:operations)[:authenticate][:action]
7
+ end
8
+
9
+ it "contains the SOAP namespace for each supported SOAP version" do
10
+ Savon::SOAPVersions.each do |soap_version|
11
+ Savon::SOAP::SOAPNamespace[soap_version].should be_a(String)
12
+ Savon::SOAP::SOAPNamespace[soap_version].should_not be_empty
13
+ end
14
+ end
15
+
16
+ it "contains the Content-Types for each supported SOAP version" do
17
+ Savon::SOAPVersions.each do |soap_version|
18
+ Savon::SOAP::ContentType[soap_version].should be_a(String)
19
+ Savon::SOAP::ContentType[soap_version].should_not be_empty
20
+ end
21
+ end
22
+
23
+ it "defaults to SOAP 1.1" do
24
+ Savon::SOAP.version.should == 1
25
+ end
26
+
27
+ it "has both getter and setter for the SOAP version to use (global setting)" do
28
+ [2, 1].each do |soap_version|
29
+ Savon::SOAP.version = soap_version
30
+ Savon::SOAP.version.should == soap_version
31
+ end
32
+ end
33
+
34
+ it "has a setter for the Savon::WSSE" do
35
+ @soap.wsse = Savon::WSSE.new
36
+ end
37
+
38
+ it "is has both getter and setter for the SOAP action" do
39
+ @soap.action.should == WSDLFixture.authentication(:operations)[:authenticate][:action]
40
+
41
+ @soap.action = "someAction"
42
+ @soap.action.should == "someAction"
43
+ end
44
+
45
+ it "has a setter for the SOAP input" do
46
+ @soap.input = "FindUserRequest"
47
+ end
48
+
49
+ it "has both getter and setter for the SOAP header" do
50
+ @soap.header.should be_a(Hash)
51
+ @soap.header.should be_empty
52
+
53
+ @soap.header = { "specialAuthKey" => "secret" }
54
+ @soap.header.should == { "specialAuthKey" => "secret" }
55
+ end
56
+
57
+ it "has a getter for the SOAP body, expecting a Hash or an XML String" do
58
+ @soap.body = { :id => 666 }
59
+ @soap.body = "<id>666</id>"
60
+ end
61
+
62
+ it "has a setter for specifying a Hash of namespaces" do
63
+ namespaces = { "xmlns:env" => "http://example.com" }
64
+ @soap.namespaces = namespaces
65
+ @soap.namespaces.should == namespaces
66
+ end
67
+
68
+ describe "has a getter for namespaces" do
69
+ it "which defaults to include the SOAP 1.1 namespace" do
70
+ @soap.namespaces.should == { "xmlns:env" => Savon::SOAP::SOAPNamespace[1] }
71
+ end
72
+
73
+ it "which contains the SOAP 1.2 namespace if specified" do
74
+ @soap.version = 2
75
+ @soap.namespaces.should == { "xmlns:env" => Savon::SOAP::SOAPNamespace[2] }
76
+ end
77
+ end
78
+
79
+ it "has a convenience method for setting the 'xmlns:wsdl' namespace" do
80
+ @soap.namespaces.should == { "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/" }
81
+
82
+ @soap.namespace = "http://example.com"
83
+ @soap.namespaces.should include("xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/")
84
+ @soap.namespaces.should include("xmlns:wsdl" => "http://example.com")
85
+ end
86
+
87
+ it "has both getter and setter for the SOAP endpoint" do
88
+ @soap.endpoint.should be_nil
89
+
90
+ soap_endpoint = URI EndpointHelper.soap_endpoint
91
+ @soap.endpoint = soap_endpoint
92
+ @soap.endpoint.should == soap_endpoint
93
+ end
94
+
95
+ it "has a getter for the SOAP version to use which defaults to SOAP 1.1" do
96
+ @soap.version.should == Savon::SOAP.version
97
+ end
98
+
99
+ it "has a setter for specifying the SOAP version to use" do
100
+ @soap.version = 2
101
+ @soap.version.should == 2
102
+ end
103
+
104
+ describe "to_xml" do
105
+ after { Savon::SOAP.version = 1 }
106
+
107
+ it "returns the XML for a SOAP request" do
108
+ @soap.namespaces["xmlns:wsdl"] = "http://v1_0.ws.auth.order.example.com/"
109
+ @soap.body = { :id => 666 }
110
+
111
+ @soap.to_xml.should include('xmlns:wsdl="http://v1_0.ws.auth.order.example.com/"')
112
+ @soap.to_xml.should include('xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"')
113
+ @soap.to_xml.should include('<wsdl:authenticate><id>666</id></wsdl:authenticate>')
114
+ end
115
+
116
+ it "caches the XML, returning the same Object every time" do
117
+ @soap.to_xml.object_id.should == @soap.to_xml.object_id
118
+ end
119
+
120
+ it "uses the SOAP namespace for the specified SOAP version" do
121
+ @soap.version = 2
122
+ @soap.to_xml.should include(Savon::SOAP::SOAPNamespace[2])
123
+ end
124
+
125
+ it "uses the SOAP namespace for the default SOAP version otherwise" do
126
+ Savon::SOAP.version = 2
127
+ @soap.to_xml.should include(Savon::SOAP::SOAPNamespace[2])
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,84 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::WSDL do
4
+ describe "a common WSDL document" do
5
+ before { @wsdl = new_wsdl }
6
+
7
+ it "is initialized with a Savon::Request object" do
8
+ Savon::WSDL.new Savon::Request.new(EndpointHelper.wsdl_endpoint)
9
+ end
10
+
11
+ it "is enabled by default" do
12
+ @wsdl.enabled?.should be_true
13
+ end
14
+
15
+ it "has a getter for the namespace URI" do
16
+ @wsdl.namespace_uri.should == WSDLFixture.authentication(:namespace_uri)
17
+ end
18
+
19
+ it "has a getter for returning an Array of available SOAP actions" do
20
+ WSDLFixture.authentication(:operations).keys.each do |soap_action|
21
+ @wsdl.soap_actions.should include(soap_action)
22
+ end
23
+ end
24
+
25
+ it "has a getter for returning a Hash of available SOAP operations" do
26
+ @wsdl.operations.should == WSDLFixture.authentication(:operations)
27
+ end
28
+
29
+ it "responds to SOAP actions while still behaving as usual otherwise" do
30
+ WSDLFixture.authentication(:operations).keys.each do |soap_action|
31
+ @wsdl.respond_to?(soap_action).should be_true
32
+ end
33
+
34
+ @wsdl.respond_to?(:object_id).should be_true
35
+ @wsdl.respond_to?(:some_undefined_method).should be_false
36
+ end
37
+
38
+ it "returns the raw WSDL document for to_s" do
39
+ @wsdl.to_s.should == WSDLFixture.authentication
40
+ end
41
+ end
42
+
43
+ describe "a WSDL document having core sections without a namespace" do
44
+ before { @wsdl = new_wsdl :no_namespace }
45
+
46
+ it "returns the namespace URI" do
47
+ @wsdl.namespace_uri.should == WSDLFixture.no_namespace(:namespace_uri)
48
+ end
49
+
50
+ it "returns an Array of available SOAP actions" do
51
+ WSDLFixture.no_namespace(:operations).keys.each do |soap_action|
52
+ @wsdl.soap_actions.should include(soap_action)
53
+ end
54
+ end
55
+
56
+ it "returns a Hash of SOAP operations" do
57
+ @wsdl.operations.should == WSDLFixture.no_namespace(:operations)
58
+ end
59
+ end
60
+
61
+ describe "a WSDL document with namespaced SOAP actions" do
62
+ before { @wsdl = new_wsdl :namespaced_actions }
63
+
64
+ it "returns the namespace URI" do
65
+ @wsdl.namespace_uri.should == WSDLFixture.namespaced_actions(:namespace_uri)
66
+ end
67
+
68
+ it "returns an Array of available SOAP actions" do
69
+ WSDLFixture.namespaced_actions(:operations).keys.each do |soap_action|
70
+ @wsdl.soap_actions.should include(soap_action)
71
+ end
72
+ end
73
+
74
+ it "returns a Hash of SOAP operations" do
75
+ @wsdl.operations.should == WSDLFixture.namespaced_actions(:operations)
76
+ end
77
+ end
78
+
79
+ def new_wsdl(fixture = nil)
80
+ endpoint = fixture ? EndpointHelper.wsdl_endpoint(fixture) : EndpointHelper.wsdl_endpoint
81
+ Savon::WSDL.new Savon::Request.new(endpoint)
82
+ end
83
+
84
+ end