savon 2.13.1 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -1
  3. data/lib/savon/builder.rb +4 -3
  4. data/lib/savon/model.rb +3 -3
  5. data/lib/savon/options.rb +1 -1
  6. data/lib/savon/response.rb +3 -3
  7. data/lib/savon/string_utils.rb +17 -0
  8. data/lib/savon/version.rb +1 -1
  9. data/lib/savon.rb +1 -0
  10. metadata +17 -76
  11. data/.gitignore +0 -16
  12. data/.yardopts +0 -6
  13. data/CONTRIBUTING.md +0 -42
  14. data/Gemfile +0 -8
  15. data/RELEASING.md +0 -10
  16. data/lib/savon/core_ext/string.rb +0 -30
  17. data/savon.gemspec +0 -47
  18. data/spec/fixtures/gzip/message.gz +0 -0
  19. data/spec/fixtures/response/another_soap_fault.xml +0 -14
  20. data/spec/fixtures/response/authentication.xml +0 -14
  21. data/spec/fixtures/response/empty_soap_fault.xml +0 -13
  22. data/spec/fixtures/response/f5.xml +0 -39
  23. data/spec/fixtures/response/header.xml +0 -13
  24. data/spec/fixtures/response/list.xml +0 -18
  25. data/spec/fixtures/response/multi_ref.xml +0 -39
  26. data/spec/fixtures/response/no_body.xml +0 -1
  27. data/spec/fixtures/response/soap_fault.xml +0 -8
  28. data/spec/fixtures/response/soap_fault12.xml +0 -18
  29. data/spec/fixtures/response/soap_fault_funky.xml +0 -8
  30. data/spec/fixtures/response/taxcloud.xml +0 -1
  31. data/spec/fixtures/ssl/client_cert.pem +0 -16
  32. data/spec/fixtures/ssl/client_encrypted_key.pem +0 -30
  33. data/spec/fixtures/ssl/client_encrypted_key_cert.pem +0 -24
  34. data/spec/fixtures/ssl/client_key.pem +0 -15
  35. data/spec/fixtures/wsdl/authentication.xml +0 -63
  36. data/spec/fixtures/wsdl/betfair.xml +0 -2981
  37. data/spec/fixtures/wsdl/brand.xml +0 -624
  38. data/spec/fixtures/wsdl/edialog.xml +0 -15416
  39. data/spec/fixtures/wsdl/elements_in_types.xml +0 -43
  40. data/spec/fixtures/wsdl/interhome.xml +0 -2137
  41. data/spec/fixtures/wsdl/lower_camel.xml +0 -52
  42. data/spec/fixtures/wsdl/multiple_namespaces.xml +0 -92
  43. data/spec/fixtures/wsdl/multiple_types.xml +0 -60
  44. data/spec/fixtures/wsdl/no_message_tag.xml +0 -1267
  45. data/spec/fixtures/wsdl/taxcloud.xml +0 -934
  46. data/spec/fixtures/wsdl/team_software.xml +0 -1
  47. data/spec/fixtures/wsdl/vies.xml +0 -176
  48. data/spec/fixtures/wsdl/wasmuth.xml +0 -153
  49. data/spec/integration/support/application.rb +0 -114
  50. data/spec/integration/support/server.rb +0 -85
  51. data/spec/integration/zipcode_example_spec.rb +0 -39
  52. data/spec/savon/builder_spec.rb +0 -138
  53. data/spec/savon/client_spec.rb +0 -272
  54. data/spec/savon/core_ext/string_spec.rb +0 -38
  55. data/spec/savon/features/message_tag_spec.rb +0 -62
  56. data/spec/savon/http_error_spec.rb +0 -57
  57. data/spec/savon/log_message_spec.rb +0 -51
  58. data/spec/savon/message_spec.rb +0 -61
  59. data/spec/savon/mock_spec.rb +0 -175
  60. data/spec/savon/model_spec.rb +0 -183
  61. data/spec/savon/multipart_request_spec.rb +0 -46
  62. data/spec/savon/observers_spec.rb +0 -93
  63. data/spec/savon/operation_spec.rb +0 -207
  64. data/spec/savon/options_spec.rb +0 -1154
  65. data/spec/savon/qualified_message_spec.rb +0 -102
  66. data/spec/savon/request_logger_spec.rb +0 -38
  67. data/spec/savon/request_spec.rb +0 -581
  68. data/spec/savon/response_spec.rb +0 -276
  69. data/spec/savon/soap_fault_spec.rb +0 -147
  70. data/spec/savon/softlayer_spec.rb +0 -42
  71. data/spec/spec_helper.rb +0 -31
  72. data/spec/support/adapters.rb +0 -49
  73. data/spec/support/endpoint.rb +0 -26
  74. data/spec/support/fixture.rb +0 -40
  75. data/spec/support/integration.rb +0 -10
  76. data/spec/support/stdout.rb +0 -26
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
- require "integration/support/server"
4
-
5
- RSpec.describe Savon::Message do
6
-
7
- before do
8
- @server = IntegrationServer.run
9
- end
10
-
11
- after do
12
- @server.stop
13
- end
14
-
15
- let(:client_config) {
16
- {
17
- :endpoint => @server.url(:repeat),
18
- :namespace => 'http://example.com',
19
- :log => false,
20
-
21
- :element_form_default => :qualified,
22
- :convert_request_keys_to => :camelcase,
23
-
24
- :convert_response_tags_to => nil
25
- }
26
- }
27
-
28
- let(:client) { Savon.client(client_config) }
29
-
30
- context "with a qualified message" do
31
- let(:message) {
32
- {
33
- :email_count => 3,
34
- :user_name => 'josh',
35
- :order! => [:user_name, :email_count]
36
- }
37
- }
38
-
39
- let(:converted_keys) {
40
- '<wsdl:UserName>josh</wsdl:UserName><wsdl:EmailCount>3</wsdl:EmailCount>'
41
- }
42
- it "converts request Hash keys for which there is not namespace" do
43
- response = client.call(:something, :message => message)
44
- expect(response.xml).to include(converted_keys)
45
- end
46
- end
47
-
48
- context 'use_wsa_headers' do
49
- let(:client_config) { super().merge(use_wsa_headers: true) }
50
-
51
- context 'headers' do
52
- [ 'wsa:Action', 'wsa:To', 'wsa:MessageID' ].each do |header|
53
- it "should include #{header} header" do
54
- response = client.call(:something, message: {})
55
- expect(response.xml).to include(header)
56
- end
57
- end
58
- end
59
- end
60
-
61
- end
@@ -1,175 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
- require "savon/mock/spec_helper"
4
-
5
- RSpec.describe "Savon's mock interface" do
6
- include Savon::SpecHelper
7
-
8
- before :all do
9
- savon.mock!
10
- end
11
-
12
- after :all do
13
- savon.unmock!
14
- end
15
-
16
- it "can verify a request and return a fixture response" do
17
- message = { :username => "luke", :password => "secret" }
18
- savon.expects(:authenticate).with(:message => message).returns("<fixture/>")
19
-
20
- response = new_client.call(:authenticate) do
21
- message(:username => "luke", :password => "secret")
22
- end
23
-
24
- expect(response.http.body).to eq("<fixture/>")
25
- end
26
-
27
- it "can verify a request with any parameters and return a fixture response" do
28
- message = { :username => "luke", :password => :any }
29
- savon.expects(:authenticate).with(:message => message).returns("<fixture/>")
30
-
31
- response = new_client.call(:authenticate) do
32
- message(:username => "luke", :password => "secret")
33
- end
34
-
35
- expect(response.http.body).to eq("<fixture/>")
36
- end
37
-
38
- it "accepts a Hash to specify the response code, headers and body" do
39
- soap_fault = Fixture.response(:soap_fault)
40
- response = { :code => 500, :headers => { "X-Result" => "invalid" }, :body => soap_fault }
41
-
42
- savon.expects(:authenticate).returns(response)
43
- response = new_client(:raise_errors => false).call(:authenticate)
44
-
45
- expect(response).to_not be_successful
46
- expect(response).to be_a_soap_fault
47
-
48
- expect(response.http.code).to eq(500)
49
- expect(response.http.headers).to eq("X-Result" => "invalid")
50
- expect(response.http.body).to eq(soap_fault)
51
- end
52
-
53
- it "works with multiple requests" do
54
- authentication_message = { :username => "luke", :password => "secret" }
55
- savon.expects(:authenticate).with(:message => authentication_message).returns("")
56
-
57
- find_user_message = { :by_username => "lea" }
58
- savon.expects(:find_user).with(:message => find_user_message).returns("")
59
-
60
- new_client.call(:authenticate, :message => authentication_message)
61
- new_client.call(:find_user, :message => find_user_message)
62
- end
63
-
64
- it "fails when the expected operation was not called" do
65
- # TODO: find out how to test this! [dh, 2012-12-17]
66
- #savon.expects(:authenticate)
67
- end
68
-
69
- it "fails when the return value for an expectation was not specified" do
70
- savon.expects(:authenticate)
71
-
72
- expect { new_client.call(:authenticate) }.
73
- to raise_error(Savon::ExpectationError, "This expectation was not set up with a response.")
74
- end
75
-
76
- it "fails with an unexpected request" do
77
- expect { new_client.call(:authenticate) }.
78
- to raise_error(Savon::ExpectationError, "Unexpected request to the :authenticate operation.")
79
- end
80
-
81
- it "fails with multiple requests" do
82
- authentication_message = { :username => "luke", :password => "secret" }
83
- savon.expects(:authenticate).with(:message => authentication_message).returns("")
84
-
85
- create_user_message = { :username => "lea" }
86
- savon.expects(:create_user).with(:message => create_user_message).returns("")
87
-
88
- find_user_message = { :by_username => "lea" }
89
- savon.expects(:find_user).with(:message => find_user_message).returns("")
90
-
91
- # reversed order from previous spec
92
- new_client.call(:authenticate, :message => authentication_message)
93
-
94
- expect { new_client.call(:find_user, :message => find_user_message) }.
95
- to raise_error(Savon::ExpectationError, "Expected a request to the :create_user operation.\n" \
96
- "Received a request to the :find_user operation instead.")
97
- end
98
-
99
- it "fails when the expected SOAP operation does not match the actual one" do
100
- savon.expects(:logout).returns("<fixture/>")
101
-
102
- expect { new_client.call(:authenticate) }.
103
- to raise_error(Savon::ExpectationError, "Expected a request to the :logout operation.\n" \
104
- "Received a request to the :authenticate operation instead.")
105
- end
106
-
107
- it "fails when there is no actual message to match" do
108
- message = { :username => "luke" }
109
- savon.expects(:find_user).with(:message => message).returns("<fixture/>")
110
-
111
- expect { new_client.call(:find_user) }.
112
- to raise_error(Savon::ExpectationError, "Expected a request to the :find_user operation\n" \
113
- " with this message: #{message.inspect}\n" \
114
- "Received a request to the :find_user operation\n" \
115
- " with no message.")
116
- end
117
-
118
- it "fails when there is no expect but an actual message" do
119
- savon.expects(:find_user).returns("<fixture/>")
120
- message = { :username => "luke" }
121
-
122
- expect { new_client.call(:find_user, :message => message) }.
123
- to raise_error(Savon::ExpectationError, "Expected a request to the :find_user operation\n" \
124
- " with no message.\n" \
125
- "Received a request to the :find_user operation\n" \
126
- " with this message: #{message.inspect}")
127
- end
128
-
129
- it "does not fail when any message is expected and an actual message" do
130
- savon.expects(:find_user).with(:message => :any).returns("<fixture/>")
131
- message = { :username => "luke" }
132
-
133
- expect { new_client.call(:find_user, :message => message) }.to_not raise_error
134
- end
135
-
136
- it "does not fail when any message is expected and no actual message" do
137
- savon.expects(:find_user).with(:message => :any).returns("<fixture/>")
138
-
139
- expect { new_client.call(:find_user) }.to_not raise_error
140
- end
141
-
142
- it "matchers can be used to specify the message" do
143
- savon.expects(:find_user).with(:message => include(:username)).returns("<fixture/>")
144
- message = { :username => "Han Solo", password: "querty"}
145
-
146
- expect { new_client.call(:find_user, :message => message) }.to_not raise_error
147
- end
148
-
149
- it "allows code to rescue Savon::Error and still report test failures" do
150
- message = { :username => "luke" }
151
- savon.expects(:find_user).with(:message => message).returns("<fixture/>")
152
-
153
- expect {
154
- begin
155
- new_client.call(:find_user)
156
- rescue Savon::Error => e
157
- puts "any real error (e.g. SOAP fault or HTTP error) is OK in the big picture, move on"
158
- end
159
- }.to raise_error(Savon::ExpectationError, "Expected a request to the :find_user operation\n" \
160
- " with this message: #{message.inspect}\n" \
161
- "Received a request to the :find_user operation\n" \
162
- " with no message.")
163
- end
164
-
165
- def new_client(globals = {})
166
- defaults = {
167
- :endpoint => "http://example.com",
168
- :namespace => "http://v1.example.com",
169
- :log => false
170
- }
171
-
172
- Savon.client defaults.merge(globals)
173
- end
174
-
175
- end
@@ -1,183 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
- require "integration/support/server"
4
-
5
- RSpec.describe Savon::Model do
6
-
7
- before :all do
8
- @server = IntegrationServer.run
9
- end
10
-
11
- after :all do
12
- @server.stop
13
- end
14
-
15
- describe ".client" do
16
- it "returns the memoized client" do
17
- model = Class.new {
18
- extend Savon::Model
19
- client :wsdl => Fixture.wsdl(:authentication)
20
- }
21
-
22
- expect(model.client).to be_a(Savon::Client)
23
- expect(model.client).to equal(model.client)
24
- end
25
-
26
- it "raises if the client was not initialized properly" do
27
- model = Class.new { extend Savon::Model }
28
-
29
- expect { model.client }.
30
- to raise_error(Savon::InitializationError, /^Expected the model to be initialized/)
31
- end
32
- end
33
-
34
- describe ".global" do
35
- it "sets global options" do
36
- model = Class.new {
37
- extend Savon::Model
38
-
39
- client :wsdl => Fixture.wsdl(:authentication)
40
-
41
- global :soap_version, 2
42
- global :open_timeout, 71
43
- global :wsse_auth, "luke", "secret", :digest
44
- }
45
-
46
- expect(model.client.globals[:soap_version]).to eq(2)
47
- expect(model.client.globals[:open_timeout]).to eq(71)
48
- expect(model.client.globals[:wsse_auth]).to eq(["luke", "secret", :digest])
49
- end
50
- end
51
-
52
- describe ".operations" do
53
- it "defines class methods for each operation" do
54
- model = Class.new {
55
- extend Savon::Model
56
-
57
- client :wsdl => Fixture.wsdl(:authentication)
58
- operations :authenticate
59
- }
60
-
61
- expect(model).to respond_to(:authenticate)
62
- end
63
-
64
- it "executes class-level SOAP operations" do
65
- repeat_url = @server.url(:repeat)
66
-
67
- model = Class.new {
68
- extend Savon::Model
69
-
70
- client :endpoint => repeat_url, :namespace => "http://v1.example.com"
71
- global :log, false
72
-
73
- operations :authenticate
74
- }
75
-
76
- response = model.authenticate(:xml => Fixture.response(:authentication))
77
- expect(response.body[:authenticate_response][:return]).to include(:authentication_value)
78
- end
79
-
80
- it "defines instance methods for each operation" do
81
- model = Class.new {
82
- extend Savon::Model
83
-
84
- client :wsdl => Fixture.wsdl(:authentication)
85
- operations :authenticate
86
- }
87
-
88
- model_instance = model.new
89
- expect(model_instance).to respond_to(:authenticate)
90
- end
91
-
92
- it "executes instance-level SOAP operations" do
93
- repeat_url = @server.url(:repeat)
94
-
95
- model = Class.new {
96
- extend Savon::Model
97
-
98
- client :endpoint => repeat_url, :namespace => "http://v1.example.com"
99
- global :log, false
100
-
101
- operations :authenticate
102
- }
103
-
104
- model_instance = model.new
105
- response = model_instance.authenticate(:xml => Fixture.response(:authentication))
106
- expect(response.body[:authenticate_response][:return]).to include(:authentication_value)
107
- end
108
- end
109
-
110
- it "allows to overwrite class operations" do
111
- repeat_url = @server.url(:repeat)
112
-
113
- model = Class.new {
114
- extend Savon::Model
115
- client :endpoint => repeat_url, :namespace => "http://v1.example.com"
116
- }
117
-
118
- supermodel = model.dup
119
- supermodel.operations :authenticate
120
-
121
- def supermodel.authenticate(locals = {})
122
- p "super"
123
- super
124
- end
125
-
126
- supermodel.client.expects(:call).with(:authenticate, :message => { :username => "luke", :password => "secret" })
127
- supermodel.expects(:p).with("super") # stupid, but works
128
-
129
- supermodel.authenticate(:message => { :username => "luke", :password => "secret" })
130
- end
131
-
132
- it "allows to overwrite instance operations" do
133
- repeat_url = @server.url(:repeat)
134
-
135
- model = Class.new {
136
- extend Savon::Model
137
- client :endpoint => repeat_url, :namespace => "http://v1.example.com"
138
- }
139
-
140
- supermodel = model.dup
141
- supermodel.operations :authenticate
142
- supermodel = supermodel.new
143
-
144
- def supermodel.authenticate(lcoals = {})
145
- p "super"
146
- super
147
- end
148
-
149
- supermodel.client.expects(:call).with(:authenticate, :message => { :username => "luke", :password => "secret" })
150
- supermodel.expects(:p).with("super") # stupid, but works
151
-
152
- supermodel.authenticate(:message => { :username => "luke", :password => "secret" })
153
- end
154
-
155
- describe ".all_operations" do
156
- it "should call operations with all available client operations" do
157
- model = Class.new {
158
- extend Savon::Model
159
-
160
- client :wsdl => Fixture.wsdl(:taxcloud)
161
- all_operations
162
- }
163
-
164
- [:verify_address,
165
- :lookup_for_date,
166
- :lookup,
167
- :authorized,
168
- :authorized_with_capture,
169
- :captured,
170
- :returned,
171
- :get_tic_groups,
172
- :get_ti_cs,
173
- :get_ti_cs_by_group,
174
- :add_exempt_certificate,
175
- :delete_exempt_certificate,
176
- :get_exempt_certificates].each do |method|
177
- expect(model).to respond_to(method)
178
- end
179
- end
180
-
181
- end
182
-
183
- end
@@ -1,46 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Savon::Builder do
4
-
5
- let(:globals) { Savon::GlobalOptions.new({ :endpoint => "http://example.co", :namespace => "http://v1.example.com" }) }
6
- let(:no_wsdl) { Wasabi::Document.new }
7
-
8
- it "building multipart request from inline content" do
9
- locals = {
10
- attachments: [
11
- { filename: 'x1.xml', content: '<xml>abc1</xml>'},
12
- { filename: 'x2.xml', content: '<xml>abc2</xml>'},
13
- ]
14
- }
15
- builder = Savon::Builder.new(:operation1, no_wsdl, globals, Savon::LocalOptions.new(locals))
16
- request_body = builder.to_s
17
-
18
- expect(request_body).to include('Content-Type')
19
- expect(request_body).to match(/<[a-z]+:operation1>/)
20
-
21
- locals[:attachments].each do |attachment|
22
- expect(request_body).to match(/^Content-Location: #{attachment[:filename]}\s$/)
23
- expect(request_body).to include(Base64.encode64(attachment[:content]).strip)
24
- end
25
-
26
- end
27
-
28
- it "building multipart request from file" do
29
- locals = {
30
- attachments: {
31
- 'file.gz' => File.expand_path("../../fixtures/gzip/message.gz", __FILE__)
32
- }
33
- }
34
- builder = Savon::Builder.new(:operation1, no_wsdl, globals, Savon::LocalOptions.new(locals))
35
- request_body = builder.to_s
36
-
37
- expect(request_body).to include('Content-Type')
38
- expect(request_body).to match(/<[a-z]+:operation1>/)
39
-
40
- locals[:attachments].each do |id, file|
41
- expect(request_body).to match(/^Content-Location: #{id}\s$/)
42
- expect(request_body.gsub("\r", "")).to include(Base64.encode64(File.read(file)).strip)
43
- end
44
-
45
- end
46
- end
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
- require "integration/support/server"
4
-
5
- RSpec.describe Savon do
6
-
7
- before :all do
8
- @server = IntegrationServer.run
9
- end
10
-
11
- after :all do
12
- @server.stop
13
- end
14
-
15
- describe ".observers" do
16
- after :each do
17
- Savon.observers.clear
18
- end
19
-
20
- it "allows to register an observer for every request" do
21
- observer = Class.new {
22
-
23
- def notify(operation_name, builder, globals, locals)
24
- @operation_name = operation_name
25
-
26
- @builder = builder
27
- @globals = globals
28
- @locals = locals
29
-
30
- # return nil to execute the request
31
- nil
32
- end
33
-
34
- attr_reader :operation_name, :builder, :globals, :locals
35
-
36
- }.new
37
-
38
- Savon.observers << observer
39
-
40
- new_client.call(:authenticate)
41
-
42
- expect(observer.operation_name).to eq(:authenticate)
43
-
44
- expect(observer.builder).to be_a(Savon::Builder)
45
- expect(observer.globals).to be_a(Savon::GlobalOptions)
46
- expect(observer.locals).to be_a(Savon::LocalOptions)
47
- end
48
-
49
- it "allows to register an observer which mocks requests" do
50
- observer = Class.new {
51
-
52
- def notify(*)
53
- # return a response to mock the request
54
- HTTPI::Response.new(201, { "X-Result" => "valid" }, "valid!")
55
- end
56
-
57
- }.new
58
-
59
- Savon.observers << observer
60
-
61
- response = new_client.call(:authenticate)
62
-
63
- expect(response.http.code).to eq(201)
64
- expect(response.http.headers).to eq("X-Result" => "valid")
65
- expect(response.http.body).to eq("valid!")
66
- end
67
-
68
- it "raises if an observer returns something other than nil or an HTTPI::Response" do
69
- observer = Class.new {
70
-
71
- def notify(*)
72
- []
73
- end
74
-
75
- }.new
76
-
77
- Savon.observers << observer
78
-
79
- expect { new_client.call(:authenticate) }.
80
- to raise_error(Savon::Error, "Observers need to return an HTTPI::Response " \
81
- "to mock the request or nil to execute the request.")
82
- end
83
- end
84
-
85
- def new_client
86
- Savon.client(
87
- :endpoint => @server.url(:repeat),
88
- :namespace => "http://v1.example.com",
89
- :log => false
90
- )
91
- end
92
-
93
- end