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