savon 2.12.1 → 2.15.1

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