s-savon 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
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,174 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::SOAP::Response do
4
+
5
+ describe ".new" do
6
+ it "should raise a Savon::SOAP::Fault in case of a SOAP fault" do
7
+ lambda { soap_fault_response }.should raise_error(Savon::SOAP::Fault)
8
+ end
9
+
10
+ it "should not raise a Savon::SOAP::Fault in case the default is turned off" do
11
+ Savon.raise_errors = false
12
+ lambda { soap_fault_response }.should_not raise_error(Savon::SOAP::Fault)
13
+ Savon.raise_errors = true
14
+ end
15
+
16
+ it "should raise a Savon::HTTP::Error in case of an HTTP error" do
17
+ lambda { soap_response :code => 500 }.should raise_error(Savon::HTTP::Error)
18
+ end
19
+
20
+ it "should not raise a Savon::HTTP::Error in case the default is turned off" do
21
+ Savon.raise_errors = false
22
+ soap_response :code => 500
23
+ Savon.raise_errors = true
24
+ end
25
+ end
26
+
27
+ describe "#success?" do
28
+ around do |example|
29
+ Savon.raise_errors = false
30
+ example.run
31
+ Savon.raise_errors = true
32
+ end
33
+
34
+ it "should return true if the request was successful" do
35
+ soap_response.should be_a_success
36
+ end
37
+
38
+ it "should return false if there was a SOAP fault" do
39
+ soap_fault_response.should_not be_a_success
40
+ end
41
+
42
+ it "should return false if there was an HTTP error" do
43
+ http_error_response.should_not be_a_success
44
+ end
45
+ end
46
+
47
+ describe "#soap_fault?" do
48
+ around do |example|
49
+ Savon.raise_errors = false
50
+ example.run
51
+ Savon.raise_errors = true
52
+ end
53
+
54
+ it "should not return true in case the response seems to be ok" do
55
+ soap_response.soap_fault?.should be_false
56
+ end
57
+
58
+ it "should return true in case of a SOAP fault" do
59
+ soap_fault_response.soap_fault?.should be_true
60
+ end
61
+ end
62
+
63
+ describe "#soap_fault" do
64
+ around do |example|
65
+ Savon.raise_errors = false
66
+ example.run
67
+ Savon.raise_errors = true
68
+ end
69
+
70
+ it "should return a Savon::SOAP::Fault" do
71
+ soap_fault_response.soap_fault.should be_a(Savon::SOAP::Fault)
72
+ end
73
+
74
+ it "should return a Savon::SOAP::Fault containing the HTTPI::Response" do
75
+ soap_fault_response.soap_fault.http.should be_an(HTTPI::Response)
76
+ end
77
+
78
+ it "should return a Savon::SOAP::Fault even if the SOAP response seems to be ok" do
79
+ soap_response.soap_fault.should be_a(Savon::SOAP::Fault)
80
+ end
81
+ end
82
+
83
+ describe "#http_error?" do
84
+ around do |example|
85
+ Savon.raise_errors = false
86
+ example.run
87
+ Savon.raise_errors = true
88
+ end
89
+
90
+ it "should not return true in case the response seems to be ok" do
91
+ soap_response.http_error?.should_not be_true
92
+ end
93
+
94
+ it "should return true in case of an HTTP error" do
95
+ soap_response(:code => 500).http_error?.should be_true
96
+ end
97
+ end
98
+
99
+ describe "#http_error" do
100
+ around do |example|
101
+ Savon.raise_errors = false
102
+ example.run
103
+ Savon.raise_errors = true
104
+ end
105
+
106
+ it "should return a Savon::HTTP::Error" do
107
+ http_error_response.http_error.should be_a(Savon::HTTP::Error)
108
+ end
109
+
110
+ it "should return a Savon::HTTP::Error containing the HTTPI::Response" do
111
+ http_error_response.http_error.http.should be_an(HTTPI::Response)
112
+ end
113
+
114
+ it "should return a Savon::HTTP::Error even if the HTTP response seems to be ok" do
115
+ soap_response.http_error.should be_a(Savon::HTTP::Error)
116
+ end
117
+ end
118
+
119
+ describe "#header" do
120
+ it "should return the SOAP response header as a Hash" do
121
+ response = soap_response :body => Fixture.response(:header)
122
+ response.header.should include(:session_number => "ABCD1234")
123
+ end
124
+ end
125
+
126
+ describe "#to_hash" do
127
+ it "should return the SOAP response body as a Hash" do
128
+ soap_response.to_hash[:authenticate_response][:return].should ==
129
+ Fixture.response_hash(:authentication)[:authenticate_response][:return]
130
+ end
131
+ end
132
+
133
+ describe "#to_array" do
134
+ it "should delegate to Savon::SOAP::XML.to_array" do
135
+ Savon::SOAP::XML.expects(:to_array).with(soap_response.to_hash, :authenticate_response, :return)
136
+ soap_response.to_array :authenticate_response, :return
137
+ end
138
+ end
139
+
140
+ describe "#basic_hash" do
141
+ it "should return the complete SOAP response XML as a Hash" do
142
+ response = soap_response :body => Fixture.response(:header)
143
+ response.basic_hash["soap:Envelope"]["soap:Header"]["SessionNumber"].should == "ABCD1234"
144
+ end
145
+ end
146
+
147
+ describe "#to_xml" do
148
+ it "should return the raw SOAP response body" do
149
+ soap_response.to_xml.should == Fixture.response(:authentication)
150
+ end
151
+ end
152
+
153
+ describe "#http" do
154
+ it "should return the HTTPI::Response" do
155
+ soap_response.http.should be_an(HTTPI::Response)
156
+ end
157
+ end
158
+
159
+ def soap_response(options = {})
160
+ defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
161
+ response = defaults.merge options
162
+
163
+ Savon::SOAP::Response.new HTTPI::Response.new(response[:code], response[:headers], response[:body])
164
+ end
165
+
166
+ def soap_fault_response
167
+ soap_response :code => 500, :body => Fixture.response(:soap_fault)
168
+ end
169
+
170
+ def http_error_response
171
+ soap_response :code => 404, :body => "Not found"
172
+ end
173
+
174
+ end
@@ -0,0 +1,335 @@
1
+ require "spec_helper"
2
+
3
+ describe Savon::SOAP::XML do
4
+ let(:xml) { Savon::SOAP::XML.new Endpoint.soap, :authenticate, :id => 1 }
5
+
6
+ describe ".to_hash" do
7
+ it "should return a given SOAP response body as a Hash" do
8
+ hash = Savon::SOAP::XML.to_hash Fixture.response(:authentication)
9
+ hash[:authenticate_response][:return].should == {
10
+ :success => true,
11
+ :authentication_value => {
12
+ :token_hash => "AAAJxA;cIedoT;mY10ExZwG6JuKgp2OYKxow==",
13
+ :token => "a68d1d6379b62ff339a0e0c69ed4d9cf",
14
+ :client => "radclient"
15
+ }
16
+ }
17
+ end
18
+
19
+ it "should return a Hash for a SOAP multiRef response" do
20
+ hash = Savon::SOAP::XML.to_hash Fixture.response(:multi_ref)
21
+
22
+ hash[:list_response].should be_a(Hash)
23
+ hash[:multi_ref].should be_an(Array)
24
+ end
25
+
26
+ it "should add existing namespaced elements as an array" do
27
+ hash = Savon::SOAP::XML.to_hash Fixture.response(:list)
28
+
29
+ hash[:multi_namespaced_entry_response][:history].should be_a(Hash)
30
+ hash[:multi_namespaced_entry_response][:history][:case].should be_an(Array)
31
+ end
32
+ end
33
+
34
+ describe ".parse" do
35
+ it "should convert the given XML into a Hash" do
36
+ hash = Savon::SOAP::XML.parse Fixture.response(:list)
37
+ hash["soapenv:Envelope"]["soapenv:Body"].should be_a(Hash)
38
+ end
39
+ end
40
+
41
+ describe ".to_array" do
42
+ let(:response_hash) { Fixture.response_hash :authentication }
43
+
44
+ context "when the given path exists" do
45
+ it "should return an Array containing the path value" do
46
+ Savon::SOAP::XML.to_array(response_hash, :authenticate_response, :return).should ==
47
+ [response_hash[:authenticate_response][:return]]
48
+ end
49
+ end
50
+
51
+ context "when the given path returns nil" do
52
+ it "should return an empty Array" do
53
+ Savon::SOAP::XML.to_array(response_hash, :authenticate_response, :undefined).should == []
54
+ end
55
+ end
56
+
57
+ context "when the given path does not exist at all" do
58
+ it "should return an empty Array" do
59
+ Savon::SOAP::XML.to_array(response_hash, :authenticate_response, :some, :wrong, :path).should == []
60
+ end
61
+ end
62
+ end
63
+
64
+ describe ".new" do
65
+ it "should accept an endpoint, an input tag and a SOAP body" do
66
+ xml = Savon::SOAP::XML.new Endpoint.soap, :authentication, :id => 1
67
+
68
+ xml.endpoint.should == Endpoint.soap
69
+ xml.input.should == :authentication
70
+ xml.body.should == { :id => 1 }
71
+ end
72
+ end
73
+
74
+ describe "#input" do
75
+ it "should set the input tag" do
76
+ xml.input = :test
77
+ xml.input.should == :test
78
+ end
79
+ end
80
+
81
+ describe "#endpoint" do
82
+ it "should set the endpoint to use" do
83
+ xml.endpoint = "http://test.com"
84
+ xml.endpoint.should == "http://test.com"
85
+ end
86
+ end
87
+
88
+ describe "#version" do
89
+ it "should default to SOAP 1.1" do
90
+ xml.version.should == 1
91
+ end
92
+
93
+ it "should default to the global default" do
94
+ Savon.soap_version = 2
95
+ xml.version.should == 2
96
+
97
+ reset_soap_version
98
+ end
99
+
100
+ it "should set the SOAP version to use" do
101
+ xml.version = 2
102
+ xml.version.should == 2
103
+ end
104
+
105
+ it "should raise an ArgumentError in case of an invalid version" do
106
+ lambda { xml.version = 3 }.should raise_error(ArgumentError)
107
+ end
108
+ end
109
+
110
+ describe "#header" do
111
+ it "should default to an empty Hash" do
112
+ xml.header.should == {}
113
+ end
114
+
115
+ it "should set the SOAP header" do
116
+ xml.header = { "MySecret" => "abc" }
117
+ xml.header.should == { "MySecret" => "abc" }
118
+ end
119
+ end
120
+
121
+ describe "#env_namespace" do
122
+ it "should default to :env" do
123
+ xml.env_namespace.should == :env
124
+ end
125
+
126
+ it "should set the SOAP envelope namespace" do
127
+ xml.env_namespace = :soapenv
128
+ xml.env_namespace.should == :soapenv
129
+ end
130
+ end
131
+
132
+ describe "#namespaces" do
133
+ it "should default to a Hash containing the namespace for SOAP 1.1" do
134
+ xml.namespaces.should == { "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/" }
135
+ end
136
+
137
+ it "should default to a Hash containing the namespace for SOAP 1.2 if that's the current version" do
138
+ xml.version = 2
139
+ xml.namespaces.should == { "xmlns:env" => "http://www.w3.org/2003/05/soap-envelope" }
140
+ end
141
+
142
+ it "should set the SOAP header" do
143
+ xml.namespaces = { "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
144
+ xml.namespaces.should == { "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
145
+ end
146
+ end
147
+
148
+ describe "#wsse" do
149
+ it "should set the Savon::WSSE object" do
150
+ xml.wsse = Savon::WSSE.new
151
+ xml.wsse.should be_a(Savon::WSSE)
152
+ end
153
+ end
154
+
155
+ describe "#body" do
156
+ it "should set the SOAP body Hash" do
157
+ xml.body = { :id => 1 }
158
+ xml.to_xml.should include("<id>1</id>")
159
+ end
160
+
161
+ it "should also accepts an XML String" do
162
+ xml.body = "<id>1</id>"
163
+ xml.to_xml.should include("<id>1</id>")
164
+ end
165
+ end
166
+
167
+ describe "#xml" do
168
+ it "lets you specify a completely custom XML String" do
169
+ xml.xml = "<custom>xml</custom>"
170
+ xml.to_xml.should == "<custom>xml</custom>"
171
+ end
172
+
173
+ it "yields a Builder::XmlMarkup object to a given block" do
174
+ xml.xml { |xml| xml.using("Builder") }
175
+ xml.to_xml.should == '<?xml version="1.0" encoding="UTF-8"?><using>Builder</using>'
176
+ end
177
+ end
178
+
179
+ describe "#to_xml" do
180
+ after { reset_soap_version }
181
+
182
+ context "by default" do
183
+ it "should start with an XML declaration" do
184
+ xml.to_xml.should match(/^<\?xml version="1.0" encoding="UTF-8"\?>/)
185
+ end
186
+
187
+ it "should use default SOAP envelope namespace" do
188
+ xml.to_xml.should include("<env:Envelope", "<env:Body")
189
+ end
190
+
191
+ it "should add the xsd namespace" do
192
+ uri = "http://www.w3.org/2001/XMLSchema"
193
+ xml.to_xml.should match(/<env:Envelope (.*)xmlns:xsd="#{uri}"(.*)>/)
194
+ end
195
+
196
+ it "should add the xsi namespace" do
197
+ uri = "http://www.w3.org/2001/XMLSchema-instance"
198
+ xml.to_xml.should match(/<env:Envelope (.*)xmlns:xsi="#{uri}"(.*)>/)
199
+ end
200
+
201
+ it "should have a SOAP envelope tag with a SOAP 1.1 namespace" do
202
+ uri = "http://schemas.xmlsoap.org/soap/envelope/"
203
+ xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
204
+ end
205
+
206
+ it "should have a SOAP body containing the SOAP input tag and body Hash" do
207
+ xml.to_xml.should include('<env:Body><authenticate><id>1</id></authenticate></env:Body>')
208
+ end
209
+
210
+ it "should accept a SOAP body as an XML String" do
211
+ xml.body = "<someId>1</someId>"
212
+ xml.to_xml.should include('<env:Body><authenticate><someId>1</someId></authenticate></env:Body>')
213
+ end
214
+
215
+ it "should not contain a SOAP header" do
216
+ xml.to_xml.should_not include('<env:Header')
217
+ end
218
+ end
219
+
220
+ context "with a SOAP header" do
221
+ it "should contain the given header" do
222
+ xml.header = {
223
+ :token => "secret",
224
+ :attributes! => { :token => { :xmlns => "http://example.com" } }
225
+ }
226
+
227
+ xml.to_xml.should include('<env:Header><token xmlns="http://example.com">secret</token></env:Header>')
228
+ end
229
+ end
230
+
231
+ context "with the global SOAP version set to 1.2" do
232
+ it "should contain the namespace for SOAP 1.2" do
233
+ Savon.soap_version = 2
234
+
235
+ uri = "http://www.w3.org/2003/05/soap-envelope"
236
+ xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
237
+ reset_soap_version
238
+ end
239
+ end
240
+
241
+ context "with a global and request SOAP version" do
242
+ it "should contain the namespace for the request SOAP version" do
243
+ Savon.soap_version = 2
244
+ xml.version = 1
245
+
246
+ uri = "http://schemas.xmlsoap.org/soap/envelope/"
247
+ xml.to_xml.should match(/<env:Envelope (.*)xmlns:env="#{uri}"(.*)>/)
248
+ reset_soap_version
249
+ end
250
+ end
251
+
252
+ context "with the SOAP envelope namespace set to an empty String" do
253
+ it "should not add a namespace to SOAP envelope tags" do
254
+ xml.env_namespace = ""
255
+ xml.to_xml.should include("<Envelope", "<Body")
256
+ end
257
+ end
258
+
259
+ context "using the #namespace and #namespace_identifier" do
260
+ it "should contain the specified namespace" do
261
+ xml.namespace_identifier = :wsdl
262
+ xml.namespace = "http://example.com"
263
+ xml.to_xml.should include('xmlns:wsdl="http://example.com"')
264
+ end
265
+ end
266
+
267
+ context "with :element_form_default set to :qualified and a :namespace" do
268
+ let :xml do
269
+ Savon::SOAP::XML.new Endpoint.soap, :authenticate, :user => { :id => 1, ":noNamespace" => true }
270
+ end
271
+
272
+ it "should namespace the default elements" do
273
+ xml.element_form_default = :qualified
274
+ xml.namespace_identifier = :wsdl
275
+
276
+ xml.to_xml.should include(
277
+ "<wsdl:user>",
278
+ "<wsdl:id>1</wsdl:id>",
279
+ "<noNamespace>true</noNamespace>"
280
+ )
281
+ end
282
+ end
283
+
284
+ context "with WSSE authentication" do
285
+ it "should containg a SOAP header with WSSE authentication details" do
286
+ xml.wsse = Savon::WSSE.new
287
+ xml.wsse.credentials "username", "password"
288
+
289
+ xml.to_xml.should include("<env:Header><wsse:Security")
290
+ xml.to_xml.should include("<wsse:Username>username</wsse:Username>")
291
+ xml.to_xml.should include("password</wsse:Password>")
292
+ end
293
+ end
294
+
295
+ context "with a simple input tag (Symbol)" do
296
+ it "should just add the input tag" do
297
+ xml.input = :simple
298
+ xml.to_xml.should include('<simple><id>1</id></simple>')
299
+ end
300
+ end
301
+
302
+ context "with a simple input tag (Array)" do
303
+ it "should just add the input tag" do
304
+ xml.input = :simple
305
+ xml.to_xml.should include('<simple><id>1</id></simple>')
306
+ end
307
+ end
308
+
309
+ context "with an input tag and a namespace Hash (Array)" do
310
+ it "should contain the input tag with namespaces" do
311
+ xml.input = [:getUser, { "active" => true }]
312
+ xml.to_xml.should include('<getUser active="true"><id>1</id></getUser>')
313
+ end
314
+ end
315
+
316
+ context "with a prefixed input tag (Array)" do
317
+ it "should contain a prefixed input tag" do
318
+ xml.input = [:wsdl, :getUser]
319
+ xml.to_xml.should include('<wsdl:getUser><id>1</id></wsdl:getUser>')
320
+ end
321
+ end
322
+
323
+ context "with a prefixed input tag and a namespace Hash (Array)" do
324
+ it "should contain a prefixed input tag with namespaces" do
325
+ xml.input = [:wsdl, :getUser, { :only_active => false }]
326
+ xml.to_xml.should include('<wsdl:getUser only_active="false"><id>1</id></wsdl:getUser>')
327
+ end
328
+ end
329
+ end
330
+
331
+ def reset_soap_version
332
+ Savon.soap_version = Savon::SOAP::DefaultVersion
333
+ end
334
+
335
+ end