savon 1.2.0 → 2.0.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 (66) hide show
  1. data/CHANGELOG.md +119 -104
  2. data/README.md +12 -11
  3. data/Rakefile +0 -6
  4. data/lib/savon.rb +16 -14
  5. data/lib/savon/block_interface.rb +26 -0
  6. data/lib/savon/builder.rb +142 -0
  7. data/lib/savon/client.rb +36 -135
  8. data/lib/savon/header.rb +42 -0
  9. data/lib/savon/http_error.rb +27 -0
  10. data/lib/savon/log_message.rb +23 -25
  11. data/lib/savon/message.rb +35 -0
  12. data/lib/savon/mock.rb +5 -0
  13. data/lib/savon/mock/expectation.rb +70 -0
  14. data/lib/savon/mock/spec_helper.rb +62 -0
  15. data/lib/savon/model.rb +39 -61
  16. data/lib/savon/operation.rb +62 -0
  17. data/lib/savon/options.rb +265 -0
  18. data/lib/savon/qualified_message.rb +49 -0
  19. data/lib/savon/request.rb +92 -0
  20. data/lib/savon/response.rb +97 -0
  21. data/lib/savon/soap_fault.rb +40 -0
  22. data/lib/savon/version.rb +1 -1
  23. data/savon.gemspec +10 -8
  24. data/spec/integration/options_spec.rb +536 -0
  25. data/spec/integration/request_spec.rb +31 -16
  26. data/spec/integration/support/application.rb +80 -0
  27. data/spec/integration/support/server.rb +84 -0
  28. data/spec/savon/builder_spec.rb +81 -0
  29. data/spec/savon/client_spec.rb +90 -488
  30. data/spec/savon/http_error_spec.rb +49 -0
  31. data/spec/savon/log_message_spec.rb +33 -0
  32. data/spec/savon/mock_spec.rb +127 -0
  33. data/spec/savon/model_spec.rb +110 -99
  34. data/spec/savon/observers_spec.rb +92 -0
  35. data/spec/savon/operation_spec.rb +49 -0
  36. data/spec/savon/request_spec.rb +145 -0
  37. data/spec/savon/{soap/response_spec.rb → response_spec.rb} +22 -59
  38. data/spec/savon/soap_fault_spec.rb +94 -0
  39. data/spec/spec_helper.rb +5 -3
  40. data/spec/support/fixture.rb +5 -1
  41. metadata +202 -197
  42. data/lib/savon/config.rb +0 -46
  43. data/lib/savon/error.rb +0 -6
  44. data/lib/savon/hooks/group.rb +0 -68
  45. data/lib/savon/hooks/hook.rb +0 -61
  46. data/lib/savon/http/error.rb +0 -42
  47. data/lib/savon/logger.rb +0 -39
  48. data/lib/savon/null_logger.rb +0 -10
  49. data/lib/savon/soap.rb +0 -21
  50. data/lib/savon/soap/fault.rb +0 -59
  51. data/lib/savon/soap/invalid_response_error.rb +0 -13
  52. data/lib/savon/soap/request.rb +0 -86
  53. data/lib/savon/soap/request_builder.rb +0 -205
  54. data/lib/savon/soap/response.rb +0 -117
  55. data/lib/savon/soap/xml.rb +0 -257
  56. data/spec/savon/config_spec.rb +0 -38
  57. data/spec/savon/hooks/group_spec.rb +0 -71
  58. data/spec/savon/hooks/hook_spec.rb +0 -16
  59. data/spec/savon/http/error_spec.rb +0 -52
  60. data/spec/savon/logger_spec.rb +0 -51
  61. data/spec/savon/savon_spec.rb +0 -33
  62. data/spec/savon/soap/fault_spec.rb +0 -89
  63. data/spec/savon/soap/request_builder_spec.rb +0 -207
  64. data/spec/savon/soap/request_spec.rb +0 -112
  65. data/spec/savon/soap/xml_spec.rb +0 -357
  66. data/spec/savon/soap_spec.rb +0 -16
@@ -1,112 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::SOAP::Request do
4
-
5
- let(:soap_request) { Savon::SOAP::Request.new(config, http_request, soap_xml) }
6
- let(:http_request) { HTTPI::Request.new }
7
- let(:http_response) { HTTPI::Response.new 200, {}, Fixture.response(:authentication) }
8
-
9
- let(:config) {
10
- config = Savon::Config.default
11
- config.log = false
12
- config
13
- }
14
-
15
- def soap_xml(*args)
16
- @soap_xml ||= soap_xml!(*args)
17
- end
18
-
19
- def soap_xml!(endpoint = nil, input = nil, body = nil)
20
- soap = Savon::SOAP::XML.new(config)
21
- soap.endpoint = endpoint || Endpoint.soap
22
- soap.input = input || [nil, :get_user, {}]
23
- soap.body = body || { :id => 1 }
24
- soap
25
- end
26
-
27
- it "contains the content type for each supported SOAP version" do
28
- content_type = Savon::SOAP::Request::CONTENT_TYPE
29
- content_type[1].should == "text/xml;charset=UTF-8"
30
- content_type[2].should == "application/soap+xml;charset=UTF-8"
31
- end
32
-
33
- describe ".execute" do
34
- it "executes a SOAP request and returns the response" do
35
- HTTPI.expects(:post).returns(http_response)
36
- response = Savon::SOAP::Request.execute config, http_request, soap_xml
37
- response.should be_a(Savon::SOAP::Response)
38
- end
39
- end
40
-
41
- describe ".new" do
42
- it "uses the SOAP endpoint for the request" do
43
- soap_request.http.url.should == URI(soap_xml.endpoint)
44
- end
45
-
46
- it "sets the SOAP body for the request" do
47
- soap_request.http.body.should == soap_xml.to_xml
48
- end
49
-
50
- it "sets the Content-Type header for SOAP 1.1" do
51
- soap_request.http.headers["Content-Type"].should == Savon::SOAP::Request::CONTENT_TYPE[1]
52
- end
53
-
54
- it "sets the Content-Type header for SOAP 1.2" do
55
- soap_xml.version = 2
56
- soap_request.http.headers["Content-Type"].should == Savon::SOAP::Request::CONTENT_TYPE[2]
57
- end
58
-
59
- it "sets the Content-Length header" do
60
- soap_request.http.headers["Content-Length"].should == soap_xml.to_xml.length.to_s
61
- end
62
-
63
- it "sets the Content-Length header for every request" do
64
- http = HTTPI::Request.new
65
- soap_request = Savon::SOAP::Request.new(config, http, soap_xml)
66
- http.headers.should include("Content-Length" => "272")
67
-
68
- soap_xml = soap_xml!(Endpoint.soap, [nil, :create_user, {}], :id => 123)
69
- soap_request = Savon::SOAP::Request.new(config, http, soap_xml)
70
- http.headers.should include("Content-Length" => "280")
71
- end
72
- end
73
-
74
- describe "#response" do
75
- it "executes an HTTP POST request and returns a Savon::SOAP::Response" do
76
- HTTPI.expects(:post).returns(http_response)
77
- soap_request.response.should be_a(Savon::SOAP::Response)
78
- end
79
-
80
- context "with a :soap_request hook" do
81
- it "lets you replace the HTTP request and return your own response" do
82
- config.hooks.define(:test, :soap_request) do |_, request|
83
- request.should be_a(Savon::SOAP::Request)
84
- http_response
85
- end
86
-
87
- response = soap_request.response
88
- response.http.should equal(http_response)
89
- end
90
-
91
- it "works as an around filter for the SOAP request" do
92
- HTTPI.expects(:post).returns(http_response)
93
- state = []
94
-
95
- config.hooks.define(:test, :soap_request) do |callback, request|
96
- state << :before
97
- response = callback.call
98
- state << response
99
- state << :after
100
- response
101
- end
102
-
103
- response = soap_request.response
104
-
105
- state[0].should == :before
106
- state[1].should be_a(HTTPI::Response)
107
- state[2].should == :after
108
- end
109
- end
110
- end
111
-
112
- end
@@ -1,357 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Savon::SOAP::XML do
4
-
5
- def xml(endpoint = nil, input = nil, body = nil)
6
- @xml ||= begin
7
- xml = Savon::SOAP::XML.new(config)
8
- xml.endpoint = endpoint || Endpoint.soap
9
- xml.input = input || [nil, :authenticate, {}]
10
- xml.body = body || { :id => 1 }
11
- xml
12
- end
13
- end
14
-
15
- let(:config) { Savon::Config.default }
16
-
17
- describe "#input" do
18
- it "should set the input tag" do
19
- xml.input = :test
20
- xml.input.should == :test
21
- end
22
- end
23
-
24
- describe "#endpoint" do
25
- it "should set the endpoint to use" do
26
- xml.endpoint = "http://test.com"
27
- xml.endpoint.should == "http://test.com"
28
- end
29
- end
30
-
31
- describe "#version" do
32
- it "should default to SOAP 1.1" do
33
- xml.version.should == 1
34
- end
35
-
36
- it "should default to the global default" do
37
- config.soap_version = 2
38
- xml.version.should == 2
39
- end
40
-
41
- it "should set the SOAP version to use" do
42
- xml.version = 2
43
- xml.version.should == 2
44
- end
45
-
46
- it "should raise an ArgumentError in case of an invalid version" do
47
- lambda { xml.version = 3 }.should raise_error(ArgumentError)
48
- end
49
- end
50
-
51
- describe "#header" do
52
- it "should default to an empty Hash" do
53
- xml.header.should == {}
54
- end
55
-
56
- it "should set the SOAP header" do
57
- xml.header = { "MySecret" => "abc" }
58
- xml.header.should == { "MySecret" => "abc" }
59
- end
60
-
61
- it "should use the global soap_header if set" do
62
- config.stubs(:soap_header).returns({ "MySecret" => "abc" })
63
- xml.header.should == { "MySecret" => "abc" }
64
- end
65
- end
66
-
67
- describe "#env_namespace" do
68
- it "should default to :env" do
69
- xml.env_namespace.should == :env
70
- end
71
-
72
- it "should set the SOAP envelope namespace" do
73
- xml.env_namespace = :soapenv
74
- xml.env_namespace.should == :soapenv
75
- end
76
-
77
- it "should use the global env_namespace if set as the SOAP envelope namespace" do
78
- config.stubs(:env_namespace).returns(:soapenv)
79
- xml.env_namespace.should == :soapenv
80
- end
81
- end
82
-
83
- describe "#namespaces" do
84
- it "should default to a Hash containing the namespace for SOAP 1.1" do
85
- xml.namespaces.should == { "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/" }
86
- end
87
-
88
- it "should default to a Hash containing the namespace for SOAP 1.2 if that's the current version" do
89
- xml.version = 2
90
- xml.namespaces.should == { "xmlns:env" => "http://www.w3.org/2003/05/soap-envelope" }
91
- end
92
-
93
- it "should set the SOAP header" do
94
- xml.namespaces = { "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
95
- xml.namespaces.should == { "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
96
- end
97
- end
98
-
99
- describe "#wsse" do
100
- it "should set the Akami::WSSE object" do
101
- xml.wsse = Akami.wsse
102
- xml.wsse.should be_a(Akami::WSSE)
103
- end
104
- end
105
-
106
- describe "#body" do
107
- it "should set the SOAP body Hash" do
108
- xml.body = { :id => 1 }
109
- xml.to_xml.should include("<id>1</id>")
110
- end
111
-
112
- it "should accepts an XML String" do
113
- xml.body = "<id>1</id>"
114
- xml.to_xml.should include("<id>1</id>")
115
- end
116
-
117
- it "should accept a block" do
118
- xml.body do |body|
119
- body.user { body.id 1 }
120
- end
121
-
122
- xml.to_xml.should include("<authenticate><user><id>1</id></user></authenticate>")
123
- end
124
- end
125
-
126
- describe "#encoding" do
127
- it "defaults to UTF-8" do
128
- xml.encoding.should == "UTF-8"
129
- end
130
- end
131
-
132
- describe "#xml" do
133
- it "lets you specify a completely custom XML String" do
134
- xml.xml = "<custom>xml</custom>"
135
- xml.to_xml.should == "<custom>xml</custom>"
136
- end
137
-
138
- it "yields a Builder::XmlMarkup object to a given block" do
139
- xml.xml { |xml| xml.using("Builder") }
140
- xml.to_xml.should == '<?xml version="1.0" encoding="UTF-8"?><using>Builder</using>'
141
- end
142
-
143
- it "accepts options to pass to the Builder::XmlMarkup instruct!" do
144
- xml.xml :xml, :aaa => :bbb do |xml|
145
- xml.using("Builder")
146
- end
147
-
148
- xml.to_xml.should == '<?xml version="1.0" encoding="UTF-8" aaa="bbb"?><using>Builder</using>'
149
- end
150
-
151
- it "allows to change the encoding" do
152
- xml.xml(:xml, :encoding => "US-ASCII") { |xml| xml.using("Builder") }
153
- xml.to_xml.should == '<?xml version="1.0" encoding="US-ASCII"?><using>Builder</using>'
154
- end
155
- end
156
-
157
- describe "#to_xml" do
158
- context "by default" do
159
- it "should start with an XML declaration" do
160
- xml.to_xml.should match(/^<\?xml version="1.0" encoding="UTF-8"\?>/)
161
- end
162
-
163
- it "should use default SOAP envelope namespace" do
164
- xml.to_xml.should include("<env:Envelope", "<env:Body")
165
- end
166
-
167
- it "should add the xsd namespace" do
168
- uri = "http://www.w3.org/2001/XMLSchema"
169
- xml.to_xml.should match(/<env:Envelope (.*)xmlns:xsd="#{uri}"(.*)>/)
170
- end
171
-
172
- it "should add the xsi namespace" do
173
- uri = "http://www.w3.org/2001/XMLSchema-instance"
174
- xml.to_xml.should match(/<env:Envelope (.*)xmlns:xsi="#{uri}"(.*)>/)
175
- end
176
-
177
- it "should have a SOAP envelope tag with a SOAP 1.1 namespace" do
178
- uri = "http://schemas.xmlsoap.org/soap/envelope/"
179
- xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
180
- end
181
-
182
- it "should have a SOAP body containing the SOAP input tag and body Hash" do
183
- xml.to_xml.should include('<env:Body><authenticate><id>1</id></authenticate></env:Body>')
184
- end
185
-
186
- it "should accept a SOAP body as an XML String" do
187
- xml.body = "<someId>1</someId>"
188
- xml.to_xml.should include('<env:Body><authenticate><someId>1</someId></authenticate></env:Body>')
189
- end
190
-
191
- it "should not contain a SOAP header" do
192
- xml.to_xml.should_not include('<env:Header')
193
- end
194
- end
195
-
196
- context "with a custom encoding" do
197
- after do
198
- xml.encoding = nil
199
- end
200
-
201
- it "should change the default encoding" do
202
- xml.encoding = "US-ASCII"
203
- xml.to_xml.should match(/^<\?xml version="1.0" encoding="US-ASCII"\?>/)
204
- end
205
- end
206
-
207
- context "with a SOAP header" do
208
- context "as a Hash" do
209
- it "should contain the given header" do
210
- xml.header = {
211
- :token => "secret",
212
- :attributes! => { :token => { :xmlns => "http://example.com" } }
213
- }
214
-
215
- xml.to_xml.should include('<env:Header><token xmlns="http://example.com">secret</token></env:Header>')
216
- end
217
- end
218
-
219
- context "as a String" do
220
- it "should contain the given header" do
221
- xml.header = %{<token xmlns="http://example.com">secret</token>}
222
-
223
- xml.to_xml.should include('<env:Header><token xmlns="http://example.com">secret</token></env:Header>')
224
- end
225
- end
226
- end
227
-
228
- context "with the global SOAP version set to 1.2" do
229
- it "should contain the namespace for SOAP 1.2" do
230
- config.soap_version = 2
231
-
232
- uri = "http://www.w3.org/2003/05/soap-envelope"
233
- xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
234
- end
235
- end
236
-
237
- context "with a global and request SOAP version" do
238
- it "should contain the namespace for the request SOAP version" do
239
- config.soap_version = 2
240
- xml.version = 1
241
-
242
- uri = "http://schemas.xmlsoap.org/soap/envelope/"
243
- xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
244
- end
245
- end
246
-
247
- context "with the SOAP envelope namespace set to an empty String" do
248
- it "should not add a namespace to SOAP envelope tags" do
249
- xml.env_namespace = ""
250
- xml.to_xml.should include("<Envelope", "<Body")
251
- end
252
- end
253
-
254
- context "using the #namespace and #namespace_identifier" do
255
- it "should contain the specified namespace" do
256
- xml.namespace_identifier = :wsdl
257
- xml.namespace = "http://example.com"
258
- xml.to_xml.should include('xmlns:wsdl="http://example.com"')
259
- end
260
- end
261
-
262
- context "with :element_form_default set to :qualified and a :namespace" do
263
- it "should namespace the default elements" do
264
- xml = xml(Endpoint.soap, [nil, :authenticate, {}], :user => { :id => 1, ":noNamespace" => true })
265
- xml.element_form_default = :qualified
266
- xml.namespace_identifier = :wsdl
267
-
268
- xml.to_xml.should include("<wsdl:user>", "<wsdl:id>1</wsdl:id>", "<noNamespace>true</noNamespace>")
269
- end
270
- end
271
-
272
- context "with :element_form_default set to :unqualified and a :namespace" do
273
- it "should namespace the default elements" do
274
- xml = xml(Endpoint.soap, [nil, :authenticate, {}], :user => { :id => 1, ":noNamespace" => true })
275
- xml.element_form_default = :unqualified
276
- xml.namespace_identifier = :wsdl
277
-
278
- xml.to_xml.should include("<user>", "<id>1</id>", "<noNamespace>true</noNamespace>")
279
- end
280
- end
281
-
282
- context "with WSSE authentication" do
283
- it "should containg a SOAP header with WSSE authentication details" do
284
- xml.wsse = Akami.wsse
285
- xml.wsse.credentials "username", "password"
286
-
287
- xml.to_xml.should include("<env:Header><wsse:Security")
288
- xml.to_xml.should include("<wsse:Username>username</wsse:Username>")
289
- xml.to_xml.should include("password</wsse:Password>")
290
- end
291
- end
292
-
293
- context "with a simple input tag (Symbol)" do
294
- it "should just add the input tag" do
295
- xml.input = [nil, :simple, {}]
296
- xml.to_xml.should include('<simple><id>1</id></simple>')
297
- end
298
- end
299
-
300
- context "with a simple input tag (Array)" do
301
- it "should just add the input tag" do
302
- xml.input = [nil, :simple, {}]
303
- xml.to_xml.should include('<simple><id>1</id></simple>')
304
- end
305
- end
306
-
307
- context "with an input tag and a namespace Hash (Array)" do
308
- it "should contain the input tag with namespaces" do
309
- xml.input = [nil, :getUser, { "active" => true }]
310
- xml.to_xml.should include('<getUser active="true"><id>1</id></getUser>')
311
- end
312
- end
313
-
314
- context "with a prefixed input tag (Array)" do
315
- it "should contain a prefixed input tag" do
316
- xml.input = [:wsdl, :getUser, {}]
317
- xml.to_xml.should include('<wsdl:getUser><id>1</id></wsdl:getUser>')
318
- end
319
- end
320
-
321
- context "with a prefixed input tag and a namespace Hash (Array)" do
322
- it "should contain a prefixed input tag with namespaces" do
323
- xml.input = [:wsdl, :getUser, { :only_active => false }]
324
- xml.to_xml.should include('<wsdl:getUser only_active="false"><id>1</id></wsdl:getUser>')
325
- end
326
- end
327
- end
328
-
329
- describe "#add_namespaces_to_body" do
330
- before :each do
331
- xml.used_namespaces.merge!({
332
- ["authenticate", "id"] =>"ns0",
333
- ["authenticate", "name"] =>"ns1",
334
- ["authenticate", "name", "firstName"] =>"ns2"
335
- })
336
- end
337
-
338
- it "adds namespaces" do
339
- body = {:id => 1, :name => {:first_name => 'Bob'}}
340
- xml.send(:add_namespaces_to_body, body).should == {"ns0:id" => "1", "ns1:name" => {"ns2:firstName" => "Bob"}}
341
- end
342
-
343
- it "adds namespaces to order! list" do
344
- body = {:id => 1, :name => {:first_name => 'Bob', :order! => [:first_name]}, :order! => [:id, :name]}
345
- xml.send(:add_namespaces_to_body, body).should == {
346
- "ns0:id" => "1",
347
- "ns1:name" => {
348
- "ns2:firstName" => "Bob",
349
- :order! => ["ns2:firstName"]
350
- },
351
- :order! => ["ns0:id", "ns1:name"]
352
- }
353
- end
354
- end
355
-
356
- end
357
-