savon 2.12.0 → 2.15.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 (95) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +115 -77
  3. data/README.md +23 -21
  4. data/lib/savon/block_interface.rb +1 -0
  5. data/lib/savon/builder.rb +100 -30
  6. data/lib/savon/client.rb +1 -0
  7. data/lib/savon/header.rb +2 -6
  8. data/lib/savon/http_error.rb +4 -4
  9. data/lib/savon/log_message.rb +1 -0
  10. data/lib/savon/message.rb +1 -0
  11. data/lib/savon/mock/expectation.rb +1 -0
  12. data/lib/savon/mock/spec_helper.rb +1 -0
  13. data/lib/savon/mock.rb +1 -0
  14. data/lib/savon/model.rb +4 -3
  15. data/lib/savon/operation.rb +20 -18
  16. data/lib/savon/options.rb +57 -1
  17. data/lib/savon/qualified_message.rb +4 -3
  18. data/lib/savon/request.rb +5 -0
  19. data/lib/savon/request_logger.rb +8 -2
  20. data/lib/savon/response.rb +51 -4
  21. data/lib/savon/soap_fault.rb +2 -1
  22. data/lib/savon/string_utils.rb +17 -0
  23. data/lib/savon/version.rb +2 -1
  24. data/lib/savon.rb +2 -0
  25. metadata +78 -101
  26. data/.gitignore +0 -14
  27. data/.travis.yml +0 -18
  28. data/.yardopts +0 -6
  29. data/CONTRIBUTING.md +0 -46
  30. data/Gemfile +0 -13
  31. data/donate.png +0 -0
  32. data/lib/savon/core_ext/string.rb +0 -29
  33. data/savon.gemspec +0 -46
  34. data/spec/fixtures/gzip/message.gz +0 -0
  35. data/spec/fixtures/response/another_soap_fault.xml +0 -14
  36. data/spec/fixtures/response/authentication.xml +0 -14
  37. data/spec/fixtures/response/f5.xml +0 -39
  38. data/spec/fixtures/response/header.xml +0 -13
  39. data/spec/fixtures/response/list.xml +0 -18
  40. data/spec/fixtures/response/multi_ref.xml +0 -39
  41. data/spec/fixtures/response/no_body.xml +0 -1
  42. data/spec/fixtures/response/soap_fault.xml +0 -8
  43. data/spec/fixtures/response/soap_fault12.xml +0 -18
  44. data/spec/fixtures/response/soap_fault_funky.xml +0 -8
  45. data/spec/fixtures/response/taxcloud.xml +0 -1
  46. data/spec/fixtures/ssl/client_cert.pem +0 -16
  47. data/spec/fixtures/ssl/client_encrypted_key.pem +0 -30
  48. data/spec/fixtures/ssl/client_encrypted_key_cert.pem +0 -24
  49. data/spec/fixtures/ssl/client_key.pem +0 -15
  50. data/spec/fixtures/wsdl/authentication.xml +0 -63
  51. data/spec/fixtures/wsdl/betfair.xml +0 -2981
  52. data/spec/fixtures/wsdl/brand.xml +0 -624
  53. data/spec/fixtures/wsdl/edialog.xml +0 -15416
  54. data/spec/fixtures/wsdl/interhome.xml +0 -2137
  55. data/spec/fixtures/wsdl/lower_camel.xml +0 -52
  56. data/spec/fixtures/wsdl/multiple_namespaces.xml +0 -92
  57. data/spec/fixtures/wsdl/multiple_types.xml +0 -60
  58. data/spec/fixtures/wsdl/no_message_tag.xml +0 -1267
  59. data/spec/fixtures/wsdl/taxcloud.xml +0 -934
  60. data/spec/fixtures/wsdl/team_software.xml +0 -1
  61. data/spec/fixtures/wsdl/vies.xml +0 -176
  62. data/spec/fixtures/wsdl/wasmuth.xml +0 -153
  63. data/spec/integration/centra_spec.rb +0 -67
  64. data/spec/integration/email_example_spec.rb +0 -32
  65. data/spec/integration/random_quote_spec.rb +0 -23
  66. data/spec/integration/ratp_example_spec.rb +0 -28
  67. data/spec/integration/stockquote_example_spec.rb +0 -34
  68. data/spec/integration/support/application.rb +0 -82
  69. data/spec/integration/support/server.rb +0 -84
  70. data/spec/integration/temperature_example_spec.rb +0 -46
  71. data/spec/integration/zipcode_example_spec.rb +0 -42
  72. data/spec/savon/builder_spec.rb +0 -137
  73. data/spec/savon/client_spec.rb +0 -271
  74. data/spec/savon/core_ext/string_spec.rb +0 -37
  75. data/spec/savon/features/message_tag_spec.rb +0 -61
  76. data/spec/savon/http_error_spec.rb +0 -49
  77. data/spec/savon/log_message_spec.rb +0 -50
  78. data/spec/savon/message_spec.rb +0 -70
  79. data/spec/savon/mock_spec.rb +0 -174
  80. data/spec/savon/model_spec.rb +0 -182
  81. data/spec/savon/observers_spec.rb +0 -92
  82. data/spec/savon/operation_spec.rb +0 -230
  83. data/spec/savon/options_spec.rb +0 -1104
  84. data/spec/savon/qualified_message_spec.rb +0 -101
  85. data/spec/savon/request_logger_spec.rb +0 -37
  86. data/spec/savon/request_spec.rb +0 -540
  87. data/spec/savon/response_spec.rb +0 -275
  88. data/spec/savon/soap_fault_spec.rb +0 -136
  89. data/spec/savon/softlayer_spec.rb +0 -27
  90. data/spec/spec_helper.rb +0 -30
  91. data/spec/support/adapters.rb +0 -48
  92. data/spec/support/endpoint.rb +0 -25
  93. data/spec/support/fixture.rb +0 -39
  94. data/spec/support/integration.rb +0 -9
  95. data/spec/support/stdout.rb +0 -25
@@ -1,1104 +0,0 @@
1
- require "spec_helper"
2
- require "integration/support/server"
3
- require "json"
4
- require "ostruct"
5
- require "logger"
6
-
7
- describe "Options" do
8
-
9
- before :all do
10
- @server = IntegrationServer.run
11
- end
12
-
13
- after :all do
14
- @server.stop
15
- end
16
-
17
- context "global: endpoint and namespace" do
18
- it "sets the SOAP endpoint to use to allow requests without a WSDL document" do
19
- client = new_client_without_wsdl(:endpoint => @server.url(:repeat), :namespace => "http://v1.example.com")
20
- response = client.call(:authenticate)
21
-
22
- # the default namespace identifier is :wsdl and contains the namespace option
23
- expect(response.http.body).to include('xmlns:wsdl="http://v1.example.com"')
24
-
25
- # the default namespace applies to the message tag
26
- expect(response.http.body).to include('<wsdl:authenticate>')
27
- end
28
- end
29
-
30
- context "global :namespace_identifier" do
31
- it "changes the default namespace identifier" do
32
- client = new_client(:endpoint => @server.url(:repeat), :namespace_identifier => :lol)
33
- response = client.call(:authenticate)
34
-
35
- expect(response.http.body).to include('xmlns:lol="http://v1_0.ws.auth.order.example.com/"')
36
- expect(response.http.body).to include("<lol:authenticate></lol:authenticate>")
37
- end
38
-
39
- it "ignores namespace identifier if it is nil" do
40
- client = new_client(:endpoint => @server.url(:repeat), :namespace_identifier => nil)
41
- response = client.call(:authenticate, :message => {:user => 'foo'})
42
-
43
- expect(response.http.body).to include('xmlns="http://v1_0.ws.auth.order.example.com/"')
44
- expect(response.http.body).to include("<authenticate><user>foo</user></authenticate>")
45
- end
46
- end
47
-
48
- context "global: :no_message_tag" do
49
- it "omits the 'message tag' encapsulation step" do
50
- client = new_client(:endpoint => @server.url(:repeat), :no_message_tag => true,
51
- :wsdl => Fixture.wsdl(:no_message_tag))
52
- msg = {'extLoginData' => {'Login' => 'test.user', 'Password' => 'secret', 'FacilityID' => 1,
53
- 'ThreePLKey' => '{XXXX-XXXX-XXXX-XXXX}', 'ThreePLID' => 1},
54
- 'Items' => ['Item' => {'SKU' => '001002003A', 'CustomerID' => 1,
55
- 'InventoryMethod' => 'FIFO', 'UPC' => '001002003A'}]}
56
- response = client.call(:create_items, :message => msg)
57
-
58
- expect(response.http.body.scan(/<tns:extLoginData>/).count).to eq(1)
59
- end
60
-
61
- it "includes the 'message tag' encapsulation step" do
62
- # This test is probably just exposing a bug while the previous
63
- # test is using a workaround fix.
64
- # That is just a guess though. I don't really have to properly debug the WSDL parser.
65
- client = new_client(:endpoint => @server.url(:repeat), :no_message_tag => false,
66
- :wsdl => Fixture.wsdl(:no_message_tag))
67
- msg = {'extLoginData' => {'Login' => 'test.user', 'Password' => 'secret', 'FacilityID' => 1,
68
- 'ThreePLKey' => '{XXXX-XXXX-XXXX-XXXX}', 'ThreePLID' => 1},
69
- 'Items' => ['Item' => {'SKU' => '001002003A', 'CustomerID' => 1,
70
- 'InventoryMethod' => 'FIFO', 'UPC' => '001002003A'}]}
71
- response = client.call(:create_items, :message => msg)
72
-
73
- expect(response.http.body.scan(/<tns:extLoginData>/).count).to eq(2)
74
- end
75
- end
76
-
77
- context "global :namespaces" do
78
- it "adds additional namespaces to the SOAP envelope" do
79
- namespaces = { "xmlns:whatever" => "http://whatever.example.com" }
80
- client = new_client(:endpoint => @server.url(:repeat), :namespaces => namespaces)
81
- response = client.call(:authenticate)
82
-
83
- expect(response.http.body).to include('xmlns:whatever="http://whatever.example.com"')
84
- end
85
- end
86
-
87
- context 'global :follow_redirects' do
88
- it 'sets whether or not request should follow redirects' do
89
- client = new_client(:endpoint => @server.url, :follow_redirects => true)
90
-
91
- HTTPI::Request.any_instance.expects(:follow_redirect=).with(true)
92
-
93
- response = client.call(:authenticate)
94
- end
95
-
96
- it 'defaults to false' do
97
- client = new_client(:endpoint => @server.url)
98
-
99
- HTTPI::Request.any_instance.expects(:follow_redirect=).with(false)
100
-
101
- response = client.call(:authenticate)
102
- end
103
- end
104
-
105
- context "global :proxy" do
106
- it "sets the proxy server to use" do
107
- proxy_url = "http://example.com"
108
- client = new_client(:endpoint => @server.url, :proxy => proxy_url)
109
-
110
- # TODO: find a way to integration test this [dh, 2012-12-08]
111
- HTTPI::Request.any_instance.expects(:proxy=).with(proxy_url)
112
-
113
- response = client.call(:authenticate)
114
- end
115
- end
116
-
117
- context "global :host" do
118
- it "overrides the WSDL endpoint host" do
119
- client = new_client(:wsdl => Fixture.wsdl(:no_message_tag), host: "https://example.com:8080")
120
-
121
- request = client.build_request(:update_orders)
122
- expect(request.url.to_s).to eq "https://example.com:8080/webserviceexternal/contracts.asmx"
123
- end
124
- end
125
-
126
- context "global :headers" do
127
- it "sets the HTTP headers for the next request" do
128
- client = new_client(:endpoint => @server.url(:inspect_request), :headers => { "X-Token" => "secret" })
129
-
130
- response = client.call(:authenticate)
131
- x_token = inspect_request(response).x_token
132
-
133
- expect(x_token).to eq("secret")
134
- end
135
- end
136
-
137
- context "global :open_timeout" do
138
- it "makes the client timeout after n seconds" do
139
- non_routable_ip = "http://192.0.2.0"
140
- client = new_client(:endpoint => non_routable_ip, :open_timeout => 0.1)
141
-
142
- expect { client.call(:authenticate) }.to raise_error { |error|
143
- host_unreachable = error.kind_of? Errno::EHOSTUNREACH
144
- net_unreachable = error.kind_of? Errno::ENETUNREACH
145
- socket_err = error.kind_of? SocketError
146
- if host_unreachable || net_unreachable || socket_err
147
- warn "Warning: looks like your network may be down?!\n" +
148
- "-> skipping spec at #{__FILE__}:#{__LINE__}"
149
- else
150
- # TODO: make HTTPI tag timeout errors, then depend on HTTPI::TimeoutError
151
- # instead of a specific client error [dh, 2012-12-08]
152
- expect(error).to be_an(HTTPClient::ConnectTimeoutError)
153
- end
154
- }
155
- end
156
- end
157
-
158
- context "global :read_timeout" do
159
- it "makes the client timeout after n seconds" do
160
- client = new_client(:endpoint => @server.url(:timeout), :open_timeout => 0.1, :read_timeout => 0.1)
161
-
162
- expect { client.call(:authenticate) }.
163
- to raise_error(HTTPClient::ReceiveTimeoutError)
164
- end
165
- end
166
-
167
- context "global :encoding" do
168
- it "changes the XML instruction" do
169
- client = new_client(:endpoint => @server.url(:repeat), :encoding => "ISO-8859-1")
170
- response = client.call(:authenticate)
171
-
172
- expect(response.http.body).to match(/<\?xml version="1\.0" encoding="ISO-8859-1"\?>/)
173
- end
174
-
175
- it "changes the Content-Type header" do
176
- client = new_client(:endpoint => @server.url(:inspect_request), :encoding => "ISO-8859-1")
177
-
178
- response = client.call(:authenticate)
179
- content_type = inspect_request(response).content_type
180
- expect(content_type).to eq("text/xml;charset=ISO-8859-1")
181
- end
182
- end
183
-
184
- context "global :soap_header" do
185
- it "accepts a Hash of SOAP header information" do
186
- client = new_client(:endpoint => @server.url(:repeat), :soap_header => { :auth_token => "secret" })
187
- response = client.call(:authenticate)
188
-
189
- expect(response.http.body).to include("<env:Header><authToken>secret</authToken></env:Header>")
190
- end
191
-
192
- it "accepts anything other than a String and calls #to_s on it" do
193
- to_s_header = Class.new {
194
- def to_s
195
- "to_s_header"
196
- end
197
- }.new
198
-
199
- client = new_client(:endpoint => @server.url(:repeat), :soap_header => to_s_header)
200
- response = client.call(:authenticate)
201
-
202
- expect(response.http.body).to include("<env:Header>to_s_header</env:Header>")
203
- end
204
- end
205
-
206
- context "global :element_form_default" do
207
- it "specifies whether elements should be :qualified or :unqualified" do
208
- # qualified
209
- client = new_client(:endpoint => @server.url(:repeat), :element_form_default => :qualified)
210
-
211
- response = client.call(:authenticate, :message => { :user => "luke", :password => "secret" })
212
- expect(response.http.body).to include("<tns:user>luke</tns:user>")
213
- expect(response.http.body).to include("<tns:password>secret</tns:password>")
214
-
215
- # unqualified
216
- client = new_client(:endpoint => @server.url(:repeat), :element_form_default => :unqualified)
217
-
218
- response = client.call(:authenticate, :message => { :user => "lea", :password => "top-secret" })
219
- expect(response.http.body).to include("<user>lea</user>")
220
- expect(response.http.body).to include("<password>top-secret</password>")
221
- end
222
- end
223
-
224
- context "global :env_namespace" do
225
- it "when set, replaces the default namespace identifier for the SOAP envelope" do
226
- client = new_client(:endpoint => @server.url(:repeat), :env_namespace => "soapenv")
227
- response = client.call(:authenticate)
228
-
229
- expect(response.http.body).to include("<soapenv:Envelope")
230
- end
231
-
232
- it "when not set, Savon defaults to use :env as the namespace identifier for the SOAP envelope" do
233
- client = new_client(:endpoint => @server.url(:repeat))
234
- response = client.call(:authenticate)
235
-
236
- expect(response.http.body).to include("<env:Envelope")
237
- end
238
- end
239
-
240
- context "global :soap_version" do
241
- it "it uses the correct SOAP 1.1 namespace" do
242
- client = new_client(:endpoint => @server.url(:repeat), :soap_version => 1)
243
- response = client.call(:authenticate)
244
-
245
- expect(response.http.body).to include('xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"')
246
- end
247
-
248
- it "it uses the correct SOAP 1.2 namespace" do
249
- client = new_client(:endpoint => @server.url(:repeat), :soap_version => 2)
250
- response = client.call(:authenticate)
251
-
252
- expect(response.http.body).to include('xmlns:env="http://www.w3.org/2003/05/soap-envelope"')
253
- end
254
- end
255
-
256
- context "global: raise_errors" do
257
- it "when true, instructs Savon to raise SOAP fault errors" do
258
- client = new_client(:endpoint => @server.url(:repeat), :raise_errors => true)
259
-
260
- expect { client.call(:authenticate, :xml => Fixture.response(:soap_fault)) }.
261
- to raise_error(Savon::SOAPFault)
262
-
263
- begin
264
- client.call(:authenticate, :xml => Fixture.response(:soap_fault))
265
- rescue Savon::SOAPFault => soap_fault
266
- # check whether the configured nori instance is used by the soap fault
267
- expect(soap_fault.to_hash[:fault][:faultcode]).to eq("soap:Server")
268
- end
269
- end
270
-
271
- it "when true, instructs Savon to raise HTTP errors" do
272
- client = new_client(:endpoint => @server.url(404), :raise_errors => true)
273
- expect { client.call(:authenticate) }.to raise_error(Savon::HTTPError)
274
- end
275
-
276
- it "when false, instructs Savon to not raise SOAP fault errors" do
277
- client = new_client(:endpoint => @server.url(:repeat), :raise_errors => false)
278
- response = client.call(:authenticate, :xml => Fixture.response(:soap_fault))
279
-
280
- expect(response).to_not be_successful
281
- expect(response).to be_a_soap_fault
282
- end
283
-
284
- it "when false, instructs Savon to not raise HTTP errors" do
285
- client = new_client(:endpoint => @server.url(404), :raise_errors => false)
286
- response = client.call(:authenticate)
287
-
288
- expect(response).to_not be_successful
289
- expect(response).to be_a_http_error
290
- end
291
- end
292
-
293
- context "global :log" do
294
- it "instructs Savon not to log SOAP requests and responses" do
295
- stdout = mock_stdout {
296
- client = new_client(:endpoint => @server.url, :log => false)
297
- client.call(:authenticate)
298
- }
299
-
300
- expect(stdout.string).to be_empty
301
- end
302
-
303
- it "silences HTTPI as well" do
304
- HTTPI.expects(:log=).with(false)
305
- new_client(:log => false)
306
- end
307
-
308
- it "instructs Savon to log SOAP requests and responses" do
309
- stdout = mock_stdout do
310
- client = new_client(:endpoint => @server.url, :log => true)
311
- client.call(:authenticate)
312
- end
313
-
314
- expect(stdout.string).to include("INFO -- : SOAP request")
315
- end
316
-
317
- it "turns HTTPI logging back on as well" do
318
- HTTPI.expects(:log=).with(true)
319
- new_client(:log => true)
320
- end
321
- end
322
-
323
- context "global :logger" do
324
- it "defaults to an instance of Ruby's standard Logger" do
325
- logger = new_client.globals[:logger]
326
- expect(logger).to be_a(Logger)
327
- end
328
-
329
- it "allows a custom logger to be set" do
330
- custom_logger = Logger.new($stdout)
331
-
332
- client = new_client(:logger => custom_logger, :log => true)
333
- logger = client.globals[:logger]
334
-
335
- expect(logger).to eq(custom_logger)
336
- end
337
-
338
- it "sets the logger of HTTPI as well" do
339
- custom_logger = Logger.new($stdout)
340
-
341
- client = new_client(:logger => custom_logger, :log => true)
342
-
343
- expect(HTTPI.logger).to be custom_logger
344
- end
345
-
346
- end
347
-
348
- context "global :log_level" do
349
- it "allows changing the Logger's log level to :debug" do
350
- client = new_client(:log_level => :debug)
351
- level = client.globals[:logger].level
352
-
353
- expect(level).to eq(0)
354
- end
355
-
356
- it "allows changing the Logger's log level to :info" do
357
- client = new_client(:log_level => :info)
358
- level = client.globals[:logger].level
359
-
360
- expect(level).to eq(1)
361
- end
362
-
363
- it "allows changing the Logger's log level to :warn" do
364
- client = new_client(:log_level => :warn)
365
- level = client.globals[:logger].level
366
-
367
- expect(level).to eq(2)
368
- end
369
-
370
- it "allows changing the Logger's log level to :error" do
371
- client = new_client(:log_level => :error)
372
- level = client.globals[:logger].level
373
-
374
- expect(level).to eq(3)
375
- end
376
-
377
- it "allows changing the Logger's log level to :fatal" do
378
- client = new_client(:log_level => :fatal)
379
- level = client.globals[:logger].level
380
-
381
- expect(level).to eq(4)
382
- end
383
-
384
- it "raises when the given level is not valid" do
385
- expect { new_client(:log_level => :invalid) }.
386
- to raise_error(ArgumentError, /Invalid log level: :invalid/)
387
- end
388
- end
389
-
390
- context "global :ssl_version" do
391
- it "sets the SSL version to use" do
392
- HTTPI::Auth::SSL.any_instance.expects(:ssl_version=).with(:TLSv1).twice
393
-
394
- client = new_client(:endpoint => @server.url, :ssl_version => :TLSv1)
395
- client.call(:authenticate)
396
- end
397
- end
398
-
399
- context "global :ssl_verify_mode" do
400
- it "sets the verify mode to use" do
401
- HTTPI::Auth::SSL.any_instance.expects(:verify_mode=).with(:peer).twice
402
-
403
- client = new_client(:endpoint => @server.url, :ssl_verify_mode => :peer)
404
- client.call(:authenticate)
405
- end
406
- end
407
-
408
- context "global :ssl_ciphers" do
409
- it "sets the ciphers to use" do
410
- HTTPI::Auth::SSL.any_instance.expects(:ciphers=).with(:none).twice
411
-
412
- client = new_client(:endpoint => @server.url, :ssl_ciphers => :none)
413
- client.call(:authenticate)
414
- end
415
- end
416
-
417
- context "global :ssl_cert_key_file" do
418
- it "sets the cert key file to use" do
419
- cert_key = File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)
420
- HTTPI::Auth::SSL.any_instance.expects(:cert_key_file=).with(cert_key).twice
421
-
422
- client = new_client(:endpoint => @server.url, :ssl_cert_key_file => cert_key)
423
- client.call(:authenticate)
424
- end
425
- end
426
-
427
- context "global :ssl_cert_key" do
428
- it "sets the cert key to use" do
429
- cert_key = File.open(File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)).read
430
- HTTPI::Auth::SSL.any_instance.expects(:cert_key=).with(cert_key).twice
431
-
432
- client = new_client(:endpoint => @server.url, :ssl_cert_key => cert_key)
433
- client.call(:authenticate)
434
- end
435
- end
436
-
437
-
438
- context "global :ssl_cert_key_password" do
439
- it "sets the encrypted cert key file password to use" do
440
- cert_key = File.expand_path("../../fixtures/ssl/client_encrypted_key.pem", __FILE__)
441
- cert_key_pass = "secure-password!42"
442
- HTTPI::Auth::SSL.any_instance.expects(:cert_key_file=).with(cert_key).twice
443
- HTTPI::Auth::SSL.any_instance.expects(:cert_key_password=).with(cert_key_pass).twice
444
-
445
- client = new_client(:endpoint => @server.url, :ssl_cert_key_file => cert_key, :ssl_cert_key_password => cert_key_pass)
446
- client.call(:authenticate)
447
- end
448
-
449
- end
450
-
451
- context "global :ssl_cert_file" do
452
- it "sets the cert file to use" do
453
- cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
454
- HTTPI::Auth::SSL.any_instance.expects(:cert_file=).with(cert).twice
455
-
456
- client = new_client(:endpoint => @server.url, :ssl_cert_file => cert)
457
- client.call(:authenticate)
458
- end
459
- end
460
-
461
- context "global :ssl_cert" do
462
- it "sets the cert to use" do
463
- cert = File.open(File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)).read
464
- HTTPI::Auth::SSL.any_instance.expects(:cert=).with(cert).twice
465
-
466
- client = new_client(:endpoint => @server.url, :ssl_cert => cert)
467
- client.call(:authenticate)
468
- end
469
- end
470
-
471
- context "global :ssl_ca_cert_file" do
472
- it "sets the ca cert file to use" do
473
- ca_cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
474
- HTTPI::Auth::SSL.any_instance.expects(:ca_cert_file=).with(ca_cert).twice
475
-
476
- client = new_client(:endpoint => @server.url, :ssl_ca_cert_file => ca_cert)
477
- client.call(:authenticate)
478
- end
479
- end
480
-
481
- context "global :ssl_ca_cert_path" do
482
- it "sets the ca cert path to use" do
483
- ca_cert_path = "../../fixtures/ssl"
484
- HTTPI::Auth::SSL.any_instance.expects(:ca_cert_path=).with(ca_cert_path).twice
485
-
486
- client = new_client(:endpoint => @server.url, :ssl_ca_cert_path => ca_cert_path)
487
- client.call(:authenticate)
488
- end
489
- end
490
-
491
- context "global :ssl_ca_cert_store" do
492
- it "sets the cert store to use" do
493
- cert_store = OpenSSL::X509::Store.new
494
- HTTPI::Auth::SSL.any_instance.expects(:cert_store=).with(cert_store).twice
495
-
496
- client = new_client(:endpoint => @server.url, :ssl_cert_store => cert_store)
497
- client.call(:authenticate)
498
- end
499
- end
500
-
501
- context "global :ssl_ca_cert" do
502
- it "sets the ca cert file to use" do
503
- ca_cert = File.open(File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)).read
504
- HTTPI::Auth::SSL.any_instance.expects(:ca_cert=).with(ca_cert).twice
505
-
506
- client = new_client(:endpoint => @server.url, :ssl_ca_cert => ca_cert)
507
- client.call(:authenticate)
508
- end
509
- end
510
-
511
-
512
- context "global :basic_auth" do
513
- it "sets the basic auth credentials" do
514
- client = new_client(:endpoint => @server.url(:basic_auth), :basic_auth => ["admin", "secret"])
515
- response = client.call(:authenticate)
516
-
517
- expect(response.http.body).to eq("basic-auth")
518
- end
519
- end
520
-
521
- context "global :digest_auth" do
522
- it "sets the digest auth credentials" do
523
- client = new_client(:endpoint => @server.url(:digest_auth), :digest_auth => ["admin", "secret"])
524
- response = client.call(:authenticate)
525
-
526
- expect(response.http.body).to eq("digest-auth")
527
- end
528
- end
529
-
530
- context "global :ntlm" do
531
- it "sets the ntlm credentials to use" do
532
- credentials = ["admin", "secret"]
533
- client = new_client(:endpoint => @server.url, :ntlm => credentials)
534
-
535
- # TODO: find a way to integration test this. including an entire ntlm
536
- # server implementation seems a bit over the top though.
537
- HTTPI::Auth::Config.any_instance.expects(:ntlm).with(*credentials)
538
-
539
- response = client.call(:authenticate)
540
- end
541
- end
542
-
543
- context "global :filters" do
544
- it "filters a list of XML tags from logged SOAP messages" do
545
- captured = mock_stdout do
546
- client = new_client(:endpoint => @server.url(:repeat), :log => true)
547
- client.globals[:filters] << :password
548
-
549
- message = { :username => "luke", :password => "secret" }
550
- client.call(:authenticate, :message => message)
551
- end
552
-
553
- captured.rewind
554
- messages = captured.readlines.join("\n")
555
-
556
- expect(messages).to include("<password>***FILTERED***</password>")
557
- end
558
- end
559
-
560
- context "global :pretty_print_xml" do
561
- it "is a nice but expensive way to debug XML messages" do
562
- captured = mock_stdout do
563
- client = new_client(
564
- :endpoint => @server.url(:repeat),
565
- :pretty_print_xml => true,
566
- :log => true)
567
- client.globals[:logger].formatter = proc { |*, msg| "#{msg}\n" }
568
-
569
- client.call(:authenticate)
570
- end
571
-
572
- captured.rewind
573
- messages = captured.readlines.join("\n")
574
-
575
- expect(messages).to match(/\n<env:Envelope/)
576
- expect(messages).to match(/\n <env:Body/)
577
- expect(messages).to match(/\n <tns:authenticate/)
578
- end
579
- end
580
-
581
- context ":wsse_auth" do
582
- let(:username) { "luke" }
583
- let(:password) { "secret" }
584
- let(:request) { response.http.body }
585
-
586
- shared_examples "WSSE basic auth" do
587
- it "adds WSSE basic auth information to the request" do
588
- # the header and wsse security node
589
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
590
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
591
-
592
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
593
- expect(request).to include("<wsse:UsernameToken")
594
- expect(request).to include("wsu:Id=\"UsernameToken-1\"")
595
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
596
-
597
- # the username and password node with type attribute
598
- expect(request).to include("<wsse:Username>#{username}</wsse:Username>")
599
- password_text = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
600
- expect(request).to include("<wsse:Password Type=\"#{password_text}\">#{password}</wsse:Password>")
601
- end
602
- end
603
-
604
- shared_examples "WSSE digest auth" do
605
- it "adds WSSE digest auth information to the request" do
606
- # the header and wsse security node
607
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
608
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
609
-
610
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
611
- expect(request).to include("<wsse:UsernameToken")
612
- expect(request).to include("wsu:Id=\"UsernameToken-1\"")
613
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
614
-
615
- # the username node
616
- expect(request).to include("<wsse:Username>#{username}</wsse:Username>")
617
-
618
- # the nonce node
619
- expect(request).to match(/<wsse:Nonce.*>.+\n?<\/wsse:Nonce>/)
620
-
621
- # the created node with a timestamp
622
- expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
623
-
624
- # the password node contains the encrypted value
625
- password_digest = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
626
- expect(request).to match(/<wsse:Password Type=\"#{password_digest}\">.+<\/wsse:Password>/)
627
- expect(request).to_not include(password)
628
- end
629
- end
630
-
631
- shared_examples "no WSSE auth" do
632
- it "does not add WSSE auth to the request" do
633
- expect(request).not_to include("<wsse:UsernameToken")
634
- end
635
- end
636
-
637
- describe "global" do
638
- context "enabled" do
639
- context "without digest" do
640
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password]) }
641
- let(:response) { client.call(:authenticate) }
642
- include_examples "WSSE basic auth"
643
- end
644
-
645
- context "with digest" do
646
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password, :digest]) }
647
- let(:response) { client.call(:authenticate) }
648
- include_examples "WSSE digest auth"
649
- end
650
-
651
- context "local override" do
652
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => ["luke", "secret"]) }
653
-
654
- context "enabled" do
655
- let(:username) { "lea" }
656
- let(:password) { "top-secret" }
657
-
658
- context "without digest" do
659
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password)} }
660
- include_examples "WSSE basic auth"
661
- end
662
-
663
- context "with digest" do
664
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password, :digest)} }
665
- include_examples "WSSE digest auth"
666
- end
667
- end
668
-
669
- context "disabled" do
670
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(false)} }
671
- include_examples "no WSSE auth"
672
- end
673
-
674
- context "set to nil" do
675
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(nil)} }
676
- include_examples "WSSE basic auth"
677
- end
678
- end
679
-
680
- context "global" do
681
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password, :digest]) }
682
- let(:response) { client.call(:authenticate) }
683
- include_examples "WSSE digest auth"
684
- end
685
- end
686
-
687
- context "not enabled" do
688
- let(:client) { new_client(:endpoint => @server.url(:repeat)) }
689
-
690
- describe "local" do
691
- context "enabled" do
692
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password, :digest)} }
693
- include_examples "WSSE digest auth"
694
- end
695
-
696
- context "disabled" do
697
- let(:response) { client.call(:authenticate) { |locals| locals.wsse_auth(false)} }
698
- include_examples "no WSSE auth"
699
- end
700
-
701
- context "set to nil" do
702
- let(:response) { client.call(:authenticate) { |locals| locals.wsse_auth(nil)} }
703
- include_examples "no WSSE auth"
704
- end
705
- end
706
- end
707
- end
708
- end
709
-
710
- context ":wsse_timestamp" do
711
- let(:request) { response.http.body }
712
-
713
- shared_examples "WSSE timestamp" do
714
- it "adds WSSE timestamp auth information to the request" do
715
- # the header and wsse security node
716
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
717
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
718
-
719
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
720
- expect(request).to include("<wsu:Timestamp")
721
- expect(request).to include("wsu:Id=\"Timestamp-1\"")
722
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
723
-
724
- # the created node with a timestamp
725
- expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
726
-
727
- # the expires node with a timestamp
728
- expect(request).to match(/<wsu:Expires>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Expires>/)
729
- end
730
- end
731
-
732
- shared_examples "no WSSE timestamp" do
733
- it "does not add WSSE timestamp to the request" do
734
- expect(request).not_to include("<wsu:Timestamp")
735
- end
736
- end
737
-
738
- describe "global" do
739
- context "enabled" do
740
- context "through block without arguments" do
741
- let(:client) do
742
- new_client(:endpoint => @server.url(:repeat)) do |globals|
743
- globals.wsse_timestamp
744
- end
745
- end
746
- let(:response) { client.call(:authenticate) }
747
- include_examples "WSSE timestamp"
748
- end
749
-
750
- context "through initializer options" do
751
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true) }
752
- let(:response) { client.call(:authenticate) }
753
- include_examples "WSSE timestamp"
754
- end
755
-
756
- context "with local override" do
757
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true) }
758
- context "enabled" do
759
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp} }
760
- include_examples "WSSE timestamp"
761
- end
762
- context "disabled" do
763
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(false) } }
764
- include_examples "no WSSE timestamp"
765
- end
766
- context "set to nil" do
767
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(nil) } }
768
- include_examples "WSSE timestamp"
769
- end
770
- end
771
- end
772
-
773
- context "not enabled" do
774
- let(:client) { new_client(:endpoint => @server.url(:repeat)) }
775
- describe "local" do
776
- context "enabled" do
777
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp} }
778
- include_examples "WSSE timestamp"
779
- end
780
- context "disabled" do
781
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(false) } }
782
- include_examples "no WSSE timestamp"
783
- end
784
- context "set to nil" do
785
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(nil) } }
786
- include_examples "no WSSE timestamp"
787
- end
788
- end
789
- end
790
- end
791
- end
792
-
793
- context "global :strip_namespaces" do
794
- it "can be changed to not strip any namespaces" do
795
- client = new_client(
796
- :endpoint => @server.url(:repeat),
797
- :convert_response_tags_to => lambda { |tag| tag.snakecase },
798
- :strip_namespaces => false
799
- )
800
-
801
- response = client.call(:authenticate, :xml => Fixture.response(:authentication))
802
-
803
- expect(response.hash["soap:envelope"]["soap:body"]).to include("ns2:authenticate_response")
804
- end
805
- end
806
-
807
- context "global :convert_request_keys_to" do
808
- it "changes how Hash message key Symbols are translated to XML tags for the request" do
809
- client = new_client_without_wsdl do |globals|
810
- globals.endpoint @server.url(:repeat)
811
- globals.namespace "http://v1.example.com"
812
- globals.convert_request_keys_to :camelcase # or one of [:lower_camelcase, :upcase, :none]
813
- end
814
-
815
- response = client.call(:find_user) do |locals|
816
- locals.message(:user_name => "luke", "pass_word" => "secret")
817
- end
818
-
819
- request = response.http.body
820
-
821
- # split into multiple assertions thanks to 1.8
822
- expect(request).to include("<wsdl:FindUser>")
823
- expect(request).to include("<UserName>luke</UserName>")
824
- expect(request).to include("<pass_word>secret</pass_word>")
825
- end
826
- end
827
-
828
- context "global :convert_response_tags_to" do
829
- it "changes how XML tags from the SOAP response are translated into Hash keys" do
830
- client = new_client(:endpoint => @server.url(:repeat), :convert_response_tags_to => lambda { |tag| tag.snakecase.upcase })
831
- response = client.call(:authenticate, :xml => Fixture.response(:authentication))
832
-
833
- expect(response.hash["ENVELOPE"]["BODY"]).to include("AUTHENTICATE_RESPONSE")
834
- end
835
-
836
- it "accepts a block in the block-based interface" do
837
- client = Savon.client do |globals|
838
- globals.log false
839
- globals.wsdl Fixture.wsdl(:authentication)
840
- globals.endpoint @server.url(:repeat)
841
- globals.convert_response_tags_to { |tag| tag.snakecase.upcase }
842
- end
843
-
844
- response = client.call(:authenticate) do |locals|
845
- locals.xml Fixture.response(:authentication)
846
- end
847
-
848
- expect(response.hash["ENVELOPE"]["BODY"]).to include("AUTHENTICATE_RESPONSE")
849
- end
850
- end
851
-
852
- context "global :convert_attributes_to" do
853
- it "changes how XML tag attributes from the SOAP response are translated into Hash keys" do
854
- client = new_client(:endpoint => @server.url(:repeat), :convert_attributes_to => lambda {|k,v| [k,v]})
855
- response = client.call(:authenticate, :xml => Fixture.response(:f5))
856
- expect(response.body[:get_agent_listen_address_response][:return][:item].first[:ipport][:address]).to eq({:"@s:type"=>"y:string"})
857
- end
858
-
859
- it "strips the attributes if an appropriate lambda is set" do
860
- client = new_client(:endpoint => @server.url(:repeat), :convert_attributes_to => lambda {|k,v| []})
861
- response = client.call(:authenticate, :xml => Fixture.response(:f5))
862
- expect(response.body[:get_agent_listen_address_response][:return][:item].first[:ipport][:address]).to eq(nil)
863
- end
864
-
865
- it "accepts a block in the block-based interface" do
866
- client = Savon.client do |globals|
867
- globals.log false
868
- globals.wsdl Fixture.wsdl(:authentication)
869
- globals.endpoint @server.url(:repeat)
870
- globals.convert_attributes_to {|k,v| [k,v]}
871
- end
872
-
873
- response = client.call(:authenticate) do |locals|
874
- locals.xml Fixture.response(:f5)
875
- end
876
-
877
- expect(response.body[:get_agent_listen_address_response][:return][:item].first[:ipport][:address]).to eq({:"@s:type"=>"y:string"})
878
- end
879
- end
880
-
881
- context 'global: :adapter' do
882
- it 'passes option to Wasabi initializer for WSDL fetching' do
883
- ## I want to use there something similar to the next mock expectation, but I can't
884
- ## as due to how Savon sets up Wasabi::Document and Wasabi::Document initialize itself
885
- ## adapter= method is called first time with nil and second time with adapter. [Envek, 2014-05-03]
886
- # Wasabi::Document.any_instance.expects(:adapter=).with(:fake_adapter_for_test)
887
- client = Savon.client(
888
- :log => false,
889
- :wsdl => @server.url(:authentication),
890
- :adapter => :fake_adapter_for_test,
891
- )
892
- operations = client.operations
893
- expect(operations).to eq([:authenticate])
894
- expect(FakeAdapterForTest.class_variable_get(:@@requests).size).to eq(1)
895
- expect(FakeAdapterForTest.class_variable_get(:@@requests).first.url).to eq(URI.parse(@server.url(:authentication)))
896
- expect(FakeAdapterForTest.class_variable_get(:@@methods)).to eq([:get])
897
- end
898
-
899
- it 'instructs HTTPI to use provided adapter for performing SOAP requests' do
900
- client = new_client_without_wsdl(
901
- :endpoint => @server.url(:repeat),
902
- :namespace => "http://v1.example.com",
903
- :adapter => :adapter_for_test,
904
- )
905
- response = client.call(:authenticate)
906
- expect(response.http.body).to include('xmlns:wsdl="http://v1.example.com"')
907
- expect(response.http.body).to include('<wsdl:authenticate>')
908
- expect(AdapterForTest.class_variable_get(:@@requests).size).to eq(1)
909
- expect(AdapterForTest.class_variable_get(:@@requests).first.url).to eq(URI.parse(@server.url(:repeat)))
910
- expect(AdapterForTest.class_variable_get(:@@methods)).to eq([:post])
911
- end
912
- end
913
-
914
- context "global and request :soap_header" do
915
- it "merges the headers if both were provided as Hashes" do
916
- global_soap_header = {
917
- :global_header => { :auth_token => "secret" },
918
- :merged => { :global => true }
919
- }
920
-
921
- request_soap_header = {
922
- :request_header => { :auth_token => "secret" },
923
- :merged => { :request => true }
924
- }
925
-
926
- client = new_client(:endpoint => @server.url(:repeat), :soap_header => global_soap_header)
927
-
928
- response = client.call(:authenticate, :soap_header => request_soap_header)
929
- request_body = response.http.body
930
-
931
- expect(request_body).to include("<globalHeader><authToken>secret</authToken></globalHeader>")
932
- expect(request_body).to include("<requestHeader><authToken>secret</authToken></requestHeader>")
933
- expect(request_body).to include("<merged><request>true</request></merged>")
934
- end
935
-
936
- it "prefers the request over the global option if at least one of them is not a Hash" do
937
- global_soap_header = "<global>header</global>"
938
- request_soap_header = "<request>header</request>"
939
-
940
- client = new_client(:endpoint => @server.url(:repeat), :soap_header => global_soap_header)
941
-
942
- response = client.call(:authenticate, :soap_header => request_soap_header)
943
- request_body = response.http.body
944
-
945
- expect(request_body).to include("<env:Header><request>header</request></env:Header>")
946
- end
947
- end
948
-
949
- context "request :soap_header" do
950
- it "accepts a Hash of SOAP header information" do
951
- client = new_client(:endpoint => @server.url(:repeat))
952
-
953
- response = client.call(:authenticate, :soap_header => { :auth_token => "secret" })
954
- expect(response.http.body).to include("<env:Header><authToken>secret</authToken></env:Header>")
955
- end
956
-
957
- it "accepts anything other than a String and calls #to_s on it" do
958
- to_s_header = Class.new {
959
- def to_s
960
- "to_s_header"
961
- end
962
- }.new
963
-
964
- client = new_client(:endpoint => @server.url(:repeat))
965
-
966
- response = client.call(:authenticate, :soap_header => to_s_header)
967
- expect(response.http.body).to include("<env:Header>to_s_header</env:Header>")
968
- end
969
- end
970
-
971
- context "request: message_tag" do
972
- it "when set, changes the SOAP message tag" do
973
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :message_tag => :doAuthenticate)
974
- expect(response.http.body).to include("<tns:doAuthenticate></tns:doAuthenticate>")
975
- end
976
-
977
- it "without it, Savon tries to get the message tag from the WSDL document" do
978
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate)
979
- expect(response.http.body).to include("<tns:authenticate></tns:authenticate>")
980
- end
981
-
982
- it "without the option and a WSDL, Savon defaults to Gyoku to create the name" do
983
- client = Savon.client(:endpoint => @server.url(:repeat), :namespace => "http://v1.example.com", :log => false)
984
-
985
- response = client.call(:init_authentication)
986
- expect(response.http.body).to include("<wsdl:initAuthentication></wsdl:initAuthentication>")
987
- end
988
- end
989
-
990
- context "request: attributes" do
991
- it "when set, adds the attributes to the message tag" do
992
- client = new_client(:endpoint => @server.url(:repeat))
993
- response = client.call(:authenticate, :attributes => { "Token" => "secret"})
994
-
995
- expect(response.http.body).to include('<tns:authenticate Token="secret">')
996
- end
997
- end
998
-
999
- context "request: soap_action" do
1000
- it "without it, Savon tries to get the SOAPAction from the WSDL document and falls back to Gyoku" do
1001
- client = new_client(:endpoint => @server.url(:inspect_request))
1002
-
1003
- response = client.call(:authenticate)
1004
- soap_action = inspect_request(response).soap_action
1005
- expect(soap_action).to eq('"authenticate"')
1006
- end
1007
-
1008
- it "when set, changes the SOAPAction HTTP header" do
1009
- client = new_client(:endpoint => @server.url(:inspect_request))
1010
-
1011
- response = client.call(:authenticate, :soap_action => "doAuthenticate")
1012
- soap_action = inspect_request(response).soap_action
1013
- expect(soap_action).to eq('"doAuthenticate"')
1014
- end
1015
- end
1016
-
1017
- context "request :message" do
1018
- it "accepts a Hash which is passed to Gyoku to be converted to XML" do
1019
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :message => { :user => "luke", :password => "secret" })
1020
-
1021
- request = response.http.body
1022
- expect(request).to include("<user>luke</user>")
1023
- expect(request).to include("<password>secret</password>")
1024
- end
1025
-
1026
- it "also accepts a String of raw XML" do
1027
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :message => "<user>lea</user><password>top-secret</password>")
1028
- expect(response.http.body).to include("<tns:authenticate><user>lea</user><password>top-secret</password></tns:authenticate>")
1029
- end
1030
- end
1031
-
1032
- context "request :xml" do
1033
- it "accepts a String of raw XML" do
1034
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :xml => "<soap>request</soap>")
1035
- expect(response.http.body).to eq("<soap>request</soap>")
1036
- end
1037
- end
1038
-
1039
- context "request :cookies" do
1040
- it "accepts an Array of HTTPI::Cookie objects for the next request" do
1041
- cookies = [
1042
- HTTPI::Cookie.new("some-cookie=choc-chip"),
1043
- HTTPI::Cookie.new("another-cookie=ny-cheesecake")
1044
- ]
1045
-
1046
- client = new_client(:endpoint => @server.url(:inspect_request))
1047
- response = client.call(:authenticate, :cookies => cookies)
1048
-
1049
- cookie = inspect_request(response).cookie
1050
- expect(cookie.split(";")).to include(
1051
- "some-cookie=choc-chip",
1052
- "another-cookie=ny-cheesecake"
1053
- )
1054
- end
1055
- end
1056
-
1057
- context "request :advanced_typecasting" do
1058
- it "can be changed to false to disable Nori's advanced typecasting" do
1059
- client = new_client(:endpoint => @server.url(:repeat))
1060
- response = client.call(:authenticate, :xml => Fixture.response(:authentication), :advanced_typecasting => false)
1061
-
1062
- expect(response.body[:authenticate_response][:return][:success]).to eq("true")
1063
- end
1064
- end
1065
-
1066
- context "request :response_parser" do
1067
- it "instructs Nori to change the response parser" do
1068
- nori = Nori.new(:strip_namespaces => true, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
1069
- Nori.expects(:new).with { |options| options[:parser] == :nokogiri }.returns(nori)
1070
-
1071
- client = new_client(:endpoint => @server.url(:repeat))
1072
- response = client.call(:authenticate, :xml => Fixture.response(:authentication), :response_parser => :nokogiri)
1073
-
1074
- expect(response.body).to_not be_empty
1075
- end
1076
- end
1077
-
1078
- context "request :headers" do
1079
- it "sets headers" do
1080
- client = new_client(:endpoint => @server.url(:inspect_request))
1081
-
1082
- response = client.call(:authenticate, :headers => { "X-Token" => "secret" })
1083
- x_token = inspect_request(response).x_token
1084
-
1085
- expect(x_token).to eq("secret")
1086
- end
1087
- end
1088
-
1089
- def new_client(globals = {}, &block)
1090
- globals = { :wsdl => Fixture.wsdl(:authentication), :log => false }.merge(globals)
1091
- Savon.client(globals, &block)
1092
- end
1093
-
1094
- def new_client_without_wsdl(globals = {}, &block)
1095
- globals = { :log => false }.merge(globals)
1096
- Savon.client(globals, &block)
1097
- end
1098
-
1099
- def inspect_request(response)
1100
- hash = JSON.parse(response.http.body)
1101
- OpenStruct.new(hash)
1102
- end
1103
-
1104
- end