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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/lib/savon/builder.rb +4 -3
- data/lib/savon/model.rb +3 -3
- data/lib/savon/options.rb +1 -1
- data/lib/savon/response.rb +3 -3
- data/lib/savon/string_utils.rb +17 -0
- data/lib/savon/version.rb +1 -1
- data/lib/savon.rb +1 -0
- metadata +17 -76
- data/.gitignore +0 -16
- data/.yardopts +0 -6
- data/CONTRIBUTING.md +0 -42
- data/Gemfile +0 -8
- data/RELEASING.md +0 -10
- data/lib/savon/core_ext/string.rb +0 -30
- data/savon.gemspec +0 -47
- data/spec/fixtures/gzip/message.gz +0 -0
- data/spec/fixtures/response/another_soap_fault.xml +0 -14
- data/spec/fixtures/response/authentication.xml +0 -14
- data/spec/fixtures/response/empty_soap_fault.xml +0 -13
- data/spec/fixtures/response/f5.xml +0 -39
- data/spec/fixtures/response/header.xml +0 -13
- data/spec/fixtures/response/list.xml +0 -18
- data/spec/fixtures/response/multi_ref.xml +0 -39
- data/spec/fixtures/response/no_body.xml +0 -1
- data/spec/fixtures/response/soap_fault.xml +0 -8
- data/spec/fixtures/response/soap_fault12.xml +0 -18
- data/spec/fixtures/response/soap_fault_funky.xml +0 -8
- data/spec/fixtures/response/taxcloud.xml +0 -1
- data/spec/fixtures/ssl/client_cert.pem +0 -16
- data/spec/fixtures/ssl/client_encrypted_key.pem +0 -30
- data/spec/fixtures/ssl/client_encrypted_key_cert.pem +0 -24
- data/spec/fixtures/ssl/client_key.pem +0 -15
- data/spec/fixtures/wsdl/authentication.xml +0 -63
- data/spec/fixtures/wsdl/betfair.xml +0 -2981
- data/spec/fixtures/wsdl/brand.xml +0 -624
- data/spec/fixtures/wsdl/edialog.xml +0 -15416
- data/spec/fixtures/wsdl/elements_in_types.xml +0 -43
- data/spec/fixtures/wsdl/interhome.xml +0 -2137
- data/spec/fixtures/wsdl/lower_camel.xml +0 -52
- data/spec/fixtures/wsdl/multiple_namespaces.xml +0 -92
- data/spec/fixtures/wsdl/multiple_types.xml +0 -60
- data/spec/fixtures/wsdl/no_message_tag.xml +0 -1267
- data/spec/fixtures/wsdl/taxcloud.xml +0 -934
- data/spec/fixtures/wsdl/team_software.xml +0 -1
- data/spec/fixtures/wsdl/vies.xml +0 -176
- data/spec/fixtures/wsdl/wasmuth.xml +0 -153
- data/spec/integration/support/application.rb +0 -114
- data/spec/integration/support/server.rb +0 -85
- data/spec/integration/zipcode_example_spec.rb +0 -39
- data/spec/savon/builder_spec.rb +0 -138
- data/spec/savon/client_spec.rb +0 -272
- data/spec/savon/core_ext/string_spec.rb +0 -38
- data/spec/savon/features/message_tag_spec.rb +0 -62
- data/spec/savon/http_error_spec.rb +0 -57
- data/spec/savon/log_message_spec.rb +0 -51
- data/spec/savon/message_spec.rb +0 -61
- data/spec/savon/mock_spec.rb +0 -175
- data/spec/savon/model_spec.rb +0 -183
- data/spec/savon/multipart_request_spec.rb +0 -46
- data/spec/savon/observers_spec.rb +0 -93
- data/spec/savon/operation_spec.rb +0 -207
- data/spec/savon/options_spec.rb +0 -1154
- data/spec/savon/qualified_message_spec.rb +0 -102
- data/spec/savon/request_logger_spec.rb +0 -38
- data/spec/savon/request_spec.rb +0 -581
- data/spec/savon/response_spec.rb +0 -276
- data/spec/savon/soap_fault_spec.rb +0 -147
- data/spec/savon/softlayer_spec.rb +0 -42
- data/spec/spec_helper.rb +0 -31
- data/spec/support/adapters.rb +0 -49
- data/spec/support/endpoint.rb +0 -26
- data/spec/support/fixture.rb +0 -40
- data/spec/support/integration.rb +0 -10
- data/spec/support/stdout.rb +0 -26
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
RSpec.describe "ZIP code example" do
|
5
|
-
it "supports threads making requests simultaneously" do
|
6
|
-
client = Savon.client(
|
7
|
-
:wsdl => "http://www.thomas-bayer.com/axis2/services/BLZService?wsdl",
|
8
|
-
|
9
|
-
# Lower timeouts so these specs don't take forever when the service is not available.
|
10
|
-
:open_timeout => 10,
|
11
|
-
:read_timeout => 10,
|
12
|
-
|
13
|
-
:log => false # Disable logging for cleaner spec output.
|
14
|
-
)
|
15
|
-
|
16
|
-
mutex = Mutex.new
|
17
|
-
|
18
|
-
request_data = [70070010, 24050110, 20050550]
|
19
|
-
threads_waiting = request_data.size
|
20
|
-
|
21
|
-
threads = request_data.map do |blz|
|
22
|
-
thread = Thread.new do
|
23
|
-
response = call_and_fail_gracefully(client, :get_bank, :message => { :blz => blz })
|
24
|
-
Thread.current[:value] = response.body[:get_bank_response][:details]
|
25
|
-
mutex.synchronize { threads_waiting -= 1 }
|
26
|
-
end
|
27
|
-
|
28
|
-
thread.abort_on_exception = true
|
29
|
-
thread
|
30
|
-
end
|
31
|
-
|
32
|
-
sleep(1) until threads_waiting == 0
|
33
|
-
|
34
|
-
threads.each(&:kill)
|
35
|
-
values = threads.map { |thr| thr[:value] }.compact
|
36
|
-
|
37
|
-
expect(values.uniq.size).to eq(values.size)
|
38
|
-
end
|
39
|
-
end
|
data/spec/savon/builder_spec.rb
DELETED
@@ -1,138 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
RSpec.describe Savon::Builder do
|
5
|
-
|
6
|
-
subject(:builder) { Savon::Builder.new(:authenticate, wsdl, globals, locals) }
|
7
|
-
|
8
|
-
let(:globals) { Savon::GlobalOptions.new }
|
9
|
-
let(:locals) { Savon::LocalOptions.new }
|
10
|
-
let(:wsdl) { Wasabi::Document.new Fixture.wsdl(:authentication) }
|
11
|
-
let(:no_wsdl) { Wasabi::Document.new }
|
12
|
-
|
13
|
-
describe "#pretty" do
|
14
|
-
it "returns the pretty printed request" do
|
15
|
-
expect(builder.pretty).to include("<env:Body>\n <tns:authenticate/>")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#to_s" do
|
20
|
-
it "includes the global :env_namespace if it's available" do
|
21
|
-
globals[:env_namespace] = :soapenv
|
22
|
-
expect(builder.to_s).to include("<soapenv:Envelope")
|
23
|
-
end
|
24
|
-
|
25
|
-
it "defaults to include the default envelope namespace of :env" do
|
26
|
-
expect(builder.to_s).to include("<env:Envelope")
|
27
|
-
end
|
28
|
-
|
29
|
-
it "includes the target namespace from the WSDL" do
|
30
|
-
expect(builder.to_s).to include('xmlns:tns="http://v1_0.ws.auth.order.example.com/"')
|
31
|
-
end
|
32
|
-
|
33
|
-
it "includes the target namespace from the global :namespace if it's available" do
|
34
|
-
globals[:namespace] = "http://v1.example.com"
|
35
|
-
expect(builder.to_s).to include('xmlns:tns="http://v1.example.com"')
|
36
|
-
end
|
37
|
-
|
38
|
-
it "includes the local :message_tag if available" do
|
39
|
-
locals[:message_tag] = "doAuthenticate"
|
40
|
-
expect(builder.to_s).to include("<tns:doAuthenticate>")
|
41
|
-
end
|
42
|
-
|
43
|
-
it "includes the message tag from the WSDL if its available" do
|
44
|
-
expect(builder.to_s).to include("<tns:authenticate>")
|
45
|
-
end
|
46
|
-
|
47
|
-
it "includes a message tag created by Gyoku if both option and WSDL are missing" do
|
48
|
-
globals[:namespace] = "http://v1.example.com"
|
49
|
-
|
50
|
-
locals = Savon::LocalOptions.new
|
51
|
-
builder = Savon::Builder.new(:authenticate, no_wsdl, globals, locals)
|
52
|
-
|
53
|
-
expect(builder.to_s).to include("<wsdl:authenticate>")
|
54
|
-
end
|
55
|
-
|
56
|
-
it "uses the global :namespace_identifier option if it's available" do
|
57
|
-
globals[:namespace_identifier] = :v1
|
58
|
-
expect(builder.to_s).to include("<v1:authenticate>")
|
59
|
-
end
|
60
|
-
|
61
|
-
it "uses the WSDL's namespace_identifier if the global option was not specified" do
|
62
|
-
expect(builder.to_s).to include("<tns:authenticate>")
|
63
|
-
end
|
64
|
-
|
65
|
-
it "uses the default :wsdl identifier if both option and WSDL were not specified" do
|
66
|
-
globals[:namespace] = "http://v1.example.com"
|
67
|
-
|
68
|
-
builder = Savon::Builder.new(:authenticate, no_wsdl, globals, locals)
|
69
|
-
expect(builder.to_s).to include("<wsdl:authenticate>")
|
70
|
-
end
|
71
|
-
|
72
|
-
it "uses the global :element_form_default option if it's available " do
|
73
|
-
globals[:element_form_default] = :qualified
|
74
|
-
locals[:message] = { :username => "luke", :password => "secret" }
|
75
|
-
|
76
|
-
expect(builder.to_s).to include("<tns:username>luke</tns:username>")
|
77
|
-
end
|
78
|
-
|
79
|
-
it "uses the WSDL's element_form_default value if the global option was set specified" do
|
80
|
-
locals[:message] = { :username => "luke", :password => "secret" }
|
81
|
-
wsdl.element_form_default = :qualified
|
82
|
-
|
83
|
-
expect(builder.to_s).to include("<tns:username>luke</tns:username>")
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "#wsse_signature" do
|
87
|
-
fixture_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'ssl')
|
88
|
-
|
89
|
-
let(:cert) { File.join(fixture_dir, 'client_cert.pem') }
|
90
|
-
let(:private_key) { File.join(fixture_dir, 'client_key.pem') }
|
91
|
-
let(:signature) do
|
92
|
-
Akami::WSSE::Signature.new(
|
93
|
-
Akami::WSSE::Certs.new(
|
94
|
-
:cert_file => cert,
|
95
|
-
:private_key_file => private_key
|
96
|
-
)
|
97
|
-
)
|
98
|
-
end
|
99
|
-
let(:globals) { Savon::GlobalOptions.new(wsse_signature: signature) }
|
100
|
-
|
101
|
-
subject(:signed_message_nn) {Nokogiri::XML(builder.to_s).remove_namespaces!}
|
102
|
-
subject(:signed_message) {Nokogiri::XML(builder.to_s)}
|
103
|
-
|
104
|
-
it "should contain a header" do
|
105
|
-
expect(signed_message_nn.xpath('/Envelope/Header').size).to eq(1)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should contain a wsse:Security" do
|
109
|
-
expect(signed_message_nn.xpath('/Envelope/Header/Security').size).to eq(1)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should have a Body[@wsu:Id]" do
|
113
|
-
#must investigate: acts funny in mri ruby
|
114
|
-
#expect(signed_message.xpath('//soapenv:Body', soapenv: "http://schemas.xmlsoap.org/soap/envelope/").attribute('ws:Id').value).to include('Body-')
|
115
|
-
expect(signed_message_nn.xpath('//Body').attr('Id').value).to include('Body-')
|
116
|
-
end
|
117
|
-
|
118
|
-
it "signature should be valid" do
|
119
|
-
certs = Akami::WSSE::Certs.new(:cert_file => cert, :private_key_file => private_key)
|
120
|
-
signature_value = signed_message_nn.xpath('//SignatureValue').text
|
121
|
-
signed_info_fragment = signed_message.xpath('//default:SignedInfo', default: "http://www.w3.org/2000/09/xmldsig#").to_xml
|
122
|
-
data = Nokogiri::XML(signed_info_fragment){|config| config.options = Nokogiri::XML::ParseOptions::NOBLANKS}
|
123
|
-
data.root.default_namespace='http://www.w3.org/2000/09/xmldsig#'
|
124
|
-
|
125
|
-
signed_info = data.canonicalize Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
|
126
|
-
|
127
|
-
signature = certs.private_key.sign(OpenSSL::Digest::SHA1.new, signed_info)
|
128
|
-
expect(Base64.encode64(signature).gsub("\n", '')).to eq(signature_value)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
describe '#body_attributes' do
|
134
|
-
it 'should not be nil' do
|
135
|
-
expect(builder.body_attributes).to eq({})
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
data/spec/savon/client_spec.rb
DELETED
@@ -1,272 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
require "integration/support/server"
|
4
|
-
|
5
|
-
RSpec.describe Savon::Client 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 ".new" do
|
16
|
-
it "supports a block without arguments to create a client with global options" do
|
17
|
-
client = Savon.client do
|
18
|
-
wsdl Fixture.wsdl(:authentication)
|
19
|
-
end
|
20
|
-
|
21
|
-
expect(client.globals[:wsdl]).to eq(Fixture.wsdl(:authentication))
|
22
|
-
end
|
23
|
-
|
24
|
-
it "supports a block with one argument to create a client with global options" do
|
25
|
-
client = Savon.client do |globals|
|
26
|
-
globals.wsdl Fixture.wsdl(:authentication)
|
27
|
-
end
|
28
|
-
|
29
|
-
expect(client.globals[:wsdl]).to eq(Fixture.wsdl(:authentication))
|
30
|
-
end
|
31
|
-
|
32
|
-
it "builds an HTTPI request for Wasabi" do
|
33
|
-
http_request = mock
|
34
|
-
wsdl_request = mock(:build => http_request)
|
35
|
-
Savon::WSDLRequest.expects(:new).with(instance_of(Savon::GlobalOptions)).returns(wsdl_request)
|
36
|
-
|
37
|
-
Wasabi::Document.any_instance.expects(:request=).with(http_request)
|
38
|
-
Savon.client(:wsdl => "http://example.com")
|
39
|
-
end
|
40
|
-
|
41
|
-
it "raises if initialized with anything other than a Hash" do
|
42
|
-
expect { Savon.client("http://example.com") }.
|
43
|
-
to raise_error(Savon::InitializationError, /Some code tries to initialize Savon with the "http:\/\/example\.com" \(String\)/)
|
44
|
-
end
|
45
|
-
|
46
|
-
it "raises if not initialized with either a :wsdl or both :endpoint and :namespace options" do
|
47
|
-
expect { Savon.client(:endpoint => "http://example.com") }.
|
48
|
-
to raise_error(Savon::InitializationError, /Expected either a WSDL document or the SOAP endpoint and target namespace options/)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "raises a when given an unknown option via the Hash syntax" do
|
52
|
-
expect { Savon.client(:invalid_global_option => true) }.
|
53
|
-
to raise_error(Savon::UnknownOptionError, "Unknown global option: :invalid_global_option")
|
54
|
-
end
|
55
|
-
|
56
|
-
it "raises a when given an unknown option via the block syntax" do
|
57
|
-
expect { Savon.client { another_invalid_global_option true } }.
|
58
|
-
to raise_error(Savon::UnknownOptionError, "Unknown global option: :another_invalid_global_option")
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe "#globals" do
|
63
|
-
it "returns the current set of global options" do
|
64
|
-
expect(new_client.globals).to be_an_instance_of(Savon::GlobalOptions)
|
65
|
-
end
|
66
|
-
|
67
|
-
fit "defaults :log to false" do
|
68
|
-
client = Savon.client(:wsdl => Fixture.wsdl(:authentication))
|
69
|
-
expect(client.globals[:log]).to be_falsey
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe "#service_name" do
|
74
|
-
it "returns the name of the service" do
|
75
|
-
expect(new_client.service_name).to eq('AuthenticationWebServiceImplService')
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe "#operations" do
|
80
|
-
it "returns all operation names" do
|
81
|
-
operations = new_client.operations
|
82
|
-
expect(operations).to eq([:authenticate])
|
83
|
-
end
|
84
|
-
|
85
|
-
it "raises when there is no WSDL document" do
|
86
|
-
expect { new_client_without_wsdl.operations }.to raise_error("Unable to inspect the service without a WSDL document.")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#operation" do
|
91
|
-
it "returns a new SOAP operation" do
|
92
|
-
operation = new_client.operation(:authenticate)
|
93
|
-
expect(operation).to be_a(Savon::Operation)
|
94
|
-
end
|
95
|
-
|
96
|
-
it "raises if there's no such SOAP operation" do
|
97
|
-
expect { new_client.operation(:does_not_exist) }.
|
98
|
-
to raise_error(Savon::UnknownOperationError)
|
99
|
-
end
|
100
|
-
|
101
|
-
it "does not raise when there is no WSDL document" do
|
102
|
-
new_client_without_wsdl.operation(:does_not_exist)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe "#call" do
|
107
|
-
it "calls a new SOAP operation" do
|
108
|
-
locals = { :message => { :symbol => "AAPL" } }
|
109
|
-
soap_response = new_soap_response
|
110
|
-
|
111
|
-
wsdl = Wasabi::Document.new('http://example.com')
|
112
|
-
operation = Savon::Operation.new(:authenticate, wsdl, Savon::GlobalOptions.new)
|
113
|
-
operation.expects(:call).with(locals).returns(soap_response)
|
114
|
-
|
115
|
-
Savon::Operation.expects(:create).with(
|
116
|
-
:authenticate,
|
117
|
-
instance_of(Wasabi::Document),
|
118
|
-
instance_of(Savon::GlobalOptions)
|
119
|
-
).returns(operation)
|
120
|
-
|
121
|
-
response = new_client.call(:authenticate, locals)
|
122
|
-
expect(response).to eq(soap_response)
|
123
|
-
end
|
124
|
-
|
125
|
-
it "supports a block without arguments to call an operation with local options" do
|
126
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
127
|
-
|
128
|
-
response = client.call(:authenticate) do
|
129
|
-
message(:symbol => "AAPL" )
|
130
|
-
end
|
131
|
-
|
132
|
-
expect(response.http.body).to include("<symbol>AAPL</symbol>")
|
133
|
-
end
|
134
|
-
|
135
|
-
it "supports a block with one argument to call an operation with local options" do
|
136
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
137
|
-
|
138
|
-
# supports instance variables!
|
139
|
-
@instance_variable = { :symbol => "AAPL" }
|
140
|
-
|
141
|
-
response = client.call(:authenticate) do |locals|
|
142
|
-
locals.message(@instance_variable)
|
143
|
-
end
|
144
|
-
|
145
|
-
expect(response.http.body).to include("<symbol>AAPL</symbol>")
|
146
|
-
end
|
147
|
-
|
148
|
-
it "accepts arguments for the message tag" do
|
149
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
150
|
-
response = client.call(:authenticate, :attributes => { "ID" => "ABC321"})
|
151
|
-
|
152
|
-
expect(response.http.body).to include('<tns:authenticate ID="ABC321">')
|
153
|
-
end
|
154
|
-
|
155
|
-
it "raises when the operation name is not a symbol" do
|
156
|
-
expect { new_client.call("not a symbol") }.to raise_error(
|
157
|
-
ArgumentError,
|
158
|
-
"Expected the first parameter (the name of the operation to call) to be a symbol\n" \
|
159
|
-
"Actual: \"not a symbol\" (String)"
|
160
|
-
)
|
161
|
-
end
|
162
|
-
|
163
|
-
it "raises a when given an unknown option via the Hash syntax" do
|
164
|
-
expect { new_client.call(:authenticate, :invalid_local_option => true) }.
|
165
|
-
to raise_error(Savon::UnknownOptionError, "Unknown local option: :invalid_local_option")
|
166
|
-
end
|
167
|
-
|
168
|
-
it "raises a when given an unknown option via the block syntax" do
|
169
|
-
expect { new_client.call(:authenticate) { another_invalid_local_option true } }.
|
170
|
-
to raise_error(Savon::UnknownOptionError, "Unknown local option: :another_invalid_local_option")
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
describe "#build_request" do
|
175
|
-
it "returns the request without making an actual call" do
|
176
|
-
expected_request = mock('request')
|
177
|
-
wsdl = Wasabi::Document.new('http://example.com')
|
178
|
-
|
179
|
-
operation = Savon::Operation.new(
|
180
|
-
:authenticate,
|
181
|
-
wsdl,
|
182
|
-
Savon::GlobalOptions.new
|
183
|
-
)
|
184
|
-
operation.expects(:request).returns(expected_request)
|
185
|
-
|
186
|
-
Savon::Operation.expects(:create).with(
|
187
|
-
:authenticate,
|
188
|
-
instance_of(Wasabi::Document),
|
189
|
-
instance_of(Savon::GlobalOptions)
|
190
|
-
).returns(operation)
|
191
|
-
|
192
|
-
operation.expects(:call).never
|
193
|
-
|
194
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
195
|
-
request = client.build_request(:authenticate) do
|
196
|
-
message(:symbol => "AAPL" )
|
197
|
-
end
|
198
|
-
|
199
|
-
expect(request).to eq expected_request
|
200
|
-
end
|
201
|
-
|
202
|
-
it "accepts a block without arguments" do
|
203
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
204
|
-
request = client.build_request(:authenticate) do
|
205
|
-
message(:symbol => "AAPL" )
|
206
|
-
end
|
207
|
-
|
208
|
-
expect(request.body).
|
209
|
-
to include('<tns:authenticate><symbol>AAPL</symbol></tns:authenticate>')
|
210
|
-
end
|
211
|
-
|
212
|
-
it "accepts a block with one argument" do
|
213
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
214
|
-
|
215
|
-
# supports instance variables!
|
216
|
-
@instance_variable = { :symbol => "AAPL" }
|
217
|
-
|
218
|
-
request = client.build_request(:authenticate) do |locals|
|
219
|
-
locals.message(@instance_variable)
|
220
|
-
end
|
221
|
-
|
222
|
-
expect(request.body).
|
223
|
-
to include("<tns:authenticate><symbol>AAPL</symbol></tns:authenticate>")
|
224
|
-
end
|
225
|
-
|
226
|
-
it "accepts argument for the message tag" do
|
227
|
-
client = new_client(:endpoint => @server.url(:repeat))
|
228
|
-
request = client.build_request(:authenticate, :attributes => { "ID" => "ABC321" })
|
229
|
-
|
230
|
-
expect(request.body).
|
231
|
-
to include("<tns:authenticate ID=\"ABC321\"></tns:authenticate>")
|
232
|
-
end
|
233
|
-
|
234
|
-
it "raises when the operation name is not a symbol" do
|
235
|
-
expect { new_client.build_request("not a symbol") }.to raise_error ArgumentError
|
236
|
-
end
|
237
|
-
|
238
|
-
it "raises when given an unknown option via the Hash syntax" do
|
239
|
-
expect { new_client.build_request(:authenticate, :invalid_local_option => true) }.to raise_error Savon::UnknownOptionError
|
240
|
-
end
|
241
|
-
|
242
|
-
it "raises when given an unknown option via the block syntax" do
|
243
|
-
expect { new_client.build_request(:authenticate) { another_invalid_local_option true } }.to raise_error Savon::UnknownOptionError
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def new_http_response(options = {})
|
248
|
-
defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
|
249
|
-
response = defaults.merge options
|
250
|
-
|
251
|
-
HTTPI::Response.new response[:code], response[:headers], response[:body]
|
252
|
-
end
|
253
|
-
|
254
|
-
def new_soap_response(options = {})
|
255
|
-
http = new_http_response(options)
|
256
|
-
globals = Savon::GlobalOptions.new
|
257
|
-
locals = Savon::LocalOptions.new
|
258
|
-
|
259
|
-
Savon::Response.new(http, globals, locals)
|
260
|
-
end
|
261
|
-
|
262
|
-
def new_client(globals = {})
|
263
|
-
globals = { :wsdl => Fixture.wsdl(:authentication), :log => false }.merge(globals)
|
264
|
-
Savon.client(globals)
|
265
|
-
end
|
266
|
-
|
267
|
-
def new_client_without_wsdl(globals = {})
|
268
|
-
globals = { :endpoint => "http://example.co", :namespace => "http://v1.example.com", :log => false }.merge(globals)
|
269
|
-
Savon.client(globals)
|
270
|
-
end
|
271
|
-
|
272
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
RSpec.describe String do
|
5
|
-
|
6
|
-
describe "snakecase" do
|
7
|
-
it "lowercases one word CamelCase" do
|
8
|
-
expect("Merb".snakecase).to eq("merb")
|
9
|
-
end
|
10
|
-
|
11
|
-
it "makes one underscore snakecase two word CamelCase" do
|
12
|
-
expect("MerbCore".snakecase).to eq("merb_core")
|
13
|
-
end
|
14
|
-
|
15
|
-
it "handles CamelCase with more than 2 words" do
|
16
|
-
expect("SoYouWantContributeToMerbCore".snakecase).to eq("so_you_want_contribute_to_merb_core")
|
17
|
-
end
|
18
|
-
|
19
|
-
it "handles CamelCase with more than 2 capital letter in a row" do
|
20
|
-
expect("CNN".snakecase).to eq("cnn")
|
21
|
-
expect("CNNNews".snakecase).to eq("cnn_news")
|
22
|
-
expect("HeadlineCNNNews".snakecase).to eq("headline_cnn_news")
|
23
|
-
end
|
24
|
-
|
25
|
-
it "does NOT change one word lowercase" do
|
26
|
-
expect("merb".snakecase).to eq("merb")
|
27
|
-
end
|
28
|
-
|
29
|
-
it "leaves snake_case as is" do
|
30
|
-
expect("merb_core".snakecase).to eq("merb_core")
|
31
|
-
end
|
32
|
-
|
33
|
-
it "converts period characters to underscores" do
|
34
|
-
expect("User.GetEmail".snakecase).to eq("user_get_email")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
RSpec.describe Savon do
|
5
|
-
|
6
|
-
it 'knows the message tag for :authentication' do
|
7
|
-
message_tag = message_tag_for(:authentication, :authenticate)
|
8
|
-
expect(message_tag).to eq(['http://v1_0.ws.auth.order.example.com/', 'authenticate'])
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'knows the message tag for :taxcloud' do
|
12
|
-
message_tag = message_tag_for(:taxcloud, :verify_address)
|
13
|
-
expect(message_tag).to eq(['http://taxcloud.net', 'VerifyAddress'])
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'knows the message tag for :team_software' do
|
17
|
-
message_tag = message_tag_for(:team_software, :login)
|
18
|
-
expect(message_tag).to eq(['http://tempuri.org/', 'Login'])
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'knows the message tag for :interhome' do
|
22
|
-
message_tag = message_tag_for(:interhome, :price_list)
|
23
|
-
expect(message_tag).to eq(['http://www.interhome.com/webservice', 'PriceList'])
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'knows the message tag for :betfair' do
|
27
|
-
message_tag = message_tag_for(:betfair, :get_bet)
|
28
|
-
expect(message_tag).to eq(['http://www.betfair.com/publicapi/v5/BFExchangeService/', 'getBet'])
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'knows the message tag for :vies' do
|
32
|
-
message_tag = message_tag_for(:vies, :check_vat)
|
33
|
-
expect(message_tag).to eq(['urn:ec.europa.eu:taxud:vies:services:checkVat:types', 'checkVat'])
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'knows the message tag for :wasmuth' do
|
37
|
-
message_tag = message_tag_for(:wasmuth, :get_st_tables)
|
38
|
-
expect(message_tag).to eq(['http://ws.online.msw/', 'getStTables'])
|
39
|
-
end
|
40
|
-
|
41
|
-
def message_tag_for(fixture, operation_name)
|
42
|
-
globals = Savon::GlobalOptions.new(:log => false)
|
43
|
-
wsdl = Wasabi::Document.new Fixture.wsdl(fixture)
|
44
|
-
operation = Savon::Operation.create(operation_name, wsdl, globals)
|
45
|
-
request_xml = operation.build.to_s
|
46
|
-
|
47
|
-
nsid, local = extract_message_tag_from_request(request_xml)
|
48
|
-
namespace = extract_namespace_from_request(nsid, request_xml)
|
49
|
-
|
50
|
-
[namespace, local]
|
51
|
-
end
|
52
|
-
|
53
|
-
def extract_message_tag_from_request(xml)
|
54
|
-
match = xml.match(/<\w+?:Body><(.+?):(.+?)>/)
|
55
|
-
[ match[1], match[2] ]
|
56
|
-
end
|
57
|
-
|
58
|
-
def extract_namespace_from_request(nsid, xml)
|
59
|
-
xml.match(/xmlns:#{nsid}="(.+?)"/)[1]
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
RSpec.describe Savon::HTTPError do
|
5
|
-
let(:http_error) { Savon::HTTPError.new new_response(:code => 404, :body => "Not Found") }
|
6
|
-
let(:http_error_with_empty_body) { Savon::HTTPError.new new_response(:code => 404, :body => "") }
|
7
|
-
let(:no_error) { Savon::HTTPError.new new_response }
|
8
|
-
|
9
|
-
it "inherits from Savon::Error" do
|
10
|
-
expect(Savon::HTTPError.ancestors).to include(Savon::Error)
|
11
|
-
end
|
12
|
-
|
13
|
-
describe ".present?" do
|
14
|
-
it "returns true if there was an HTTP error" do
|
15
|
-
http = new_response(:code => 404, :body => "Not Found")
|
16
|
-
expect(Savon::HTTPError.present? http).to be_truthy
|
17
|
-
end
|
18
|
-
|
19
|
-
it "returns false unless there was an HTTP error" do
|
20
|
-
expect(Savon::HTTPError.present? new_response).to be_falsey
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "#http" do
|
25
|
-
it "returns the HTTPI::Response" do
|
26
|
-
expect(http_error.http).to be_a(HTTPI::Response)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
[:message, :to_s].each do |method|
|
31
|
-
describe "##{method}" do
|
32
|
-
it "returns the HTTP error message" do
|
33
|
-
expect(http_error.send method).to eq("HTTP error (404): Not Found")
|
34
|
-
end
|
35
|
-
|
36
|
-
context "when the body is empty" do
|
37
|
-
it "returns the HTTP error without the body message" do
|
38
|
-
expect(http_error_with_empty_body.send method).to eq("HTTP error (404)")
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "#to_hash" do
|
45
|
-
it "returns the HTTP response details as a Hash" do
|
46
|
-
expect(http_error.to_hash).to eq(:code => 404, :headers => {}, :body => "Not Found")
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def new_response(options = {})
|
51
|
-
defaults = { :code => 200, :headers => {}, :body => Fixture.response(:authentication) }
|
52
|
-
response = defaults.merge options
|
53
|
-
|
54
|
-
HTTPI::Response.new response[:code], response[:headers], response[:body]
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
RSpec.describe Savon::LogMessage do
|
5
|
-
|
6
|
-
it "returns the message if it's not XML" do
|
7
|
-
message = log_message("hello", [:password], :pretty_print).to_s
|
8
|
-
expect(message).to eq("hello")
|
9
|
-
end
|
10
|
-
|
11
|
-
it "returns the message if it shouldn't be filtered or pretty printed" do
|
12
|
-
Nokogiri.expects(:XML).never
|
13
|
-
|
14
|
-
message = log_message("<hello/>", [], false).to_s
|
15
|
-
expect(message).to eq("<hello/>")
|
16
|
-
end
|
17
|
-
|
18
|
-
it "pretty prints a given message" do
|
19
|
-
message = log_message("<envelope><body>hello</body></envelope>", [], :pretty_print).to_s
|
20
|
-
|
21
|
-
expect(message).to include("\n<envelope>")
|
22
|
-
expect(message).to include("\n <body>")
|
23
|
-
end
|
24
|
-
|
25
|
-
it "filters tags in a given message without pretty printing" do
|
26
|
-
message = log_message("<root><password>secret</password></root>", [:password], false).to_s
|
27
|
-
expect(message).to include("<password>***FILTERED***</password>")
|
28
|
-
expect(message).to_not include("\n <password>***FILTERED***</password>") # no pretty printing
|
29
|
-
end
|
30
|
-
|
31
|
-
it "filters tags in a given message with pretty printing" do
|
32
|
-
message = log_message("<root><password>secret</password></root>", [:password], true).to_s
|
33
|
-
expect(message).to include("\n <password>***FILTERED***</password>")
|
34
|
-
end
|
35
|
-
|
36
|
-
it "properly applies Proc filter" do
|
37
|
-
filter = Proc.new do |document|
|
38
|
-
document.xpath('//password').each do |node|
|
39
|
-
node.content = "FILTERED"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
message = log_message("<root><password>secret</password></root>", [filter], false).to_s
|
44
|
-
expect(message).to include("<password>FILTERED</password>")
|
45
|
-
end
|
46
|
-
|
47
|
-
def log_message(*args)
|
48
|
-
Savon::LogMessage.new(*args)
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|