s-savon 0.8.6

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 (61) hide show
  1. data/.gitignore +9 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +2 -0
  4. data/CHANGELOG.md +461 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +20 -0
  7. data/README.md +37 -0
  8. data/Rakefile +40 -0
  9. data/lib/savon.rb +14 -0
  10. data/lib/savon/client.rb +157 -0
  11. data/lib/savon/core_ext/hash.rb +70 -0
  12. data/lib/savon/core_ext/object.rb +14 -0
  13. data/lib/savon/core_ext/string.rb +51 -0
  14. data/lib/savon/core_ext/time.rb +14 -0
  15. data/lib/savon/error.rb +6 -0
  16. data/lib/savon/global.rb +75 -0
  17. data/lib/savon/http/error.rb +42 -0
  18. data/lib/savon/soap.rb +24 -0
  19. data/lib/savon/soap/fault.rb +59 -0
  20. data/lib/savon/soap/request.rb +61 -0
  21. data/lib/savon/soap/response.rb +80 -0
  22. data/lib/savon/soap/xml.rb +187 -0
  23. data/lib/savon/version.rb +5 -0
  24. data/lib/savon/wsdl/document.rb +112 -0
  25. data/lib/savon/wsdl/parser.rb +102 -0
  26. data/lib/savon/wsdl/request.rb +35 -0
  27. data/lib/savon/wsse.rb +150 -0
  28. data/savon.gemspec +29 -0
  29. data/spec/fixtures/gzip/message.gz +0 -0
  30. data/spec/fixtures/response/another_soap_fault.xml +14 -0
  31. data/spec/fixtures/response/authentication.xml +14 -0
  32. data/spec/fixtures/response/header.xml +13 -0
  33. data/spec/fixtures/response/list.xml +18 -0
  34. data/spec/fixtures/response/multi_ref.xml +39 -0
  35. data/spec/fixtures/response/soap_fault.xml +8 -0
  36. data/spec/fixtures/response/soap_fault12.xml +18 -0
  37. data/spec/fixtures/wsdl/authentication.xml +63 -0
  38. data/spec/fixtures/wsdl/geotrust.xml +156 -0
  39. data/spec/fixtures/wsdl/namespaced_actions.xml +307 -0
  40. data/spec/fixtures/wsdl/no_namespace.xml +115 -0
  41. data/spec/fixtures/wsdl/two_bindings.xml +25 -0
  42. data/spec/savon/client_spec.rb +346 -0
  43. data/spec/savon/core_ext/hash_spec.rb +121 -0
  44. data/spec/savon/core_ext/object_spec.rb +19 -0
  45. data/spec/savon/core_ext/string_spec.rb +57 -0
  46. data/spec/savon/core_ext/time_spec.rb +13 -0
  47. data/spec/savon/http/error_spec.rb +52 -0
  48. data/spec/savon/savon_spec.rb +85 -0
  49. data/spec/savon/soap/fault_spec.rb +89 -0
  50. data/spec/savon/soap/request_spec.rb +45 -0
  51. data/spec/savon/soap/response_spec.rb +174 -0
  52. data/spec/savon/soap/xml_spec.rb +335 -0
  53. data/spec/savon/soap_spec.rb +21 -0
  54. data/spec/savon/wsdl/document_spec.rb +132 -0
  55. data/spec/savon/wsdl/parser_spec.rb +99 -0
  56. data/spec/savon/wsdl/request_spec.rb +15 -0
  57. data/spec/savon/wsse_spec.rb +213 -0
  58. data/spec/spec_helper.rb +14 -0
  59. data/spec/support/endpoint.rb +25 -0
  60. data/spec/support/fixture.rb +37 -0
  61. metadata +251 -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,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Example of a WSDL with two <binding> tags ("sections" in Savon
3
+ parlance).
4
+
5
+ This is stripped down from a real example found in the wild, although
6
+ having different operations for the SOAP 1.1 and SOAP 1.2 bindings
7
+ is hypothetical (the real-world example I saw had the same operations
8
+ in each binding section). -->
9
+ <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
10
+ <types>
11
+ </types>
12
+ <portType name="BlogSoap">
13
+ </portType>
14
+ <binding name="BlogSoap">
15
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
16
+ <operation name="Post" />
17
+ <operation name="Post11only" />
18
+ </binding>
19
+ <binding name="BlogSoap12">
20
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
21
+ <operation name="Post" />
22
+ <operation name="Post12only" />
23
+ </binding>
24
+ </definitions>
25
+
@@ -0,0 +1,346 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::Client do
4
+ let(:client) { Savon::Client.new { wsdl.document = Endpoint.wsdl } }
5
+
6
+ describe ".new" do
7
+ context "with a block expecting one argument" do
8
+ it "should yield the WSDL object" do
9
+ Savon::Client.new { |wsdl| wsdl.should be_a(Savon::WSDL::Document) }
10
+ end
11
+ end
12
+
13
+ context "with a block expecting two arguments" do
14
+ it "should yield the WSDL and HTTP objects" do
15
+ Savon::Client.new do |wsdl, http|
16
+ wsdl.should be_an(Savon::WSDL::Document)
17
+ http.should be_an(HTTPI::Request)
18
+ end
19
+ end
20
+ end
21
+
22
+ context "with a block expecting three arguments" do
23
+ it "should yield the WSDL, HTTP and WSSE objects" do
24
+ Savon::Client.new do |wsdl, http, wsse|
25
+ wsdl.should be_an(Savon::WSDL::Document)
26
+ http.should be_an(HTTPI::Request)
27
+ wsse.should be_an(Savon::WSSE)
28
+ end
29
+ end
30
+ end
31
+
32
+ context "with a block expecting no arguments" do
33
+ it "should let you access the WSDL object" do
34
+ Savon::Client.new { wsdl.should be_a(Savon::WSDL::Document) }
35
+ end
36
+
37
+ it "should let you access the HTTP object" do
38
+ Savon::Client.new { http.should be_an(HTTPI::Request) }
39
+ end
40
+
41
+ it "should let you access the WSSE object" do
42
+ Savon::Client.new { wsse.should be_a(Savon::WSSE) }
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#wsdl" do
48
+ it "should return the Savon::WSDL::Document" do
49
+ client.wsdl.should be_a(Savon::WSDL::Document)
50
+ end
51
+ end
52
+
53
+ describe "#http" do
54
+ it "should return the HTTPI::Request" do
55
+ client.http.should be_an(HTTPI::Request)
56
+ end
57
+ end
58
+
59
+ describe "#wsse" do
60
+ it "should return the Savon::WSSE object" do
61
+ client.wsse.should be_a(Savon::WSSE)
62
+ end
63
+ end
64
+
65
+ describe "#request" do
66
+ before do
67
+ HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:authentication)))
68
+ HTTPI.stubs(:post).returns(new_response)
69
+ end
70
+
71
+ context "without any arguments" do
72
+ it "should raise an ArgumentError" do
73
+ lambda { client.request }.should raise_error(ArgumentError)
74
+ end
75
+ end
76
+
77
+ context "with a single argument (Symbol)" do
78
+ it "should set the input tag to result in <getUser>" do
79
+ client.request(:get_user) { soap.input.should == [:getUser, {}] }
80
+ end
81
+
82
+ it "should set the target namespace with the default identifier" do
83
+ namespace = 'xmlns:wsdl="http://v1_0.ws.auth.order.example.com/"'
84
+ HTTPI::Request.any_instance.expects(:body=).with { |value| value.include? namespace }
85
+
86
+ client.request :get_user
87
+ end
88
+
89
+ it "should not set the target namespace if soap.namespace was set to nil" do
90
+ namespace = "http://v1_0.ws.auth.order.example.com/"
91
+ HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
92
+
93
+ client.request(:get_user) { soap.namespace = nil }
94
+ end
95
+ end
96
+
97
+ context "with a single argument (String)" do
98
+ it "should set the input tag to result in <get_user>" do
99
+ client.request("get_user") { soap.input.should == [:get_user, {}] }
100
+ end
101
+ end
102
+
103
+ context "with a Symbol and a Hash" do
104
+ it "should set the input tag to result in <getUser active='true'>" do
105
+ client.request(:get_user, :active => true) { soap.input.should == [:getUser, { :active => true }] }
106
+ end
107
+ end
108
+
109
+ context "with two Symbols" do
110
+ it "should set the input tag to result in <wsdl:getUser>" do
111
+ client.request(:v1, :get_user) { soap.input.should == [:v1, :getUser, {}] }
112
+ end
113
+
114
+ it "should set the target namespace with the given identifier" do
115
+ namespace = 'xmlns:v1="http://v1_0.ws.auth.order.example.com/"'
116
+ HTTPI::Request.any_instance.expects(:body=).with { |value| value.include? namespace }
117
+
118
+ client.request :v1, :get_user
119
+ end
120
+
121
+ it "should not set the target namespace if soap.namespace was set to nil" do
122
+ namespace = "http://v1_0.ws.auth.order.example.com/"
123
+ HTTPI::Request.any_instance.expects(:body=).with { |value| !value.include?(namespace) }
124
+
125
+ client.request(:v1, :get_user) { soap.namespace = nil }
126
+ end
127
+ end
128
+
129
+ context "with two Symbols and a Hash" do
130
+ it "should set the input tag to result in <wsdl:getUser active='true'>" do
131
+ client.request(:wsdl, :get_user, :active => true) { soap.input.should == [:wsdl, :getUser, { :active => true }] }
132
+ end
133
+ end
134
+
135
+ context "with a block expecting one argument" do
136
+ it "should yield the SOAP object" do
137
+ client.request(:authenticate) { |soap| soap.should be_a(Savon::SOAP::XML) }
138
+ end
139
+ end
140
+
141
+ context "with a block expecting two arguments" do
142
+ it "should yield the SOAP and WSDL objects" do
143
+ client.request(:authenticate) do |soap, wsdl|
144
+ soap.should be_a(Savon::SOAP::XML)
145
+ wsdl.should be_an(Savon::WSDL::Document)
146
+ end
147
+ end
148
+ end
149
+
150
+ context "with a block expecting three arguments" do
151
+ it "should yield the SOAP, WSDL and HTTP objects" do
152
+ client.request(:authenticate) do |soap, wsdl, http|
153
+ soap.should be_a(Savon::SOAP::XML)
154
+ wsdl.should be_an(Savon::WSDL::Document)
155
+ http.should be_an(HTTPI::Request)
156
+ end
157
+ end
158
+ end
159
+
160
+ context "with a block expecting four arguments" do
161
+ it "should yield the SOAP, WSDL, HTTP and WSSE objects" do
162
+ client.request(:authenticate) do |soap, wsdl, http, wsse|
163
+ soap.should be_a(Savon::SOAP::XML)
164
+ wsdl.should be_a(Savon::WSDL::Document)
165
+ http.should be_an(HTTPI::Request)
166
+ wsse.should be_a(Savon::WSSE)
167
+ end
168
+ end
169
+ end
170
+
171
+ context "with a block expecting no arguments" do
172
+ it "should let you access the SOAP object" do
173
+ client.request(:authenticate) { soap.should be_a(Savon::SOAP::XML) }
174
+ end
175
+
176
+ it "should let you access the HTTP object" do
177
+ client.request(:authenticate) { http.should be_an(HTTPI::Request) }
178
+ end
179
+
180
+ it "should let you access the WSSE object" do
181
+ client.request(:authenticate) { wsse.should be_a(Savon::WSSE) }
182
+ end
183
+
184
+ it "should let you access the WSDL object" do
185
+ client.request(:authenticate) { wsdl.should be_a(Savon::WSDL::Document) }
186
+ end
187
+ end
188
+
189
+ it "should not set the Cookie header for the next request" do
190
+ client.http.headers.expects(:[]=).with("Cookie", anything).never
191
+ client.http.headers.stubs(:[]=).with("SOAPAction", '"authenticate"')
192
+ client.http.headers.stubs(:[]=).with("Content-Type", "text/xml;charset=UTF-8")
193
+
194
+ client.request :authenticate
195
+ end
196
+ end
197
+
198
+ context "#request with a Set-Cookie response header" do
199
+ before do
200
+ HTTPI.stubs(:get).returns(new_response(:body => Fixture.wsdl(:authentication)))
201
+ HTTPI.stubs(:post).returns(new_response(:headers => { "Set-Cookie" => "some-cookie" }))
202
+ end
203
+
204
+ it "should set the Cookie header for the next request" do
205
+ client.http.headers.expects(:[]=).with("Cookie", "some-cookie")
206
+ client.http.headers.stubs(:[]=).with("SOAPAction", '"authenticate"')
207
+ client.http.headers.stubs(:[]=).with("Content-Type", "text/xml;charset=UTF-8")
208
+
209
+ client.request :authenticate
210
+ end
211
+ end
212
+
213
+ context "with a remote WSDL document" do
214
+ let(:client) { Savon::Client.new { wsdl.document = Endpoint.wsdl } }
215
+ before { HTTPI.expects(:get).returns(new_response(:body => Fixture.wsdl(:authentication))) }
216
+
217
+ it "should return a list of available SOAP actions" do
218
+ client.wsdl.soap_actions.should == [:authenticate]
219
+ end
220
+
221
+ it "adds a SOAPAction header containing the SOAP action name" do
222
+ HTTPI.stubs(:post).returns(new_response)
223
+
224
+ client.request :authenticate do
225
+ http.headers["SOAPAction"].should == %{"authenticate"}
226
+ end
227
+ end
228
+
229
+ it "should execute SOAP requests and return the response" do
230
+ HTTPI.expects(:post).returns(new_response)
231
+ response = client.request(:authenticate)
232
+
233
+ response.should be_a(Savon::SOAP::Response)
234
+ response.to_xml.should == Fixture.response(:authentication)
235
+ end
236
+ end
237
+
238
+ context "with a local WSDL document" do
239
+ let(:client) { Savon::Client.new { wsdl.document = "spec/fixtures/wsdl/authentication.xml" } }
240
+
241
+ before { HTTPI.expects(:get).never }
242
+
243
+ it "should return a list of available SOAP actions" do
244
+ client.wsdl.soap_actions.should == [:authenticate]
245
+ end
246
+
247
+ it "adds a SOAPAction header containing the SOAP action name" do
248
+ HTTPI.stubs(:post).returns(new_response)
249
+
250
+ client.request :authenticate do
251
+ http.headers["SOAPAction"].should == %{"authenticate"}
252
+ end
253
+ end
254
+
255
+ it "should get #element_form_default from the WSDL" do
256
+ HTTPI.stubs(:post).returns(new_response)
257
+ Savon::WSDL::Document.any_instance.expects(:element_form_default).returns(:qualified)
258
+
259
+ client.request :authenticate
260
+ end
261
+
262
+ it "should execute SOAP requests and return the response" do
263
+ HTTPI.expects(:post).returns(new_response)
264
+ response = client.request(:authenticate)
265
+
266
+ response.should be_a(Savon::SOAP::Response)
267
+ response.to_xml.should == Fixture.response(:authentication)
268
+ end
269
+ end
270
+
271
+ context "without a WSDL document" do
272
+ let(:client) do
273
+ Savon::Client.new do
274
+ wsdl.endpoint = Endpoint.soap
275
+ wsdl.namespace = "http://v1_0.ws.auth.order.example.com/"
276
+ end
277
+ end
278
+
279
+ before { HTTPI.expects(:get).never }
280
+
281
+ it "raise an ArgumentError when trying to access the WSDL" do
282
+ lambda { client.wsdl.soap_actions }.should raise_error(ArgumentError)
283
+ end
284
+
285
+ it "adds a SOAPAction header containing the SOAP action name" do
286
+ HTTPI.stubs(:post).returns(new_response)
287
+
288
+ client.request :authenticate do
289
+ http.headers["SOAPAction"].should == %{"authenticate"}
290
+ end
291
+ end
292
+
293
+ it "should not get #element_form_default from the WSDL" do
294
+ HTTPI.stubs(:post).returns(new_response)
295
+ Savon::WSDL::Document.any_instance.expects(:element_form_default).never
296
+
297
+ client.request :authenticate
298
+ end
299
+
300
+ it "should execute SOAP requests and return the response" do
301
+ HTTPI.expects(:post).returns(new_response)
302
+ response = client.request(:authenticate)
303
+
304
+ response.should be_a(Savon::SOAP::Response)
305
+ response.to_xml.should == Fixture.response(:authentication)
306
+ end
307
+ end
308
+
309
+ context "when encountering a SOAP fault" do
310
+ let(:client) do
311
+ Savon::Client.new do
312
+ wsdl.endpoint = Endpoint.soap
313
+ wsdl.namespace = "http://v1_0.ws.auth.order.example.com/"
314
+ end
315
+ end
316
+
317
+ before { HTTPI::expects(:post).returns(new_response(:code => 500, :body => Fixture.response(:soap_fault))) }
318
+
319
+ it "should raise a Savon::SOAP::Fault" do
320
+ lambda { client.request :authenticate }.should raise_error(Savon::SOAP::Fault)
321
+ end
322
+ end
323
+
324
+ context "when encountering an HTTP error" do
325
+ let(:client) do
326
+ Savon::Client.new do
327
+ wsdl.endpoint = Endpoint.soap
328
+ wsdl.namespace = "http://v1_0.ws.auth.order.example.com/"
329
+ end
330
+ end
331
+
332
+ before { HTTPI::expects(:post).returns(new_response(:code => 500)) }
333
+
334
+ it "should raise a Savon::HTTP::Error" do
335
+ lambda { client.request :authenticate }.should raise_error(Savon::HTTP::Error)
336
+ end
337
+ end
338
+
339
+ def new_response(options = {})
340
+ defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
341
+ response = defaults.merge options
342
+
343
+ HTTPI::Response.new response[:code], response[:headers], response[:body]
344
+ end
345
+
346
+ end