savon 2.11.2 → 2.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +112 -73
  3. data/README.md +25 -16
  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 +71 -2
  17. data/lib/savon/qualified_message.rb +5 -4
  18. data/lib/savon/request.rb +18 -3
  19. data/lib/savon/request_logger.rb +8 -2
  20. data/lib/savon/response.rb +52 -5
  21. data/lib/savon/soap_fault.rb +2 -3
  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 +62 -97
  26. data/.gitignore +0 -14
  27. data/.travis.yml +0 -19
  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/soap_fault.xml +0 -8
  42. data/spec/fixtures/response/soap_fault12.xml +0 -18
  43. data/spec/fixtures/response/soap_fault_funky.xml +0 -8
  44. data/spec/fixtures/response/taxcloud.xml +0 -1
  45. data/spec/fixtures/ssl/client_cert.pem +0 -16
  46. data/spec/fixtures/ssl/client_encrypted_key.pem +0 -30
  47. data/spec/fixtures/ssl/client_encrypted_key_cert.pem +0 -24
  48. data/spec/fixtures/ssl/client_key.pem +0 -15
  49. data/spec/fixtures/wsdl/authentication.xml +0 -63
  50. data/spec/fixtures/wsdl/betfair.xml +0 -2981
  51. data/spec/fixtures/wsdl/brand.xml +0 -624
  52. data/spec/fixtures/wsdl/edialog.xml +0 -15416
  53. data/spec/fixtures/wsdl/interhome.xml +0 -2137
  54. data/spec/fixtures/wsdl/lower_camel.xml +0 -52
  55. data/spec/fixtures/wsdl/multiple_namespaces.xml +0 -92
  56. data/spec/fixtures/wsdl/multiple_types.xml +0 -60
  57. data/spec/fixtures/wsdl/no_message_tag.xml +0 -1267
  58. data/spec/fixtures/wsdl/taxcloud.xml +0 -934
  59. data/spec/fixtures/wsdl/team_software.xml +0 -1
  60. data/spec/fixtures/wsdl/vies.xml +0 -176
  61. data/spec/fixtures/wsdl/wasmuth.xml +0 -153
  62. data/spec/integration/centra_spec.rb +0 -66
  63. data/spec/integration/email_example_spec.rb +0 -32
  64. data/spec/integration/random_quote_spec.rb +0 -23
  65. data/spec/integration/ratp_example_spec.rb +0 -28
  66. data/spec/integration/stockquote_example_spec.rb +0 -34
  67. data/spec/integration/support/application.rb +0 -82
  68. data/spec/integration/support/server.rb +0 -84
  69. data/spec/integration/temperature_example_spec.rb +0 -46
  70. data/spec/integration/zipcode_example_spec.rb +0 -42
  71. data/spec/savon/builder_spec.rb +0 -137
  72. data/spec/savon/client_spec.rb +0 -271
  73. data/spec/savon/core_ext/string_spec.rb +0 -37
  74. data/spec/savon/features/message_tag_spec.rb +0 -61
  75. data/spec/savon/http_error_spec.rb +0 -49
  76. data/spec/savon/log_message_spec.rb +0 -50
  77. data/spec/savon/message_spec.rb +0 -70
  78. data/spec/savon/mock_spec.rb +0 -174
  79. data/spec/savon/model_spec.rb +0 -182
  80. data/spec/savon/observers_spec.rb +0 -92
  81. data/spec/savon/operation_spec.rb +0 -230
  82. data/spec/savon/options_spec.rb +0 -1075
  83. data/spec/savon/qualified_message_spec.rb +0 -68
  84. data/spec/savon/request_logger_spec.rb +0 -37
  85. data/spec/savon/request_spec.rb +0 -496
  86. data/spec/savon/response_spec.rb +0 -270
  87. data/spec/savon/soap_fault_spec.rb +0 -136
  88. data/spec/savon/softlayer_spec.rb +0 -27
  89. data/spec/spec_helper.rb +0 -30
  90. data/spec/support/adapters.rb +0 -48
  91. data/spec/support/endpoint.rb +0 -25
  92. data/spec/support/fixture.rb +0 -39
  93. data/spec/support/integration.rb +0 -9
  94. data/spec/support/stdout.rb +0 -25
@@ -1,1075 +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(:SSLv3).twice
393
-
394
- client = new_client(:endpoint => @server.url, :ssl_version => :SSLv3)
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(:none).twice
402
-
403
- client = new_client(:endpoint => @server.url, :ssl_verify_mode => :none)
404
- client.call(:authenticate)
405
- end
406
- end
407
-
408
- context "global :ssl_cert_key_file" do
409
- it "sets the cert key file to use" do
410
- cert_key = File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)
411
- HTTPI::Auth::SSL.any_instance.expects(:cert_key_file=).with(cert_key).twice
412
-
413
- client = new_client(:endpoint => @server.url, :ssl_cert_key_file => cert_key)
414
- client.call(:authenticate)
415
- end
416
- end
417
-
418
- context "global :ssl_cert_key" do
419
- it "sets the cert key to use" do
420
- cert_key = File.open(File.expand_path("../../fixtures/ssl/client_key.pem", __FILE__)).read
421
- HTTPI::Auth::SSL.any_instance.expects(:cert_key=).with(cert_key).twice
422
-
423
- client = new_client(:endpoint => @server.url, :ssl_cert_key => cert_key)
424
- client.call(:authenticate)
425
- end
426
- end
427
-
428
-
429
- context "global :ssl_cert_key_password" do
430
- it "sets the encrypted cert key file password to use" do
431
- cert_key = File.expand_path("../../fixtures/ssl/client_encrypted_key.pem", __FILE__)
432
- cert_key_pass = "secure-password!42"
433
- HTTPI::Auth::SSL.any_instance.expects(:cert_key_file=).with(cert_key).twice
434
- HTTPI::Auth::SSL.any_instance.expects(:cert_key_password=).with(cert_key_pass).twice
435
-
436
- client = new_client(:endpoint => @server.url, :ssl_cert_key_file => cert_key, :ssl_cert_key_password => cert_key_pass)
437
- client.call(:authenticate)
438
- end
439
-
440
- end
441
-
442
- context "global :ssl_cert_file" do
443
- it "sets the cert file to use" do
444
- cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
445
- HTTPI::Auth::SSL.any_instance.expects(:cert_file=).with(cert).twice
446
-
447
- client = new_client(:endpoint => @server.url, :ssl_cert_file => cert)
448
- client.call(:authenticate)
449
- end
450
- end
451
-
452
- context "global :ssl_cert" do
453
- it "sets the cert to use" do
454
- cert = File.open(File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)).read
455
- HTTPI::Auth::SSL.any_instance.expects(:cert=).with(cert).twice
456
-
457
- client = new_client(:endpoint => @server.url, :ssl_cert => cert)
458
- client.call(:authenticate)
459
- end
460
- end
461
-
462
- context "global :ssl_ca_cert_file" do
463
- it "sets the ca cert file to use" do
464
- ca_cert = File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)
465
- HTTPI::Auth::SSL.any_instance.expects(:ca_cert_file=).with(ca_cert).twice
466
-
467
- client = new_client(:endpoint => @server.url, :ssl_ca_cert_file => ca_cert)
468
- client.call(:authenticate)
469
- end
470
- end
471
-
472
- context "global :ssl_ca_cert" do
473
- it "sets the ca cert file to use" do
474
- ca_cert = File.open(File.expand_path("../../fixtures/ssl/client_cert.pem", __FILE__)).read
475
- HTTPI::Auth::SSL.any_instance.expects(:ca_cert=).with(ca_cert).twice
476
-
477
- client = new_client(:endpoint => @server.url, :ssl_ca_cert => ca_cert)
478
- client.call(:authenticate)
479
- end
480
- end
481
-
482
-
483
- context "global :basic_auth" do
484
- it "sets the basic auth credentials" do
485
- client = new_client(:endpoint => @server.url(:basic_auth), :basic_auth => ["admin", "secret"])
486
- response = client.call(:authenticate)
487
-
488
- expect(response.http.body).to eq("basic-auth")
489
- end
490
- end
491
-
492
- context "global :digest_auth" do
493
- it "sets the digest auth credentials" do
494
- client = new_client(:endpoint => @server.url(:digest_auth), :digest_auth => ["admin", "secret"])
495
- response = client.call(:authenticate)
496
-
497
- expect(response.http.body).to eq("digest-auth")
498
- end
499
- end
500
-
501
- context "global :ntlm" do
502
- it "sets the ntlm credentials to use" do
503
- credentials = ["admin", "secret"]
504
- client = new_client(:endpoint => @server.url, :ntlm => credentials)
505
-
506
- # TODO: find a way to integration test this. including an entire ntlm
507
- # server implementation seems a bit over the top though.
508
- HTTPI::Auth::Config.any_instance.expects(:ntlm).with(*credentials)
509
-
510
- response = client.call(:authenticate)
511
- end
512
- end
513
-
514
- context "global :filters" do
515
- it "filters a list of XML tags from logged SOAP messages" do
516
- captured = mock_stdout do
517
- client = new_client(:endpoint => @server.url(:repeat), :log => true)
518
- client.globals[:filters] << :password
519
-
520
- message = { :username => "luke", :password => "secret" }
521
- client.call(:authenticate, :message => message)
522
- end
523
-
524
- captured.rewind
525
- messages = captured.readlines.join("\n")
526
-
527
- expect(messages).to include("<password>***FILTERED***</password>")
528
- end
529
- end
530
-
531
- context "global :pretty_print_xml" do
532
- it "is a nice but expensive way to debug XML messages" do
533
- captured = mock_stdout do
534
- client = new_client(
535
- :endpoint => @server.url(:repeat),
536
- :pretty_print_xml => true,
537
- :log => true)
538
- client.globals[:logger].formatter = proc { |*, msg| "#{msg}\n" }
539
-
540
- client.call(:authenticate)
541
- end
542
-
543
- captured.rewind
544
- messages = captured.readlines.join("\n")
545
-
546
- expect(messages).to match(/\n<env:Envelope/)
547
- expect(messages).to match(/\n <env:Body/)
548
- expect(messages).to match(/\n <tns:authenticate/)
549
- end
550
- end
551
-
552
- context ":wsse_auth" do
553
- let(:username) { "luke" }
554
- let(:password) { "secret" }
555
- let(:request) { response.http.body }
556
-
557
- shared_examples "WSSE basic auth" do
558
- it "adds WSSE basic auth information to the request" do
559
- # the header and wsse security node
560
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
561
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
562
-
563
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
564
- expect(request).to include("<wsse:UsernameToken")
565
- expect(request).to include("wsu:Id=\"UsernameToken-1\"")
566
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
567
-
568
- # the username and password node with type attribute
569
- expect(request).to include("<wsse:Username>#{username}</wsse:Username>")
570
- password_text = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
571
- expect(request).to include("<wsse:Password Type=\"#{password_text}\">#{password}</wsse:Password>")
572
- end
573
- end
574
-
575
- shared_examples "WSSE digest auth" do
576
- it "adds WSSE digest auth information to the request" do
577
- # the header and wsse security node
578
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
579
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
580
-
581
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
582
- expect(request).to include("<wsse:UsernameToken")
583
- expect(request).to include("wsu:Id=\"UsernameToken-1\"")
584
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
585
-
586
- # the username node
587
- expect(request).to include("<wsse:Username>#{username}</wsse:Username>")
588
-
589
- # the nonce node
590
- expect(request).to match(/<wsse:Nonce.*>.+\n?<\/wsse:Nonce>/)
591
-
592
- # the created node with a timestamp
593
- expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
594
-
595
- # the password node contains the encrypted value
596
- password_digest = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
597
- expect(request).to match(/<wsse:Password Type=\"#{password_digest}\">.+<\/wsse:Password>/)
598
- expect(request).to_not include(password)
599
- end
600
- end
601
-
602
- shared_examples "no WSSE auth" do
603
- it "does not add WSSE auth to the request" do
604
- expect(request).not_to include("<wsse:UsernameToken")
605
- end
606
- end
607
-
608
- describe "global" do
609
- context "enabled" do
610
- context "without digest" do
611
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password]) }
612
- let(:response) { client.call(:authenticate) }
613
- include_examples "WSSE basic auth"
614
- end
615
-
616
- context "with digest" do
617
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password, :digest]) }
618
- let(:response) { client.call(:authenticate) }
619
- include_examples "WSSE digest auth"
620
- end
621
-
622
- context "local override" do
623
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => ["luke", "secret"]) }
624
-
625
- context "enabled" do
626
- let(:username) { "lea" }
627
- let(:password) { "top-secret" }
628
-
629
- context "without digest" do
630
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password)} }
631
- include_examples "WSSE basic auth"
632
- end
633
-
634
- context "with digest" do
635
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password, :digest)} }
636
- include_examples "WSSE digest auth"
637
- end
638
- end
639
-
640
- context "disabled" do
641
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(false)} }
642
- include_examples "no WSSE auth"
643
- end
644
-
645
- context "set to nil" do
646
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(nil)} }
647
- include_examples "WSSE basic auth"
648
- end
649
- end
650
-
651
- context "global" do
652
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password, :digest]) }
653
- let(:response) { client.call(:authenticate) }
654
- include_examples "WSSE digest auth"
655
- end
656
- end
657
-
658
- context "not enabled" do
659
- let(:client) { new_client(:endpoint => @server.url(:repeat)) }
660
-
661
- describe "local" do
662
- context "enabled" do
663
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password, :digest)} }
664
- include_examples "WSSE digest auth"
665
- end
666
-
667
- context "disabled" do
668
- let(:response) { client.call(:authenticate) { |locals| locals.wsse_auth(false)} }
669
- include_examples "no WSSE auth"
670
- end
671
-
672
- context "set to nil" do
673
- let(:response) { client.call(:authenticate) { |locals| locals.wsse_auth(nil)} }
674
- include_examples "no WSSE auth"
675
- end
676
- end
677
- end
678
- end
679
- end
680
-
681
- context ":wsse_timestamp" do
682
- let(:request) { response.http.body }
683
-
684
- shared_examples "WSSE timestamp" do
685
- it "adds WSSE timestamp auth information to the request" do
686
- # the header and wsse security node
687
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
688
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
689
-
690
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
691
- expect(request).to include("<wsu:Timestamp")
692
- expect(request).to include("wsu:Id=\"Timestamp-1\"")
693
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
694
-
695
- # the created node with a timestamp
696
- expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
697
-
698
- # the expires node with a timestamp
699
- expect(request).to match(/<wsu:Expires>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Expires>/)
700
- end
701
- end
702
-
703
- shared_examples "no WSSE timestamp" do
704
- it "does not add WSSE timestamp to the request" do
705
- expect(request).not_to include("<wsu:Timestamp")
706
- end
707
- end
708
-
709
- describe "global" do
710
- context "enabled" do
711
- context "through block without arguments" do
712
- let(:client) do
713
- new_client(:endpoint => @server.url(:repeat)) do |globals|
714
- globals.wsse_timestamp
715
- end
716
- end
717
- let(:response) { client.call(:authenticate) }
718
- include_examples "WSSE timestamp"
719
- end
720
-
721
- context "through initializer options" do
722
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true) }
723
- let(:response) { client.call(:authenticate) }
724
- include_examples "WSSE timestamp"
725
- end
726
-
727
- context "with local override" do
728
- let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true) }
729
- context "enabled" do
730
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp} }
731
- include_examples "WSSE timestamp"
732
- end
733
- context "disabled" do
734
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(false) } }
735
- include_examples "no WSSE timestamp"
736
- end
737
- context "set to nil" do
738
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(nil) } }
739
- include_examples "WSSE timestamp"
740
- end
741
- end
742
- end
743
-
744
- context "not enabled" do
745
- let(:client) { new_client(:endpoint => @server.url(:repeat)) }
746
- describe "local" do
747
- context "enabled" do
748
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp} }
749
- include_examples "WSSE timestamp"
750
- end
751
- context "disabled" do
752
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(false) } }
753
- include_examples "no WSSE timestamp"
754
- end
755
- context "set to nil" do
756
- let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(nil) } }
757
- include_examples "no WSSE timestamp"
758
- end
759
- end
760
- end
761
- end
762
- end
763
-
764
- context "global :strip_namespaces" do
765
- it "can be changed to not strip any namespaces" do
766
- client = new_client(
767
- :endpoint => @server.url(:repeat),
768
- :convert_response_tags_to => lambda { |tag| tag.snakecase },
769
- :strip_namespaces => false
770
- )
771
-
772
- response = client.call(:authenticate, :xml => Fixture.response(:authentication))
773
-
774
- expect(response.hash["soap:envelope"]["soap:body"]).to include("ns2:authenticate_response")
775
- end
776
- end
777
-
778
- context "global :convert_request_keys_to" do
779
- it "changes how Hash message key Symbols are translated to XML tags for the request" do
780
- client = new_client_without_wsdl do |globals|
781
- globals.endpoint @server.url(:repeat)
782
- globals.namespace "http://v1.example.com"
783
- globals.convert_request_keys_to :camelcase # or one of [:lower_camelcase, :upcase, :none]
784
- end
785
-
786
- response = client.call(:find_user) do |locals|
787
- locals.message(:user_name => "luke", "pass_word" => "secret")
788
- end
789
-
790
- request = response.http.body
791
-
792
- # split into multiple assertions thanks to 1.8
793
- expect(request).to include("<wsdl:FindUser>")
794
- expect(request).to include("<UserName>luke</UserName>")
795
- expect(request).to include("<pass_word>secret</pass_word>")
796
- end
797
- end
798
-
799
- context "global :convert_response_tags_to" do
800
- it "changes how XML tags from the SOAP response are translated into Hash keys" do
801
- client = new_client(:endpoint => @server.url(:repeat), :convert_response_tags_to => lambda { |tag| tag.snakecase.upcase })
802
- response = client.call(:authenticate, :xml => Fixture.response(:authentication))
803
-
804
- expect(response.hash["ENVELOPE"]["BODY"]).to include("AUTHENTICATE_RESPONSE")
805
- end
806
-
807
- it "accepts a block in the block-based interface" do
808
- client = Savon.client do |globals|
809
- globals.log false
810
- globals.wsdl Fixture.wsdl(:authentication)
811
- globals.endpoint @server.url(:repeat)
812
- globals.convert_response_tags_to { |tag| tag.snakecase.upcase }
813
- end
814
-
815
- response = client.call(:authenticate) do |locals|
816
- locals.xml Fixture.response(:authentication)
817
- end
818
-
819
- expect(response.hash["ENVELOPE"]["BODY"]).to include("AUTHENTICATE_RESPONSE")
820
- end
821
- end
822
-
823
- context "global :convert_attributes_to" do
824
- it "changes how XML tag attributes from the SOAP response are translated into Hash keys" do
825
- client = new_client(:endpoint => @server.url(:repeat), :convert_attributes_to => lambda {|k,v| [k,v]})
826
- response = client.call(:authenticate, :xml => Fixture.response(:f5))
827
- expect(response.body[:get_agent_listen_address_response][:return][:item].first[:ipport][:address]).to eq({:"@s:type"=>"y:string"})
828
- end
829
-
830
- it "strips the attributes if an appropriate lambda is set" do
831
- client = new_client(:endpoint => @server.url(:repeat), :convert_attributes_to => lambda {|k,v| []})
832
- response = client.call(:authenticate, :xml => Fixture.response(:f5))
833
- expect(response.body[:get_agent_listen_address_response][:return][:item].first[:ipport][:address]).to eq(nil)
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_attributes_to {|k,v| [k,v]}
842
- end
843
-
844
- response = client.call(:authenticate) do |locals|
845
- locals.xml Fixture.response(:f5)
846
- end
847
-
848
- expect(response.body[:get_agent_listen_address_response][:return][:item].first[:ipport][:address]).to eq({:"@s:type"=>"y:string"})
849
- end
850
- end
851
-
852
- context 'global: :adapter' do
853
- it 'passes option to Wasabi initializer for WSDL fetching' do
854
- ## I want to use there something similar to the next mock expectation, but I can't
855
- ## as due to how Savon sets up Wasabi::Document and Wasabi::Document initialize itself
856
- ## adapter= method is called first time with nil and second time with adapter. [Envek, 2014-05-03]
857
- # Wasabi::Document.any_instance.expects(:adapter=).with(:fake_adapter_for_test)
858
- client = Savon.client(
859
- :log => false,
860
- :wsdl => @server.url(:authentication),
861
- :adapter => :fake_adapter_for_test,
862
- )
863
- operations = client.operations
864
- expect(operations).to eq([:authenticate])
865
- expect(FakeAdapterForTest.class_variable_get(:@@requests).size).to eq(1)
866
- expect(FakeAdapterForTest.class_variable_get(:@@requests).first.url).to eq(URI.parse(@server.url(:authentication)))
867
- expect(FakeAdapterForTest.class_variable_get(:@@methods)).to eq([:get])
868
- end
869
-
870
- it 'instructs HTTPI to use provided adapter for performing SOAP requests' do
871
- client = new_client_without_wsdl(
872
- :endpoint => @server.url(:repeat),
873
- :namespace => "http://v1.example.com",
874
- :adapter => :adapter_for_test,
875
- )
876
- response = client.call(:authenticate)
877
- expect(response.http.body).to include('xmlns:wsdl="http://v1.example.com"')
878
- expect(response.http.body).to include('<wsdl:authenticate>')
879
- expect(AdapterForTest.class_variable_get(:@@requests).size).to eq(1)
880
- expect(AdapterForTest.class_variable_get(:@@requests).first.url).to eq(URI.parse(@server.url(:repeat)))
881
- expect(AdapterForTest.class_variable_get(:@@methods)).to eq([:post])
882
- end
883
- end
884
-
885
- context "global and request :soap_header" do
886
- it "merges the headers if both were provided as Hashes" do
887
- global_soap_header = {
888
- :global_header => { :auth_token => "secret" },
889
- :merged => { :global => true }
890
- }
891
-
892
- request_soap_header = {
893
- :request_header => { :auth_token => "secret" },
894
- :merged => { :request => true }
895
- }
896
-
897
- client = new_client(:endpoint => @server.url(:repeat), :soap_header => global_soap_header)
898
-
899
- response = client.call(:authenticate, :soap_header => request_soap_header)
900
- request_body = response.http.body
901
-
902
- expect(request_body).to include("<globalHeader><authToken>secret</authToken></globalHeader>")
903
- expect(request_body).to include("<requestHeader><authToken>secret</authToken></requestHeader>")
904
- expect(request_body).to include("<merged><request>true</request></merged>")
905
- end
906
-
907
- it "prefers the request over the global option if at least one of them is not a Hash" do
908
- global_soap_header = "<global>header</global>"
909
- request_soap_header = "<request>header</request>"
910
-
911
- client = new_client(:endpoint => @server.url(:repeat), :soap_header => global_soap_header)
912
-
913
- response = client.call(:authenticate, :soap_header => request_soap_header)
914
- request_body = response.http.body
915
-
916
- expect(request_body).to include("<env:Header><request>header</request></env:Header>")
917
- end
918
- end
919
-
920
- context "request :soap_header" do
921
- it "accepts a Hash of SOAP header information" do
922
- client = new_client(:endpoint => @server.url(:repeat))
923
-
924
- response = client.call(:authenticate, :soap_header => { :auth_token => "secret" })
925
- expect(response.http.body).to include("<env:Header><authToken>secret</authToken></env:Header>")
926
- end
927
-
928
- it "accepts anything other than a String and calls #to_s on it" do
929
- to_s_header = Class.new {
930
- def to_s
931
- "to_s_header"
932
- end
933
- }.new
934
-
935
- client = new_client(:endpoint => @server.url(:repeat))
936
-
937
- response = client.call(:authenticate, :soap_header => to_s_header)
938
- expect(response.http.body).to include("<env:Header>to_s_header</env:Header>")
939
- end
940
- end
941
-
942
- context "request: message_tag" do
943
- it "when set, changes the SOAP message tag" do
944
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :message_tag => :doAuthenticate)
945
- expect(response.http.body).to include("<tns:doAuthenticate></tns:doAuthenticate>")
946
- end
947
-
948
- it "without it, Savon tries to get the message tag from the WSDL document" do
949
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate)
950
- expect(response.http.body).to include("<tns:authenticate></tns:authenticate>")
951
- end
952
-
953
- it "without the option and a WSDL, Savon defaults to Gyoku to create the name" do
954
- client = Savon.client(:endpoint => @server.url(:repeat), :namespace => "http://v1.example.com", :log => false)
955
-
956
- response = client.call(:init_authentication)
957
- expect(response.http.body).to include("<wsdl:initAuthentication></wsdl:initAuthentication>")
958
- end
959
- end
960
-
961
- context "request: attributes" do
962
- it "when set, adds the attributes to the message tag" do
963
- client = new_client(:endpoint => @server.url(:repeat))
964
- response = client.call(:authenticate, :attributes => { "Token" => "secret"})
965
-
966
- expect(response.http.body).to include('<tns:authenticate Token="secret">')
967
- end
968
- end
969
-
970
- context "request: soap_action" do
971
- it "without it, Savon tries to get the SOAPAction from the WSDL document and falls back to Gyoku" do
972
- client = new_client(:endpoint => @server.url(:inspect_request))
973
-
974
- response = client.call(:authenticate)
975
- soap_action = inspect_request(response).soap_action
976
- expect(soap_action).to eq('"authenticate"')
977
- end
978
-
979
- it "when set, changes the SOAPAction HTTP header" do
980
- client = new_client(:endpoint => @server.url(:inspect_request))
981
-
982
- response = client.call(:authenticate, :soap_action => "doAuthenticate")
983
- soap_action = inspect_request(response).soap_action
984
- expect(soap_action).to eq('"doAuthenticate"')
985
- end
986
- end
987
-
988
- context "request :message" do
989
- it "accepts a Hash which is passed to Gyoku to be converted to XML" do
990
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :message => { :user => "luke", :password => "secret" })
991
-
992
- request = response.http.body
993
- expect(request).to include("<user>luke</user>")
994
- expect(request).to include("<password>secret</password>")
995
- end
996
-
997
- it "also accepts a String of raw XML" do
998
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :message => "<user>lea</user><password>top-secret</password>")
999
- expect(response.http.body).to include("<tns:authenticate><user>lea</user><password>top-secret</password></tns:authenticate>")
1000
- end
1001
- end
1002
-
1003
- context "request :xml" do
1004
- it "accepts a String of raw XML" do
1005
- response = new_client(:endpoint => @server.url(:repeat)).call(:authenticate, :xml => "<soap>request</soap>")
1006
- expect(response.http.body).to eq("<soap>request</soap>")
1007
- end
1008
- end
1009
-
1010
- context "request :cookies" do
1011
- it "accepts an Array of HTTPI::Cookie objects for the next request" do
1012
- cookies = [
1013
- HTTPI::Cookie.new("some-cookie=choc-chip"),
1014
- HTTPI::Cookie.new("another-cookie=ny-cheesecake")
1015
- ]
1016
-
1017
- client = new_client(:endpoint => @server.url(:inspect_request))
1018
- response = client.call(:authenticate, :cookies => cookies)
1019
-
1020
- cookie = inspect_request(response).cookie
1021
- expect(cookie.split(";")).to include(
1022
- "some-cookie=choc-chip",
1023
- "another-cookie=ny-cheesecake"
1024
- )
1025
- end
1026
- end
1027
-
1028
- context "request :advanced_typecasting" do
1029
- it "can be changed to false to disable Nori's advanced typecasting" do
1030
- client = new_client(:endpoint => @server.url(:repeat))
1031
- response = client.call(:authenticate, :xml => Fixture.response(:authentication), :advanced_typecasting => false)
1032
-
1033
- expect(response.body[:authenticate_response][:return][:success]).to eq("true")
1034
- end
1035
- end
1036
-
1037
- context "request :response_parser" do
1038
- it "instructs Nori to change the response parser" do
1039
- nori = Nori.new(:strip_namespaces => true, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
1040
- Nori.expects(:new).with { |options| options[:parser] == :nokogiri }.returns(nori)
1041
-
1042
- client = new_client(:endpoint => @server.url(:repeat))
1043
- response = client.call(:authenticate, :xml => Fixture.response(:authentication), :response_parser => :nokogiri)
1044
-
1045
- expect(response.body).to_not be_empty
1046
- end
1047
- end
1048
-
1049
- context "request :headers" do
1050
- it "sets headers" do
1051
- client = new_client(:endpoint => @server.url(:inspect_request))
1052
-
1053
- response = client.call(:authenticate, :headers => { "X-Token" => "secret" })
1054
- x_token = inspect_request(response).x_token
1055
-
1056
- expect(x_token).to eq("secret")
1057
- end
1058
- end
1059
-
1060
- def new_client(globals = {}, &block)
1061
- globals = { :wsdl => Fixture.wsdl(:authentication), :log => false }.merge(globals)
1062
- Savon.client(globals, &block)
1063
- end
1064
-
1065
- def new_client_without_wsdl(globals = {}, &block)
1066
- globals = { :log => false }.merge(globals)
1067
- Savon.client(globals, &block)
1068
- end
1069
-
1070
- def inspect_request(response)
1071
- hash = JSON.parse(response.http.body)
1072
- OpenStruct.new(hash)
1073
- end
1074
-
1075
- end