savon 0.3.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +68 -0
- data/Rakefile +9 -7
- data/VERSION +1 -1
- data/lib/savon.rb +33 -34
- data/lib/savon/client.rb +96 -0
- data/lib/savon/core_ext.rb +6 -0
- data/lib/savon/core_ext/datetime.rb +8 -0
- data/lib/savon/core_ext/hash.rb +65 -0
- data/lib/savon/core_ext/object.rb +14 -0
- data/lib/savon/core_ext/string.rb +41 -0
- data/lib/savon/core_ext/symbol.rb +8 -0
- data/lib/savon/core_ext/uri.rb +10 -0
- data/lib/savon/request.rb +103 -0
- data/lib/savon/soap.rb +71 -0
- data/lib/savon/validation.rb +57 -0
- data/lib/savon/wsdl.rb +39 -41
- data/lib/savon/wsse.rb +111 -0
- data/spec/fixtures/multiple_user_response.xml +22 -0
- data/spec/fixtures/soap_fault.xml +0 -0
- data/spec/fixtures/user_fixture.rb +42 -0
- data/spec/fixtures/user_response.xml +4 -2
- data/spec/fixtures/user_wsdl.xml +0 -0
- data/spec/http_stubs.rb +20 -0
- data/spec/savon/client_spec.rb +144 -0
- data/spec/savon/core_ext/datetime_spec.rb +12 -0
- data/spec/savon/core_ext/hash_spec.rb +146 -0
- data/spec/savon/core_ext/object_spec.rb +26 -0
- data/spec/savon/core_ext/string_spec.rb +52 -0
- data/spec/savon/core_ext/symbol_spec.rb +11 -0
- data/spec/savon/core_ext/uri_spec.rb +15 -0
- data/spec/savon/request_spec.rb +93 -0
- data/spec/savon/savon_spec.rb +37 -0
- data/spec/savon/soap_spec.rb +101 -0
- data/spec/savon/validation_spec.rb +88 -0
- data/spec/savon/wsdl_spec.rb +17 -46
- data/spec/savon/wsse_spec.rb +169 -0
- data/spec/spec_helper.rb +7 -92
- data/spec/spec_helper_methods.rb +29 -0
- metadata +68 -20
- data/README.rdoc +0 -62
- data/lib/savon/service.rb +0 -151
- data/spec/savon/service_spec.rb +0 -76
@@ -0,0 +1,22 @@
|
|
1
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
2
|
+
<soap:Body>
|
3
|
+
<ns2:findUserResponse xmlns:ns2="http://v1_0.ws.user.example.com">
|
4
|
+
<return>
|
5
|
+
<id>666</id>
|
6
|
+
<email>thedude@example.com</email>
|
7
|
+
<username>thedude</username>
|
8
|
+
<firstname>The</firstname>
|
9
|
+
<lastname>Dude</lastname>
|
10
|
+
<registered>2000-01-22T22:11:21</registered>
|
11
|
+
</return>
|
12
|
+
<return>
|
13
|
+
<id>999</id>
|
14
|
+
<email>anotherdude@example.com</email>
|
15
|
+
<username>anotherdude</username>
|
16
|
+
<firstname>Another</firstname>
|
17
|
+
<lastname>Dude</lastname>
|
18
|
+
<registered>1984-05-26T11:22:12</registered>
|
19
|
+
</return>
|
20
|
+
</ns2:findUserResponse>
|
21
|
+
</soap:Body>
|
22
|
+
</soap:Envelope>
|
File without changes
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class UserFixture
|
2
|
+
|
3
|
+
@namespace_uri = "http://v1_0.ws.user.example.com"
|
4
|
+
@soap_actions = { :find_user => "findUser" }
|
5
|
+
|
6
|
+
@datetime_string = "2010-11-22T11:22:33"
|
7
|
+
@datetime_object = DateTime.parse @datetime_string
|
8
|
+
|
9
|
+
@response_hash = { :id => "666", :active => true, :username => "thedude",
|
10
|
+
:firstname => "The", :lastname => "Dude", :email => "thedude@example.com",
|
11
|
+
:registered => @datetime_object }
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
attr_accessor :namespace_uri, :soap_actions,
|
16
|
+
:datetime_string, :datetime_object, :response_hash
|
17
|
+
|
18
|
+
def user_wsdl
|
19
|
+
load_fixture :user_wsdl
|
20
|
+
end
|
21
|
+
|
22
|
+
def user_response
|
23
|
+
load_fixture :user_response
|
24
|
+
end
|
25
|
+
|
26
|
+
def multiple_user_response
|
27
|
+
load_fixture :multiple_user_response
|
28
|
+
end
|
29
|
+
|
30
|
+
def soap_fault
|
31
|
+
load_fixture :soap_fault
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def load_fixture(file)
|
37
|
+
file_path = File.join File.dirname(__FILE__), "#{file}.xml"
|
38
|
+
IO.readlines(file_path, "").to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -2,12 +2,14 @@
|
|
2
2
|
<soap:Body>
|
3
3
|
<ns2:findUserResponse xmlns:ns2="http://v1_0.ws.user.example.com">
|
4
4
|
<return>
|
5
|
-
<id>
|
5
|
+
<id>666</id>
|
6
6
|
<email>thedude@example.com</email>
|
7
7
|
<username>thedude</username>
|
8
8
|
<firstname>The</firstname>
|
9
9
|
<lastname>Dude</lastname>
|
10
|
+
<registered>2010-11-22T11:22:33</registered>
|
11
|
+
<active>true</active>
|
10
12
|
</return>
|
11
13
|
</ns2:findUserResponse>
|
12
14
|
</soap:Body>
|
13
|
-
</soap:Envelope>
|
15
|
+
</soap:Envelope>
|
data/spec/fixtures/user_wsdl.xml
CHANGED
File without changes
|
data/spec/http_stubs.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "fakeweb"
|
2
|
+
|
3
|
+
FakeWeb.allow_net_connect = false
|
4
|
+
|
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
|
8
|
+
|
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
|
12
|
+
|
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
|
16
|
+
|
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"]
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Savon::Client do
|
4
|
+
before { @client = new_client_instance }
|
5
|
+
|
6
|
+
def new_client_instance
|
7
|
+
Savon::Client.new SpecHelper.some_endpoint
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "@response_process" do
|
11
|
+
it "expects a Net::HTTPResponse, translates the response" <<
|
12
|
+
"into a Hash and returns the SOAP response body" do
|
13
|
+
response = Savon::Client.response_process.call(http_response_mock)
|
14
|
+
|
15
|
+
response.should be_a Hash
|
16
|
+
UserFixture.response_hash.each do |key, value|
|
17
|
+
response[key].should == value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has accessor methods" do
|
22
|
+
response_process = Savon::Client.response_process
|
23
|
+
|
24
|
+
Savon::Client.response_process = "process"
|
25
|
+
Savon::Client.response_process.should == "process"
|
26
|
+
Savon::Client.response_process = response_process
|
27
|
+
Savon::Client.response_process.should == response_process
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "initialize" do
|
32
|
+
it "expects a SOAP endpoint String" do
|
33
|
+
new_client_instance
|
34
|
+
end
|
35
|
+
|
36
|
+
it "raises an ArgumentError in case of an invalid endpoint" do
|
37
|
+
lambda { Savon::Client.new "invalid" }.should raise_error ArgumentError
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "wsdl" do
|
42
|
+
it "returns the Savon::WSDL" do
|
43
|
+
@client.find_user
|
44
|
+
|
45
|
+
@client.wsdl.should be_a Savon::WSDL
|
46
|
+
@client.wsdl.to_s.should == UserFixture.user_wsdl
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "response" do
|
51
|
+
it "returns the Net::HTTPResponse of the last SOAP request" do
|
52
|
+
@client.find_user
|
53
|
+
|
54
|
+
@client.response.should be_a Net::HTTPResponse
|
55
|
+
@client.response.body.should == UserFixture.user_response
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "respond_to?" do
|
60
|
+
it "returns true for available SOAP actions" do
|
61
|
+
@client.respond_to?(UserFixture.soap_actions.keys.first).
|
62
|
+
should be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "still behaves like usual otherwise" do
|
66
|
+
@client.respond_to?(:object_id).should be_true
|
67
|
+
@client.respond_to?(:some_missing_method).should be_false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "method_missing" do
|
72
|
+
it "dispatches SOAP requests for available SOAP actions" do
|
73
|
+
@client.find_user.should be_a Hash
|
74
|
+
end
|
75
|
+
|
76
|
+
it "still returns a NoMethodError for missing methods" do
|
77
|
+
lambda { @client.some_missing_method }.should raise_error NoMethodError
|
78
|
+
end
|
79
|
+
|
80
|
+
it "accepts a Hash for specifying the SOAP body" do
|
81
|
+
soap_body_hash = { :id => 666 }
|
82
|
+
@client.find_user soap_body_hash
|
83
|
+
|
84
|
+
@client.instance_variable_get("@soap").body.
|
85
|
+
should include soap_body_hash.to_soap_xml
|
86
|
+
end
|
87
|
+
|
88
|
+
it "accepts a String for specifying the SOAP body" do
|
89
|
+
soap_body_xml = "<username>dude</username>"
|
90
|
+
@client.find_user soap_body_xml
|
91
|
+
|
92
|
+
@client.instance_variable_get("@soap").body.
|
93
|
+
should include soap_body_xml
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "accepts a Hash of per request options" do
|
97
|
+
it "to specify the SOAP version" do
|
98
|
+
@client.find_user nil, :soap_version => 2
|
99
|
+
@client.instance_variable_get("@soap").version.should == 2
|
100
|
+
end
|
101
|
+
|
102
|
+
it "to specify credentials for WSSE authentication" do
|
103
|
+
@client.find_user nil, :wsse =>
|
104
|
+
{ :username => "gorilla", :password => "secret" }
|
105
|
+
|
106
|
+
@client.instance_variable_get("@soap").body.should include "gorilla"
|
107
|
+
@client.instance_variable_get("@soap").body.should include "secret"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "to specify credentials for WSSE digestauthentication" do
|
111
|
+
@client.find_user nil, :wsse =>
|
112
|
+
{ :username => "gorilla", :password => "secret", :digest => true }
|
113
|
+
|
114
|
+
@client.instance_variable_get("@soap").body.should include "gorilla"
|
115
|
+
@client.instance_variable_get("@soap").body.should_not include "secret"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
it "accepts a block for specifying the response process per request" do
|
120
|
+
@client.find_user { |response| response.body }.
|
121
|
+
should == UserFixture.user_response
|
122
|
+
end
|
123
|
+
|
124
|
+
it "raises a Savon::SOAPFault in case of a SOAP fault" do
|
125
|
+
client = Savon::Client.new SpecHelper.soapfault_endpoint
|
126
|
+
lambda { client.find_user }.should raise_error Savon::SOAPFault
|
127
|
+
end
|
128
|
+
|
129
|
+
it "raises a Savon::HTTPError in case of an HTTP error" do
|
130
|
+
client = Savon::Client.new SpecHelper.httperror_endpoint
|
131
|
+
lambda { client.find_user }.should raise_error Savon::HTTPError
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def http_response_mock
|
136
|
+
unless @http_response_mock
|
137
|
+
@http_response_mock = mock "Net::HTTPResponse"
|
138
|
+
@http_response_mock.stubs :code => "200", :message => "OK",
|
139
|
+
:content_type => "text/html", :body => UserFixture.user_response
|
140
|
+
end
|
141
|
+
@http_response_mock
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
|
5
|
+
describe "to_soap_xml" do
|
6
|
+
describe "returns SOAP request compatible XML" do
|
7
|
+
it "for a simple Hash" do
|
8
|
+
{ :some => "user" }.to_soap_xml.should == "<some>user</some>"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "for a nested Hash" do
|
12
|
+
{ :some => { :new => "user" } }.to_soap_xml.
|
13
|
+
should == "<some><new>user</new></some>"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "for a Hash with multiple keys" do
|
17
|
+
soap_xml = { :all => "users", :before => "whatever" }.to_soap_xml
|
18
|
+
|
19
|
+
soap_xml.should include "<all>users</all>"
|
20
|
+
soap_xml.should include "<before>whatever</before>"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "for a Hash containing an Array" do
|
24
|
+
{ :some => ["user", "gorilla"] }.to_soap_xml.
|
25
|
+
should == "<some>user</some><some>gorilla</some>"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "for a Hash containing an Array of Hashes" do
|
29
|
+
{ :some => [{ :new => "user" }, { :old => "gorilla" }] }.to_soap_xml.
|
30
|
+
should == "<some><new>user</new></some><some><old>gorilla</old></some>"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "converts Hash key Symbols to lowerCamelCase" do
|
35
|
+
{ :find_or_create => "user" }.to_soap_xml.
|
36
|
+
should == "<findOrCreate>user</findOrCreate>"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does not convert Hash key Strings" do
|
40
|
+
{ "find_or_create" => "user" }.to_soap_xml.
|
41
|
+
should == "<find_or_create>user</find_or_create>"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "converts DateTime objects to xs:dateTime compliant Strings" do
|
45
|
+
{ :before => UserFixture.datetime_object }.to_soap_xml.
|
46
|
+
should == "<before>" << UserFixture.datetime_string << "</before>"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "converts Objects responding to to_datetime to xs:dateTime compliant Strings" do
|
50
|
+
singleton = Object.new
|
51
|
+
def singleton.to_datetime
|
52
|
+
UserFixture.datetime_object
|
53
|
+
end
|
54
|
+
|
55
|
+
{ :before => singleton }.to_soap_xml.
|
56
|
+
should == "<before>" << UserFixture.datetime_string << "</before>"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "calls to_s on Strings even if they respond to to_datetime" do
|
60
|
+
singleton = "gorilla"
|
61
|
+
def singleton.to_datetime
|
62
|
+
UserFixture.datetime_object
|
63
|
+
end
|
64
|
+
|
65
|
+
{ :name => singleton }.to_soap_xml.should == "<name>gorilla</name>"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "call to_s on any other Object" do
|
69
|
+
[666, true, false, nil].each do |object|
|
70
|
+
{ :some => object }.to_soap_xml.should == "<some>#{object}</some>"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "to_soap_fault_message" do
|
76
|
+
it "returns a SOAP fault message for SOAP version 1" do
|
77
|
+
soap_fault = soap_fault_hash(
|
78
|
+
"faultcode" => "soap:Server",
|
79
|
+
"faultstring" => "Fault occurred while processing."
|
80
|
+
)
|
81
|
+
|
82
|
+
soap_fault.to_soap_fault_message.should be_a String
|
83
|
+
soap_fault.to_soap_fault_message.should_not be_empty
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns a SOAP fault message for SOAP version 2" do
|
87
|
+
soap_fault = soap_fault_hash(
|
88
|
+
"code" => { "value" => "soap:Server" },
|
89
|
+
"reason" => { "text" => "Fault occurred while processing." }
|
90
|
+
)
|
91
|
+
|
92
|
+
soap_fault.to_soap_fault_message.should be_a String
|
93
|
+
soap_fault.to_soap_fault_message.should_not be_empty
|
94
|
+
end
|
95
|
+
|
96
|
+
it "returns nil in case the Hash does not include a SOAP fault" do
|
97
|
+
{ :soap_fault => false }.to_soap_fault_message.should be_nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns nil for unknown SOAP faults" do
|
101
|
+
soap_fault_hash.to_soap_fault_message.should be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def soap_fault_hash(details = {})
|
105
|
+
{ "soap:Envelope" => { "soap:Body" => { "soap:Fault" => details } } }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "map_soap_response" do
|
110
|
+
it "converts Hash key Strings to snake_case Symbols" do
|
111
|
+
{ "userResponse" => { "accountStatus" => "active" } }.map_soap_response.
|
112
|
+
should == { :user_response => { :account_status => "active" } }
|
113
|
+
end
|
114
|
+
|
115
|
+
it "strips namespaces from Hash keys" do
|
116
|
+
{ "ns:userResponse" => { "ns2:id" => "666" } }.map_soap_response.
|
117
|
+
should == { :user_response => { :id => "666" } }
|
118
|
+
end
|
119
|
+
|
120
|
+
it "converts Hash keys and values in Arrays" do
|
121
|
+
{ "response" => [{ "name" => "dude" }, { "name" => "gorilla" }] }.map_soap_response.
|
122
|
+
should == { :response=> [{ :name => "dude" }, { :name => "gorilla" }] }
|
123
|
+
end
|
124
|
+
|
125
|
+
it "converts xsi:nil values to nil Objects" do
|
126
|
+
{ "userResponse" => { "xsi:nil" => "true" } }.map_soap_response.
|
127
|
+
should == { :user_response => nil }
|
128
|
+
end
|
129
|
+
|
130
|
+
it "converts Hash values matching the xs:dateTime format into DateTime Objects" do
|
131
|
+
{ "response" => { "at" => UserFixture.datetime_string } }.map_soap_response.
|
132
|
+
should == { :response => { :at => UserFixture.datetime_object } }
|
133
|
+
end
|
134
|
+
|
135
|
+
it "converts Hash values matching 'true' to TrueClass" do
|
136
|
+
{ "response" => { "active" => "false" } }.map_soap_response.
|
137
|
+
should == { :response => { :active => false } }
|
138
|
+
end
|
139
|
+
|
140
|
+
it "converts Hash values matching 'false' to FalseClass" do
|
141
|
+
{ "response" => { "active" => "true" } }.map_soap_response.
|
142
|
+
should == { :response => { :active => true } }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Object do
|
4
|
+
|
5
|
+
describe "to_soap_key" do
|
6
|
+
it "calls to_s for every Object" do
|
7
|
+
Object.to_soap_key.should == Object.to_s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "to_soap_value" do
|
12
|
+
it "returns an xs:dateTime compliant String for Objects responding to to_datetime" do
|
13
|
+
singleton = Object.new
|
14
|
+
def singleton.to_datetime
|
15
|
+
UserFixture.datetime_object
|
16
|
+
end
|
17
|
+
|
18
|
+
singleton.to_soap_value.should == UserFixture.datetime_string
|
19
|
+
end
|
20
|
+
|
21
|
+
it "calls to_s unless the Object responds to to_datetime" do
|
22
|
+
"value".to_soap_value.should == "value".to_s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
describe "snakecase" do
|
6
|
+
it "converts a lowerCamelCase String to snakecase" do
|
7
|
+
"lowerCamelCase".snakecase.should == "lower_camel_case"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "lower_camelcase" do
|
12
|
+
it "converts a snakecase String to lowerCamelCase" do
|
13
|
+
"lower_camel_case".lower_camelcase.should == "lowerCamelCase"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "strip_namespace" do
|
18
|
+
it "strips the namespace from a namespaced String" do
|
19
|
+
"ns:customer".strip_namespace.should == "customer"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns the original String for a String without namespace" do
|
23
|
+
"customer".strip_namespace.should == "customer"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "map_soap_response" do
|
28
|
+
it "returns a DateTime Object for Strings matching the xs:dateTime format" do
|
29
|
+
UserFixture.datetime_string.map_soap_response.should ==
|
30
|
+
UserFixture.datetime_object
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns true for Strings matching 'true'" do
|
34
|
+
"true".map_soap_response.should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns false for Strings matching 'false'" do
|
38
|
+
"false".map_soap_response.should be_false
|
39
|
+
end
|
40
|
+
|
41
|
+
it "defaults to return the original value" do
|
42
|
+
"whatever".map_soap_response.should == "whatever"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "to_soap_value" do
|
47
|
+
it "calls to_s, bypassing Rails to_datetime extension for Strings" do
|
48
|
+
"string".to_soap_value.should == "string".to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|