savon-xaop 0.7.2.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 (48) hide show
  1. data/CHANGELOG +124 -0
  2. data/README.textile +75 -0
  3. data/Rakefile +45 -0
  4. data/lib/savon/client.rb +84 -0
  5. data/lib/savon/core_ext/datetime.rb +8 -0
  6. data/lib/savon/core_ext/hash.rb +78 -0
  7. data/lib/savon/core_ext/net_http.rb +20 -0
  8. data/lib/savon/core_ext/object.rb +21 -0
  9. data/lib/savon/core_ext/string.rb +47 -0
  10. data/lib/savon/core_ext/symbol.rb +8 -0
  11. data/lib/savon/core_ext/uri.rb +10 -0
  12. data/lib/savon/core_ext.rb +3 -0
  13. data/lib/savon/request.rb +160 -0
  14. data/lib/savon/response.rb +108 -0
  15. data/lib/savon/soap.rb +176 -0
  16. data/lib/savon/wsdl.rb +122 -0
  17. data/lib/savon/wsse.rb +136 -0
  18. data/lib/savon.rb +34 -0
  19. data/spec/basic_spec_helper.rb +12 -0
  20. data/spec/endpoint_helper.rb +22 -0
  21. data/spec/fixtures/response/response_fixture.rb +36 -0
  22. data/spec/fixtures/response/xml/authentication.xml +14 -0
  23. data/spec/fixtures/response/xml/multi_ref.xml +39 -0
  24. data/spec/fixtures/response/xml/soap_fault.xml +8 -0
  25. data/spec/fixtures/response/xml/soap_fault12.xml +18 -0
  26. data/spec/fixtures/wsdl/wsdl_fixture.rb +37 -0
  27. data/spec/fixtures/wsdl/xml/authentication.xml +63 -0
  28. data/spec/fixtures/wsdl/xml/namespaced_actions.xml +307 -0
  29. data/spec/fixtures/wsdl/xml/no_namespace.xml +115 -0
  30. data/spec/http_stubs.rb +23 -0
  31. data/spec/integration/http_basic_auth_spec.rb +16 -0
  32. data/spec/integration/server.rb +51 -0
  33. data/spec/savon/client_spec.rb +77 -0
  34. data/spec/savon/core_ext/datetime_spec.rb +12 -0
  35. data/spec/savon/core_ext/hash_spec.rb +138 -0
  36. data/spec/savon/core_ext/net_http_spec.rb +38 -0
  37. data/spec/savon/core_ext/object_spec.rb +40 -0
  38. data/spec/savon/core_ext/string_spec.rb +68 -0
  39. data/spec/savon/core_ext/symbol_spec.rb +11 -0
  40. data/spec/savon/core_ext/uri_spec.rb +15 -0
  41. data/spec/savon/request_spec.rb +89 -0
  42. data/spec/savon/response_spec.rb +137 -0
  43. data/spec/savon/savon_spec.rb +23 -0
  44. data/spec/savon/soap_spec.rb +171 -0
  45. data/spec/savon/wsdl_spec.rb +84 -0
  46. data/spec/savon/wsse_spec.rb +132 -0
  47. data/spec/spec_helper.rb +5 -0
  48. metadata +175 -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>
@@ -0,0 +1,23 @@
1
+ FakeWeb.allow_net_connect = false
2
+
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
10
+
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"]
14
+
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"]
18
+
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
+
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,16 @@
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
@@ -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
@@ -0,0 +1,77 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::Client do
4
+ before { @client = Savon::Client.new EndpointHelper.wsdl_endpoint }
5
+
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
9
+ end
10
+
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
16
+
17
+ it "should have a method that returns the Savon::WSDL" do
18
+ @client.wsdl.should be_a(Savon::WSDL)
19
+ end
20
+
21
+ it "should have a method that returns the Savon::Request" do
22
+ @client.request.should be_a(Savon::Request)
23
+ end
24
+
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
28
+ end
29
+
30
+ @client.respond_to?(:object_id).should be_true
31
+ @client.respond_to?(:some_undefined_method).should be_false
32
+ end
33
+
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
37
+
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
42
+ end
43
+
44
+ response = @client.authenticate! do |soap|
45
+ soap.input.should == "authenticate"
46
+ soap.input.should == "authenticate"
47
+ end
48
+ response.should be_a(Savon::Response)
49
+ @client.wsdl.enabled?.should be_false
50
+ end
51
+
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
+
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
61
+
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)
70
+ end
71
+ end
72
+
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
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe DateTime do
4
+
5
+ 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:33"
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,138 @@
1
+ require "spec_helper"
2
+
3
+ describe Hash do
4
+
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"
8
+ end
9
+
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 == {}
12
+ end
13
+ end
14
+
15
+ describe "to_soap_xml" do
16
+ describe "returns SOAP request compatible XML" do
17
+ it "for a simple Hash" do
18
+ { :some => "user" }.to_soap_xml.should == "<some>user</some>"
19
+ end
20
+
21
+ it "for a nested Hash" do
22
+ { :some => { :new => "user" } }.to_soap_xml.
23
+ should == "<some><new>user</new></some>"
24
+ end
25
+
26
+ it "for a Hash with multiple keys" do
27
+ soap_xml = { :all => "users", :before => "whatever" }.to_soap_xml
28
+
29
+ soap_xml.should include("<all>users</all>")
30
+ soap_xml.should include("<before>whatever</before>")
31
+ end
32
+
33
+ it "for a Hash containing an Array" do
34
+ { :some => ["user", "gorilla"] }.to_soap_xml.
35
+ should == "<some>user</some><some>gorilla</some>"
36
+ end
37
+
38
+ it "for a Hash containing an Array of Hashes" do
39
+ { :some => [{ :new => "user" }, { :old => "gorilla" }] }.to_soap_xml.
40
+ should == "<some><new>user</new></some><some><old>gorilla</old></some>"
41
+ end
42
+ end
43
+
44
+ it "converts Hash key Symbols to lowerCamelCase" do
45
+ { :find_or_create => "user" }.to_soap_xml.
46
+ should == "<findOrCreate>user</findOrCreate>"
47
+ end
48
+
49
+ it "does not convert Hash key Strings" do
50
+ { "find_or_create" => "user" }.to_soap_xml.
51
+ should == "<find_or_create>user</find_or_create>"
52
+ end
53
+
54
+ it "converts DateTime objects to xs:dateTime compliant Strings" do
55
+ { :before => DateTime.new(2012, 03, 22, 16, 22, 33) }.to_soap_xml.
56
+ should == "<before>" << "2012-03-22T16:22:33" << "</before>"
57
+ end
58
+
59
+ it "converts Objects responding to to_datetime to xs:dateTime compliant Strings" do
60
+ singleton = Object.new
61
+ def singleton.to_datetime
62
+ DateTime.new(2012, 03, 22, 16, 22, 33)
63
+ end
64
+
65
+ { :before => singleton }.to_soap_xml.
66
+ should == "<before>" << "2012-03-22T16:22:33" << "</before>"
67
+ end
68
+
69
+ it "calls to_s on Strings even if they respond to to_datetime" do
70
+ object = "gorilla"
71
+ object.expects(:to_s).returns object
72
+ object.expects(:to_datetime).never
73
+
74
+ { :name => object }.to_soap_xml.should == "<name>gorilla</name>"
75
+ end
76
+
77
+ it "call to_s on any other Object" do
78
+ [666, true, false, nil].each do |object|
79
+ { :some => object }.to_soap_xml.should == "<some>#{object}</some>"
80
+ end
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
99
+ end
100
+
101
+ describe "map_soap_response" do
102
+ it "converts Hash key Strings to snake_case Symbols" do
103
+ { "userResponse" => { "accountStatus" => "active" } }.map_soap_response.
104
+ should == { :user_response => { :account_status => "active" } }
105
+ end
106
+
107
+ it "strips namespaces from Hash keys" do
108
+ { "ns:userResponse" => { "ns2:id" => "666" } }.map_soap_response.
109
+ should == { :user_response => { :id => "666" } }
110
+ end
111
+
112
+ it "converts Hash keys and values in Arrays" do
113
+ { "response" => [{ "name" => "dude" }, { "name" => "gorilla" }] }.map_soap_response.
114
+ should == { :response=> [{ :name => "dude" }, { :name => "gorilla" }] }
115
+ end
116
+
117
+ it "converts xsi:nil values to nil Objects" do
118
+ { "userResponse" => { "xsi:nil" => "true" } }.map_soap_response.
119
+ should == { :user_response => nil }
120
+ end
121
+
122
+ it "converts Hash values matching the xs:dateTime format into DateTime Objects" do
123
+ { "response" => { "at" => "2012-03-22T16:22:33" } }.map_soap_response.
124
+ should == { :response => { :at => DateTime.new(2012, 03, 22, 16, 22, 33) } }
125
+ end
126
+
127
+ it "converts Hash values matching 'true' to TrueClass" do
128
+ { "response" => { "active" => "false" } }.map_soap_response.
129
+ should == { :response => { :active => false } }
130
+ end
131
+
132
+ it "converts Hash values matching 'false' to FalseClass" do
133
+ { "response" => { "active" => "true" } }.map_soap_response.
134
+ should == { :response => { :active => true } }
135
+ end
136
+ end
137
+
138
+ end
@@ -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
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe Object do
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
+
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
+ describe "to_soap_value" do
26
+ it "returns an xs:dateTime compliant String for Objects responding to to_datetime" do
27
+ singleton = Object.new
28
+ def singleton.to_datetime
29
+ DateTime.new(2012, 03, 22, 16, 22, 33)
30
+ end
31
+
32
+ singleton.to_soap_value.should == "2012-03-22T16:22:33"
33
+ end
34
+
35
+ it "calls to_s unless the Object responds to to_datetime" do
36
+ "value".to_soap_value.should == "value".to_s
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,68 @@
1
+ require "spec_helper"
2
+
3
+ describe String do
4
+
5
+ describe "self.random" do
6
+ it "returns a random 100-character String" do
7
+ String.random.should be_a(String)
8
+ String.random.length.should == 100
9
+ end
10
+
11
+ it "returns a random String of a given length" do
12
+ String.random(50).should be_a(String)
13
+ String.random(50).length.should == 50
14
+ end
15
+ end
16
+
17
+ describe "snakecase" do
18
+ it "converts a lowerCamelCase String to snakecase" do
19
+ "lowerCamelCase".snakecase.should == "lower_camel_case"
20
+ end
21
+
22
+ it "converts period characters to underscores" do
23
+ "User.GetEmail".snakecase.should == "user_get_email"
24
+ end
25
+ end
26
+
27
+ describe "lower_camelcase" do
28
+ it "converts a snakecase String to lowerCamelCase" do
29
+ "lower_camel_case".lower_camelcase.should == "lowerCamelCase"
30
+ end
31
+ end
32
+
33
+ describe "strip_namespace" do
34
+ it "strips the namespace from a namespaced String" do
35
+ "ns:customer".strip_namespace.should == "customer"
36
+ end
37
+
38
+ it "returns the original String for a String without namespace" do
39
+ "customer".strip_namespace.should == "customer"
40
+ end
41
+ end
42
+
43
+ describe "map_soap_response" do
44
+ it "returns a DateTime Object for Strings matching the xs:dateTime format" do
45
+ "2012-03-22T16:22:33".map_soap_response.should ==
46
+ DateTime.new(2012, 03, 22, 16, 22, 33)
47
+ end
48
+
49
+ it "returns true for Strings matching 'true'" do
50
+ "true".map_soap_response.should be_true
51
+ end
52
+
53
+ it "returns false for Strings matching 'false'" do
54
+ "false".map_soap_response.should be_false
55
+ end
56
+
57
+ it "defaults to return the original value" do
58
+ "whatever".map_soap_response.should == "whatever"
59
+ end
60
+ end
61
+
62
+ describe "to_soap_value" do
63
+ it "calls to_s, bypassing Rails to_datetime extension for Strings" do
64
+ "string".to_soap_value.should == "string".to_s
65
+ end
66
+ end
67
+
68
+ end
@@ -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