savon 0.6.0 → 0.7.0

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 (51) hide show
  1. data/CHANGELOG +112 -0
  2. data/README.textile +42 -35
  3. data/Rakefile +28 -33
  4. data/lib/savon/client.rb +42 -19
  5. data/lib/savon/core_ext/hash.rb +35 -22
  6. data/lib/savon/core_ext/net_http.rb +20 -0
  7. data/lib/savon/core_ext/object.rb +7 -0
  8. data/lib/savon/core_ext/string.rb +1 -1
  9. data/lib/savon/core_ext.rb +2 -2
  10. data/lib/savon/request.rb +73 -33
  11. data/lib/savon/response.rb +23 -36
  12. data/lib/savon/soap.rb +63 -30
  13. data/lib/savon/wsdl.rb +82 -35
  14. data/lib/savon/wsse.rb +41 -35
  15. data/lib/savon.rb +3 -2
  16. data/spec/basic_spec_helper.rb +12 -0
  17. data/spec/endpoint_helper.rb +22 -0
  18. data/spec/fixtures/response/response_fixture.rb +36 -0
  19. data/spec/fixtures/response/xml/authentication.xml +14 -0
  20. data/spec/fixtures/response/xml/multi_ref.xml +39 -0
  21. data/spec/fixtures/response/xml/soap_fault12.xml +18 -0
  22. data/spec/fixtures/wsdl/wsdl_fixture.rb +37 -0
  23. data/spec/fixtures/wsdl/xml/authentication.xml +63 -0
  24. data/spec/fixtures/wsdl/xml/namespaced_actions.xml +307 -0
  25. data/spec/fixtures/wsdl/xml/no_namespace.xml +115 -0
  26. data/spec/http_stubs.rb +17 -19
  27. data/spec/integration/http_basic_auth_spec.rb +12 -0
  28. data/spec/integration/server.rb +51 -0
  29. data/spec/savon/client_spec.rb +52 -44
  30. data/spec/savon/core_ext/datetime_spec.rb +2 -2
  31. data/spec/savon/core_ext/hash_spec.rb +34 -31
  32. data/spec/savon/core_ext/net_http_spec.rb +38 -0
  33. data/spec/savon/core_ext/object_spec.rb +16 -2
  34. data/spec/savon/core_ext/string_spec.rb +4 -4
  35. data/spec/savon/core_ext/symbol_spec.rb +1 -1
  36. data/spec/savon/core_ext/uri_spec.rb +1 -1
  37. data/spec/savon/request_spec.rb +49 -63
  38. data/spec/savon/response_spec.rb +48 -51
  39. data/spec/savon/savon_spec.rb +12 -19
  40. data/spec/savon/soap_spec.rb +81 -90
  41. data/spec/savon/wsdl_spec.rb +62 -30
  42. data/spec/savon/wsse_spec.rb +58 -84
  43. data/spec/spec_helper.rb +3 -13
  44. metadata +29 -15
  45. data/VERSION +0 -1
  46. data/spec/fixtures/multiple_user_response.xml +0 -22
  47. data/spec/fixtures/user_fixture.rb +0 -54
  48. data/spec/fixtures/user_response.xml +0 -15
  49. data/spec/fixtures/user_wsdl.xml +0 -124
  50. data/spec/spec_helper_methods.rb +0 -33
  51. /data/spec/fixtures/{soap_fault.xml → response/xml/soap_fault.xml} +0 -0
@@ -0,0 +1,115 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <definitions name="Api" xmlns:typens="urn:ActionWebService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="urn:ActionWebService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/">
3
+ <types>
4
+ <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ActionWebService">
5
+ <xsd:complexType name="MpUser">
6
+ <xsd:all>
7
+ <xsd:element name="avatar_thumb_url" type="xsd:string"/>
8
+ <xsd:element name="speciality" type="xsd:string"/>
9
+ <xsd:element name="avatar_icon_url" type="xsd:string"/>
10
+ <xsd:element name="firstname" type="xsd:string"/>
11
+ <xsd:element name="city" type="xsd:string"/>
12
+ <xsd:element name="mp_id" type="xsd:int"/>
13
+ <xsd:element name="lastname" type="xsd:string"/>
14
+ <xsd:element name="login" type="xsd:string"/>
15
+ </xsd:all>
16
+ </xsd:complexType>
17
+ <xsd:complexType name="MpUserArray">
18
+ <xsd:complexContent>
19
+ <xsd:restriction base="soapenc:Array">
20
+ <xsd:attribute wsdl:arrayType="typens:MpUser[]" ref="soapenc:arrayType"/>
21
+ </xsd:restriction>
22
+ </xsd:complexContent>
23
+ </xsd:complexType>
24
+ <xsd:complexType name="McContact">
25
+ <xsd:all>
26
+ <xsd:element name="last_name" type="xsd:string"/>
27
+ <xsd:element name="email" type="xsd:string"/>
28
+ <xsd:element name="mp_id" type="xsd:int"/>
29
+ <xsd:element name="role" type="xsd:int"/>
30
+ <xsd:element name="login" type="xsd:string"/>
31
+ <xsd:element name="first_name" type="xsd:string"/>
32
+ </xsd:all>
33
+ </xsd:complexType>
34
+ <xsd:complexType name="McContactArray">
35
+ <xsd:complexContent>
36
+ <xsd:restriction base="soapenc:Array">
37
+ <xsd:attribute wsdl:arrayType="typens:McContact[]" ref="soapenc:arrayType"/>
38
+ </xsd:restriction>
39
+ </xsd:complexContent>
40
+ </xsd:complexType>
41
+ </xsd:schema>
42
+ </types>
43
+ <message name="GetUserLoginById">
44
+ <part name="api_key" type="xsd:string"/>
45
+ <part name="id" type="xsd:int"/>
46
+ </message>
47
+ <message name="GetUserLoginByIdResponse">
48
+ <part name="return" type="xsd:string"/>
49
+ </message>
50
+ <message name="GetAllContacts">
51
+ <part name="api_key" type="xsd:string"/>
52
+ <part name="login" type="xsd:string"/>
53
+ </message>
54
+ <message name="GetAllContactsResponse">
55
+ <part name="return" type="typens:McContactArray"/>
56
+ </message>
57
+ <message name="SearchUser">
58
+ <part name="api_key" type="xsd:string"/>
59
+ <part name="phrase" type="xsd:string"/>
60
+ <part name="page" type="xsd:string"/>
61
+ <part name="per_page" type="xsd:string"/>
62
+ </message>
63
+ <message name="SearchUserResponse">
64
+ <part name="return" type="typens:MpUserArray"/>
65
+ </message>
66
+ <portType name="ApiApiPort">
67
+ <operation name="GetUserLoginById">
68
+ <input message="typens:GetUserLoginById"/>
69
+ <output message="typens:GetUserLoginByIdResponse"/>
70
+ </operation>
71
+ <operation name="GetAllContacts">
72
+ <input message="typens:GetAllContacts"/>
73
+ <output message="typens:GetAllContactsResponse"/>
74
+ </operation>
75
+ <operation name="SearchUser">
76
+ <input message="typens:SearchUser"/>
77
+ <output message="typens:SearchUserResponse"/>
78
+ </operation>
79
+ </portType>
80
+ <binding name="ApiApiBinding" type="typens:ApiApiPort">
81
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
82
+ <operation name="GetUserLoginById">
83
+ <soap:operation soapAction="/api/api/GetUserLoginById"/>
84
+ <input>
85
+ <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:ActionWebService" use="encoded"/>
86
+ </input>
87
+ <output>
88
+ <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:ActionWebService" use="encoded"/>
89
+ </output>
90
+ </operation>
91
+ <operation name="GetAllContacts">
92
+ <soap:operation soapAction="/api/api/GetAllContacts"/>
93
+ <input>
94
+ <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:ActionWebService" use="encoded"/>
95
+ </input>
96
+ <output>
97
+ <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:ActionWebService" use="encoded"/>
98
+ </output>
99
+ </operation>
100
+ <operation name="SearchUser">
101
+ <soap:operation soapAction="/api/api/SearchUser"/>
102
+ <input>
103
+ <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:ActionWebService" use="encoded"/>
104
+ </input>
105
+ <output>
106
+ <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:ActionWebService" use="encoded"/>
107
+ </output>
108
+ </operation>
109
+ </binding>
110
+ <service name="ApiService">
111
+ <port name="ApiApiPort" binding="typens:ApiApiBinding">
112
+ <soap:address location="http://example.com/api/api"/>
113
+ </port>
114
+ </service>
115
+ </definitions>
data/spec/http_stubs.rb CHANGED
@@ -1,25 +1,23 @@
1
- require "fakeweb"
2
-
3
1
  FakeWeb.allow_net_connect = false
4
2
 
5
- # Register fake WSDL and SOAP request.
6
- FakeWeb.register_uri :get, SpecHelper.some_endpoint, :body => UserFixture.user_wsdl
7
- FakeWeb.register_uri :post, SpecHelper.soap_call_endpoint, :body => UserFixture.user_response
3
+ # Some WSDL and SOAP request.
4
+ FakeWeb.register_uri :get, EndpointHelper.wsdl_endpoint, :body => WSDLFixture.authentication
5
+ FakeWeb.register_uri :post, EndpointHelper.soap_endpoint, :body => ResponseFixture.authentication
6
+
7
+ # WSDL and SOAP request with a Savon::SOAPFault.
8
+ FakeWeb.register_uri :get, EndpointHelper.wsdl_endpoint(:soap_fault), :body => WSDLFixture.authentication
9
+ FakeWeb.register_uri :post, EndpointHelper.soap_endpoint(:soap_fault), :body => ResponseFixture.soap_fault
8
10
 
9
- # Register fake WSDL and SOAP request with multiple "//return" nodes.
10
- FakeWeb.register_uri :get, SpecHelper.multiple_endpoint, :body => UserFixture.user_wsdl
11
- FakeWeb.register_uri :post, SpecHelper.soap_multiple_endpoint, :body => UserFixture.multiple_user_response
11
+ # WSDL and SOAP request with a Savon::HTTPError.
12
+ FakeWeb.register_uri :get, EndpointHelper.wsdl_endpoint(:http_error), :body => WSDLFixture.authentication
13
+ FakeWeb.register_uri :post, EndpointHelper.soap_endpoint(:http_error), :body => "", :status => ["404", "Not Found"]
12
14
 
13
- # Register fake WSDL and SOAP request for a Savon::SOAPFault.
14
- FakeWeb.register_uri :get, SpecHelper.soapfault_endpoint, :body => UserFixture.user_wsdl
15
- FakeWeb.register_uri :post, SpecHelper.soap_soapfault_endpoint, :body => UserFixture.soap_fault
15
+ # WSDL and SOAP request with an invalid endpoint.
16
+ FakeWeb.register_uri :get, EndpointHelper.wsdl_endpoint(:invalid), :body => ""
17
+ FakeWeb.register_uri :post, EndpointHelper.soap_endpoint(:invalid), :body => "", :status => ["404", "Not Found"]
16
18
 
17
- # Register fake WSDL and SOAP request for a Savon::HTTPError.
18
- FakeWeb.register_uri :get, SpecHelper.httperror_endpoint, :body => UserFixture.user_wsdl
19
- FakeWeb.register_uri :post, SpecHelper.soap_httperror_endpoint, :body => "",
20
- :status => ["404", "Not Found"]
19
+ # WSDL request returning a WSDL document where the main sections are not namespaced.
20
+ FakeWeb.register_uri :get, EndpointHelper.wsdl_endpoint(:no_namespace), :body => WSDLFixture.no_namespace
21
21
 
22
- # Register fake WSDL and SOAP request for an invalid endpoint.
23
- FakeWeb.register_uri :get, SpecHelper.invalid_endpoint, :body => ""
24
- FakeWeb.register_uri :post, SpecHelper.soap_invalid_endpoint, :body => "",
25
- :status => ["404", "Not Found"]
22
+ # WSDL request returning a WSDL document with namespaced SOAP actions.
23
+ FakeWeb.register_uri :get, EndpointHelper.wsdl_endpoint(:namespaced_actions), :body => WSDLFixture.namespaced_actions
@@ -0,0 +1,12 @@
1
+ require "basic_spec_helper"
2
+
3
+ describe Savon do
4
+ before { @endpoint = "http://localhost:8080/http-basic-auth" }
5
+
6
+ it "should be able to handle HTTP basic authentication" do
7
+ client = Savon::Client.new @endpoint
8
+ client.request.basic_auth "user", "password"
9
+ response = client.do_something!
10
+ response.to_hash[:authenticate_response][:return][:success].should == true
11
+ end
12
+ end
@@ -0,0 +1,51 @@
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,69 +1,77 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Savon::Client do
4
- before { @client = some_client_instance }
4
+ before { @client = Savon::Client.new EndpointHelper.wsdl_endpoint }
5
5
 
6
- def some_client_instance
7
- Savon::Client.new SpecHelper.some_endpoint
6
+ it "should be initialized with an endpoint String" do
7
+ client = Savon::Client.new EndpointHelper.wsdl_endpoint
8
+ client.request.http.proxy?.should be_false
8
9
  end
9
10
 
10
- describe "initialize" do
11
- it "expects a SOAP endpoint String" do
12
- some_client_instance
13
- end
11
+ it "should accept a proxy URI via an optional Hash of options" do
12
+ client = Savon::Client.new EndpointHelper.wsdl_endpoint, :proxy => "http://proxy"
13
+ client.request.http.proxy?.should be_true
14
+ client.request.http.proxy_address == "http://proxy"
15
+ end
14
16
 
15
- it "raises an ArgumentError in case of an invalid endpoint" do
16
- lambda { Savon::Client.new "invalid" }.should raise_error ArgumentError
17
- end
17
+ it "should have a method that returns the Savon::WSDL" do
18
+ @client.wsdl.should be_a(Savon::WSDL)
18
19
  end
19
20
 
20
- describe "wsdl" do
21
- it "returns the Savon::WSDL" do
22
- @client.wsdl.should be_a Savon::WSDL
23
- end
21
+ it "should have a method that returns the Savon::Request" do
22
+ @client.request.should be_a(Savon::Request)
24
23
  end
25
24
 
26
- describe "respond_to?" do
27
- it "returns true for available SOAP actions" do
28
- @client.respond_to?(UserFixture.soap_actions.keys.first).
29
- should be_true
25
+ it "should respond to available SOAP actions while behaving as expected otherwise" do
26
+ WSDLFixture.authentication(:operations).keys.each do |soap_action|
27
+ @client.respond_to?(soap_action).should be_true
30
28
  end
31
29
 
32
- it "still behaves like usual otherwise" do
33
- @client.respond_to?(:object_id).should be_true
34
- @client.respond_to?(:some_undefined_method).should be_false
35
- end
30
+ @client.respond_to?(:object_id).should be_true
31
+ @client.respond_to?(:some_undefined_method).should be_false
36
32
  end
37
33
 
38
- describe "method_missing" do
39
- it "dispatches SOAP requests for available SOAP actions" do
40
- @client.find_user.should be_a Savon::Response
41
- end
34
+ it "should dispatch available SOAP calls via method_missing and return the Savon::Response" do
35
+ @client.authenticate.should be_a(Savon::Response)
36
+ end
42
37
 
43
- it "raises a Savon::SOAPFault in case of a SOAP fault" do
44
- client = Savon::Client.new SpecHelper.soapfault_endpoint
45
- lambda { client.find_user }.should raise_error Savon::SOAPFault
38
+ it "should disable the Savon::WSDL when passed a method with an exclamation mark" do
39
+ @client.wsdl.enabled?.should be_true
40
+ [:respond_to?, :operations, :namespace_uri, :soap_endpoint].each do |method|
41
+ Savon::WSDL.any_instance.expects(method).never
46
42
  end
47
43
 
48
- it "raises a Savon::HTTPError in case of an HTTP error" do
49
- client = Savon::Client.new SpecHelper.httperror_endpoint
50
- lambda { client.find_user }.should raise_error Savon::HTTPError
44
+ response = @client.authenticate! do |soap|
45
+ soap.input.should == "authenticate"
46
+ soap.input.should == "authenticate"
51
47
  end
48
+ response.should be_a(Savon::Response)
49
+ @client.wsdl.enabled?.should be_false
50
+ end
52
51
 
53
- it "yields the SOAP object to a block that expects one argument" do
54
- @client.find_user { |soap| soap.should be_a Savon::SOAP }
55
- end
52
+ it "should raise a Savon::SOAPFault in case of a SOAP fault" do
53
+ client = Savon::Client.new EndpointHelper.wsdl_endpoint(:soap_fault)
54
+ lambda { client.authenticate! }.should raise_error(Savon::SOAPFault)
55
+ end
56
56
 
57
- it "yields the SOAP and WSSE object to a block that expects two argument" do
58
- @client.find_user do |soap, wsse|
59
- soap.should be_a Savon::SOAP
60
- wsse.should be_a Savon::WSSE
61
- end
62
- end
57
+ it "should raise a Savon::HTTPError in case of an HTTP error" do
58
+ client = Savon::Client.new EndpointHelper.wsdl_endpoint(:http_error)
59
+ lambda { client.authenticate! }.should raise_error(Savon::HTTPError)
60
+ end
63
61
 
64
- it "still raises a NoMethodError for undefined methods" do
65
- lambda { @client.some_undefined_method }.should raise_error NoMethodError
62
+ it "should yield an instance of Savon::SOAP to a given block expecting one argument" do
63
+ @client.authenticate { |soap| soap.should be_a(Savon::SOAP) }
64
+ end
65
+
66
+ it "should yield an instance of Savon::SOAP and Savon::WSSE to a gven block expecting two arguments" do
67
+ @client.authenticate do |soap, wsse|
68
+ soap.should be_a(Savon::SOAP)
69
+ wsse.should be_a(Savon::WSSE)
66
70
  end
67
71
  end
68
72
 
69
- end
73
+ it "should raise a NoMethodError when the method does not match an available SOAP action or method" do
74
+ lambda { @client.some_undefined_method }.should raise_error(NoMethodError)
75
+ end
76
+
77
+ end
@@ -4,8 +4,8 @@ describe DateTime do
4
4
 
5
5
  describe "to_soap_value" do
6
6
  it "returns an xs:dateTime compliant String" do
7
- UserFixture.datetime_object.to_soap_value.
8
- should == UserFixture.datetime_string
7
+ DateTime.new(2012, 03, 22, 16, 22, 33).to_soap_value.
8
+ should == "2012-03-22T16:22:33"
9
9
  end
10
10
  end
11
11
 
@@ -2,26 +2,13 @@ require "spec_helper"
2
2
 
3
3
  describe Hash do
4
4
 
5
- describe "find_regexp" do
6
- before do
7
- @soap_fault_hash = { "soap:Envelope" => { "soap:Body" => { "soap:Fault" => {
8
- "faultcode" => "soap:Server", "faultstring" => "Fault occurred while processing."
9
- } } } }
5
+ describe "find_soap_body" do
6
+ it "returns the content from the 'soap:Body' element" do
7
+ { "soap:Envelope" => { "soap:Body" => "content" } }.find_soap_body.should == "content"
10
8
  end
11
9
 
12
- it "returns an empty Hash in case it did not find the specified value" do
13
- result = @soap_fault_hash.find_regexp "soap:Fault"
14
-
15
- result.should be_a Hash
16
- result.should be_empty
17
- end
18
-
19
- it "returns the value of the last Regexp filter found in the Hash" do
20
- @soap_fault_hash.find_regexp([".+:Envelope", ".+:Body"]).
21
- should == @soap_fault_hash["soap:Envelope"]["soap:Body"]
22
-
23
- @soap_fault_hash.find_regexp([/.+:Envelope/, /.+:Body/, /.+Fault/]).
24
- should == @soap_fault_hash["soap:Envelope"]["soap:Body"]["soap:Fault"]
10
+ it "returns an empty Hash in case the 'soap:Body' element could not be found" do
11
+ { "some_hash" => "content" }.find_soap_body.should == {}
25
12
  end
26
13
  end
27
14
 
@@ -39,8 +26,8 @@ describe Hash do
39
26
  it "for a Hash with multiple keys" do
40
27
  soap_xml = { :all => "users", :before => "whatever" }.to_soap_xml
41
28
 
42
- soap_xml.should include "<all>users</all>"
43
- soap_xml.should include "<before>whatever</before>"
29
+ soap_xml.should include("<all>users</all>")
30
+ soap_xml.should include("<before>whatever</before>")
44
31
  end
45
32
 
46
33
  it "for a Hash containing an Array" do
@@ -65,27 +52,26 @@ describe Hash do
65
52
  end
66
53
 
67
54
  it "converts DateTime objects to xs:dateTime compliant Strings" do
68
- { :before => UserFixture.datetime_object }.to_soap_xml.
69
- should == "<before>" << UserFixture.datetime_string << "</before>"
55
+ { :before => DateTime.new(2012, 03, 22, 16, 22, 33) }.to_soap_xml.
56
+ should == "<before>" << "2012-03-22T16:22:33" << "</before>"
70
57
  end
71
58
 
72
59
  it "converts Objects responding to to_datetime to xs:dateTime compliant Strings" do
73
60
  singleton = Object.new
74
61
  def singleton.to_datetime
75
- UserFixture.datetime_object
62
+ DateTime.new(2012, 03, 22, 16, 22, 33)
76
63
  end
77
64
 
78
65
  { :before => singleton }.to_soap_xml.
79
- should == "<before>" << UserFixture.datetime_string << "</before>"
66
+ should == "<before>" << "2012-03-22T16:22:33" << "</before>"
80
67
  end
81
68
 
82
69
  it "calls to_s on Strings even if they respond to to_datetime" do
83
- singleton = "gorilla"
84
- def singleton.to_datetime
85
- UserFixture.datetime_object
86
- end
70
+ object = "gorilla"
71
+ object.expects(:to_s).returns object
72
+ object.expects(:to_datetime).never
87
73
 
88
- { :name => singleton }.to_soap_xml.should == "<name>gorilla</name>"
74
+ { :name => object }.to_soap_xml.should == "<name>gorilla</name>"
89
75
  end
90
76
 
91
77
  it "call to_s on any other Object" do
@@ -93,6 +79,23 @@ describe Hash do
93
79
  { :some => object }.to_soap_xml.should == "<some>#{object}</some>"
94
80
  end
95
81
  end
82
+
83
+ it "preserves the order of Hash keys and values specified through :@inorder" do
84
+ { :find_user => { :name => "Lucy", :id => 666, :@inorder => [:id, :name] } }.to_soap_xml.
85
+ should == "<findUser><id>666</id><name>Lucy</name></findUser>"
86
+
87
+ { :find_user => { :by_name => { :mname => "in the", :lname => "Sky", :fname => "Lucy",
88
+ :@inorder => [:fname, :mname, :lname] } } }.to_soap_xml. should ==
89
+ "<findUser><byName><fname>Lucy</fname><mname>in the</mname><lname>Sky</lname></byName></findUser>"
90
+ end
91
+
92
+ it "raises an error if the :@inorder Array does not match the Hash keys" do
93
+ lambda { { :name => "Lucy", :id => 666, :@inorder => [:name] }.to_soap_xml }.
94
+ should raise_error(RuntimeError)
95
+
96
+ lambda { { :by_name => { :name => "Lucy", :lname => "Sky", :@inorder => [:mname, :name] } }.to_soap_xml }.
97
+ should raise_error(RuntimeError)
98
+ end
96
99
  end
97
100
 
98
101
  describe "map_soap_response" do
@@ -117,8 +120,8 @@ describe Hash do
117
120
  end
118
121
 
119
122
  it "converts Hash values matching the xs:dateTime format into DateTime Objects" do
120
- { "response" => { "at" => UserFixture.datetime_string } }.map_soap_response.
121
- should == { :response => { :at => UserFixture.datetime_object } }
123
+ { "response" => { "at" => "2012-03-22T16:22:33" } }.map_soap_response.
124
+ should == { :response => { :at => DateTime.new(2012, 03, 22, 16, 22, 33) } }
122
125
  end
123
126
 
124
127
  it "converts Hash values matching 'true' to TrueClass" do
@@ -0,0 +1,38 @@
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
@@ -2,6 +2,20 @@ require "spec_helper"
2
2
 
3
3
  describe Object do
4
4
 
5
+ describe "blank?" do
6
+ it "returns true for Objects perceived to be blank" do
7
+ ["", false, nil, [], {}].each do |object|
8
+ object.should be_blank
9
+ end
10
+ end
11
+
12
+ it "returns false for every other Object" do
13
+ ["!blank", true, [:a], {:a => "b"}].each do |object|
14
+ object.should_not be_blank
15
+ end
16
+ end
17
+ end
18
+
5
19
  describe "to_soap_key" do
6
20
  it "calls to_s for every Object" do
7
21
  Object.to_soap_key.should == Object.to_s
@@ -12,10 +26,10 @@ describe Object do
12
26
  it "returns an xs:dateTime compliant String for Objects responding to to_datetime" do
13
27
  singleton = Object.new
14
28
  def singleton.to_datetime
15
- UserFixture.datetime_object
29
+ DateTime.new(2012, 03, 22, 16, 22, 33)
16
30
  end
17
31
 
18
- singleton.to_soap_value.should == UserFixture.datetime_string
32
+ singleton.to_soap_value.should == "2012-03-22T16:22:33"
19
33
  end
20
34
 
21
35
  it "calls to_s unless the Object responds to to_datetime" do
@@ -4,12 +4,12 @@ describe String do
4
4
 
5
5
  describe "self.random" do
6
6
  it "returns a random 100-character String" do
7
- String.random.should be_a String
7
+ String.random.should be_a(String)
8
8
  String.random.length.should == 100
9
9
  end
10
10
 
11
11
  it "returns a random String of a given length" do
12
- String.random(50).should be_a String
12
+ String.random(50).should be_a(String)
13
13
  String.random(50).length.should == 50
14
14
  end
15
15
  end
@@ -42,8 +42,8 @@ describe String do
42
42
 
43
43
  describe "map_soap_response" do
44
44
  it "returns a DateTime Object for Strings matching the xs:dateTime format" do
45
- UserFixture.datetime_string.map_soap_response.should ==
46
- UserFixture.datetime_object
45
+ "2012-03-22T16:22:33".map_soap_response.should ==
46
+ DateTime.new(2012, 03, 22, 16, 22, 33)
47
47
  end
48
48
 
49
49
  it "returns true for Strings matching 'true'" do
@@ -8,4 +8,4 @@ describe Symbol do
8
8
  end
9
9
  end
10
10
 
11
- end
11
+ end
@@ -12,4 +12,4 @@ describe URI::HTTP do
12
12
  end
13
13
  end
14
14
 
15
- end
15
+ end