wash_out 0.10.0.beta.1 → 0.10.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/.gitignore +3 -1
- data/.travis.yml +23 -3
- data/Appraisals +11 -5
- data/Gemfile +2 -2
- data/README.md +66 -2
- data/Rakefile +6 -7
- data/app/helpers/wash_out_helper.rb +49 -18
- data/app/views/{wash_with_soap → wash_out}/document/error.builder +0 -0
- data/app/views/{wash_with_soap → wash_out}/document/response.builder +1 -3
- data/app/views/{wash_with_soap → wash_out}/document/wsdl.builder +15 -15
- data/app/views/{wash_with_soap → wash_out}/rpc/error.builder +0 -0
- data/app/views/{wash_with_soap → wash_out}/rpc/response.builder +1 -3
- data/app/views/{wash_with_soap → wash_out}/rpc/wsdl.builder +16 -16
- data/gemfiles/rails_3.1.3.gemfile +20 -0
- data/gemfiles/rails_3.2.12.gemfile +20 -0
- data/gemfiles/rails_4.0.0.gemfile +19 -0
- data/gemfiles/rails_4.1.0.gemfile +19 -0
- data/gemfiles/rails_4.2.0.gemfile +19 -0
- data/lib/wash_out.rb +48 -16
- data/lib/wash_out/configurable.rb +41 -0
- data/lib/wash_out/dispatcher.rb +212 -0
- data/lib/wash_out/engine.rb +12 -0
- data/lib/wash_out/middleware.rb +41 -0
- data/lib/wash_out/model.rb +29 -0
- data/lib/wash_out/param.rb +43 -16
- data/lib/wash_out/router.rb +95 -0
- data/lib/wash_out/soap.rb +48 -0
- data/lib/wash_out/soap_config.rb +93 -0
- data/lib/wash_out/type.rb +20 -13
- data/lib/wash_out/version.rb +1 -1
- data/lib/wash_out/wsse.rb +29 -10
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/lib/wash_out/dispatcher_spec.rb +28 -13
- data/spec/lib/wash_out/middleware_spec.rb +33 -0
- data/spec/lib/wash_out/param_spec.rb +47 -17
- data/spec/lib/wash_out/router_spec.rb +22 -0
- data/spec/lib/wash_out/type_spec.rb +9 -9
- data/spec/lib/wash_out_spec.rb +139 -87
- data/spec/spec_helper.rb +7 -1
- metadata +32 -25
- data/lib/wash_out/exceptions/programmer_error.rb +0 -10
- data/lib/wash_out/exceptions/soap_error.rb +0 -19
- data/lib/wash_out/middlewares/catcher.rb +0 -42
- data/lib/wash_out/middlewares/router.rb +0 -132
- data/lib/wash_out/rails/active_record.rb +0 -27
- data/lib/wash_out/rails/controller.rb +0 -201
- data/lib/wash_out/rails/engine.rb +0 -74
- data/spec/lib/wash_out/rack_spec.rb +0 -55
data/lib/wash_out/wsse.rb
CHANGED
@@ -1,26 +1,41 @@
|
|
1
1
|
module WashOut
|
2
|
-
class Wsse
|
3
2
|
|
4
|
-
|
3
|
+
module WsseParams
|
4
|
+
def wsse_username
|
5
|
+
if request.env['WSSE_TOKEN']
|
6
|
+
request.env['WSSE_TOKEN'].values_at(:username, :Username).compact.first
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
5
10
|
|
11
|
+
class Wsse
|
12
|
+
attr_reader :soap_config
|
6
13
|
def self.authenticate(soap_config, token)
|
7
14
|
wsse = self.new(soap_config, token)
|
8
15
|
|
9
16
|
unless wsse.eligible?
|
10
|
-
raise WashOut::SOAPError, "Unauthorized"
|
17
|
+
raise WashOut::Dispatcher::SOAPError, "Unauthorized"
|
11
18
|
end
|
12
19
|
end
|
13
20
|
|
14
21
|
def initialize(soap_config, token)
|
15
22
|
@soap_config = soap_config
|
16
23
|
if token.blank? && required?
|
17
|
-
raise WashOut::SOAPError, "Missing required UsernameToken"
|
24
|
+
raise WashOut::Dispatcher::SOAPError, "Missing required UsernameToken"
|
18
25
|
end
|
19
26
|
@username_token = token
|
20
27
|
end
|
21
28
|
|
22
29
|
def required?
|
23
|
-
!soap_config.wsse_username.blank?
|
30
|
+
!soap_config.wsse_username.blank? || auth_callback?
|
31
|
+
end
|
32
|
+
|
33
|
+
def auth_callback?
|
34
|
+
return !!soap_config.wsse_auth_callback && soap_config.wsse_auth_callback.respond_to?(:call) && soap_config.wsse_auth_callback.arity == 2
|
35
|
+
end
|
36
|
+
|
37
|
+
def perform_auth_callback(user, password)
|
38
|
+
soap_config.wsse_auth_callback.call(user, password)
|
24
39
|
end
|
25
40
|
|
26
41
|
def expected_user
|
@@ -34,8 +49,8 @@ module WashOut
|
|
34
49
|
def matches_expected_digest?(password)
|
35
50
|
nonce = @username_token.values_at(:nonce, :Nonce).compact.first
|
36
51
|
timestamp = @username_token.values_at(:created, :Created).compact.first
|
37
|
-
|
38
52
|
return false if nonce.nil? || timestamp.nil?
|
53
|
+
timestamp = timestamp.to_datetime
|
39
54
|
|
40
55
|
# Token should not be accepted if timestamp is older than 5 minutes ago
|
41
56
|
# http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf
|
@@ -47,11 +62,11 @@ module WashOut
|
|
47
62
|
flavors = Array.new
|
48
63
|
|
49
64
|
# Ruby / Savon
|
50
|
-
token = nonce + timestamp.
|
65
|
+
token = nonce + timestamp.strftime("%Y-%m-%dT%H:%M:%SZ") + expected_password
|
51
66
|
flavors << Base64.encode64(Digest::SHA1.hexdigest(token)).chomp!
|
52
67
|
|
53
68
|
# Java
|
54
|
-
token = Base64.decode64(nonce) + timestamp.
|
69
|
+
token = Base64.decode64(nonce) + timestamp.strftime("%Y-%m-%dT%H:%M:%SZ") + expected_password
|
55
70
|
flavors << Base64.encode64(Digest::SHA1.digest(token)).chomp!
|
56
71
|
|
57
72
|
flavors.each do |f|
|
@@ -67,11 +82,15 @@ module WashOut
|
|
67
82
|
user = @username_token.values_at(:username, :Username).compact.first
|
68
83
|
password = @username_token.values_at(:password, :Password).compact.first
|
69
84
|
|
70
|
-
if (expected_user == user &&
|
85
|
+
if (expected_user == user && matches_expected_digest?(password))
|
71
86
|
return true
|
72
87
|
end
|
73
88
|
|
74
|
-
if
|
89
|
+
if auth_callback?
|
90
|
+
return perform_auth_callback(user, password)
|
91
|
+
end
|
92
|
+
|
93
|
+
if (expected_user == user && expected_password == password)
|
75
94
|
return true
|
76
95
|
end
|
77
96
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe WashOut::
|
5
|
+
describe WashOut::Dispatcher do
|
6
6
|
|
7
7
|
class Dispatcher < ApplicationController
|
8
8
|
soap_service
|
@@ -13,19 +13,19 @@ describe WashOut::Rails::Controller do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "finds nested hashes" do
|
16
|
-
WashOut::
|
17
|
-
WashOut::
|
16
|
+
expect(WashOut::Dispatcher.deep_select(:foo => 1){|k,v| k == :foo}).to eq [1]
|
17
|
+
expect(WashOut::Dispatcher.deep_select({:foo => {:foo => 1}}){|k,v| k == :foo}).to eq([{:foo => 1}, 1])
|
18
18
|
end
|
19
19
|
|
20
20
|
it "replaces nested hashed" do
|
21
|
-
WashOut::
|
22
|
-
WashOut::
|
21
|
+
expect(WashOut::Dispatcher.deep_replace_href({:foo => {:@href => 1}}, {1 => 2})).to eq({:foo => 2})
|
22
|
+
expect(WashOut::Dispatcher.deep_replace_href({:bar => {:foo => {:@href => 1}}}, {1 => 2})).to eq({:bar => {:foo => 2}})
|
23
23
|
end
|
24
24
|
|
25
25
|
xit "parses typical request" do
|
26
26
|
dispatcher = Dispatcher.mock("<foo>1</foo>")
|
27
27
|
dispatcher._parse_soap_parameters
|
28
|
-
dispatcher.params.
|
28
|
+
expect(dispatcher.params).to eq({:foo => "1"})
|
29
29
|
end
|
30
30
|
|
31
31
|
xit "parses href request" do
|
@@ -45,38 +45,53 @@ describe WashOut::Rails::Controller do
|
|
45
45
|
</root>
|
46
46
|
XML
|
47
47
|
dispatcher._parse_soap_parameters
|
48
|
-
dispatcher.params[:root][:request][:entities].
|
48
|
+
expect(dispatcher.params[:root][:request][:entities]).to eq({
|
49
49
|
:foo => {:bar=>"1"},
|
50
50
|
:sub => {:foo=>"1", :@id=>"id2"},
|
51
51
|
:@id => "id1"
|
52
|
-
}
|
52
|
+
})
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#_map_soap_parameters" do
|
56
|
+
let(:dispatcher) { Dispatcher.new }
|
57
|
+
let(:soap_config) { WashOut::SoapConfig.new(camelize_wsdl: false) }
|
58
|
+
|
59
|
+
before do
|
60
|
+
allow(dispatcher).to receive(:action_spec).and_return(in: WashOut::Param.parse_def(soap_config, { foo: { "@bar" => :string, empty: :string } } ))
|
61
|
+
allow(dispatcher).to receive(:xml_data).and_return(foo: { "@bar" => "buzz", empty: { :"@xsi:type" => "xsd:string" } })
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should handle empty strings that have been parsed wrong by nori, but preserve attrs" do
|
65
|
+
dispatcher._map_soap_parameters
|
66
|
+
expect(dispatcher.params).to eq("foo" => { "bar" => "buzz", "empty" => nil })
|
67
|
+
end
|
53
68
|
end
|
54
69
|
|
55
70
|
describe "#_load_params" do
|
56
71
|
let(:dispatcher) { Dispatcher.new }
|
57
|
-
let(:soap_config) {
|
72
|
+
let(:soap_config) { WashOut::SoapConfig.new({ camelize_wsdl: false }) }
|
58
73
|
it "should load params for an array" do
|
59
74
|
spec = WashOut::Param.parse_def(soap_config, {:my_array => [:integer] } )
|
60
75
|
xml_data = {:my_array => [1, 2, 3]}
|
61
|
-
dispatcher._load_params(spec, xml_data).
|
76
|
+
expect(dispatcher._load_params(spec, xml_data)).to eq({"my_array" => [1, 2, 3]})
|
62
77
|
end
|
63
78
|
|
64
79
|
it "should load params for an empty array" do
|
65
80
|
spec = WashOut::Param.parse_def(soap_config, {:my_array => [:integer] } )
|
66
81
|
xml_data = {}
|
67
|
-
dispatcher._load_params(spec, xml_data).
|
82
|
+
expect(dispatcher._load_params(spec, xml_data)).to eq({})
|
68
83
|
end
|
69
84
|
|
70
85
|
it "should load params for a nested array" do
|
71
86
|
spec = WashOut::Param.parse_def(soap_config, {:nested => {:my_array => [:integer]}} )
|
72
87
|
xml_data = {:nested => {:my_array => [1, 2, 3]}}
|
73
|
-
dispatcher._load_params(spec, xml_data).
|
88
|
+
expect(dispatcher._load_params(spec, xml_data)).to eq({"nested" => {"my_array" => [1, 2, 3]}})
|
74
89
|
end
|
75
90
|
|
76
91
|
it "should load params for an empty nested array" do
|
77
92
|
spec = WashOut::Param.parse_def(soap_config, {:nested => {:empty => [:integer] }} )
|
78
93
|
xml_data = {:nested => nil}
|
79
|
-
dispatcher._load_params(spec, xml_data).
|
94
|
+
expect(dispatcher._load_params(spec, xml_data)).to eq({"nested" => {}})
|
80
95
|
end
|
81
96
|
|
82
97
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'wash_out/middleware'
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
describe WashOut::Middleware do
|
6
|
+
it 'handles Rack environment variables' do
|
7
|
+
err = begin
|
8
|
+
REXML::Document.new '<hi>'
|
9
|
+
rescue REXML::ParseException => e
|
10
|
+
e
|
11
|
+
end
|
12
|
+
|
13
|
+
env = {}
|
14
|
+
expect {
|
15
|
+
WashOut::Middleware.raise_or_render_rexml_parse_error err, env
|
16
|
+
}.to raise_exception(REXML::ParseException)
|
17
|
+
|
18
|
+
env['HTTP_SOAPACTION'] = 'pretend_action'
|
19
|
+
env['rack.errors'] = double 'logger', {:puts => true}
|
20
|
+
env['rack.input'] = double 'basic-rack-input', {:string => '<hi>'}
|
21
|
+
result = WashOut::Middleware.raise_or_render_rexml_parse_error err, env
|
22
|
+
expect(result[0]).to eq 400
|
23
|
+
expect(result[1]['Content-Type']).to eq 'text/xml'
|
24
|
+
msg = result[2][0]
|
25
|
+
expect(msg).to include 'Error parsing SOAP Request XML'
|
26
|
+
expect(msg).to include 'soap:Fault'
|
27
|
+
expect(msg).not_to include __FILE__
|
28
|
+
|
29
|
+
env['rack.input'] = double 'passenger-input', {:read => '<hi>'}
|
30
|
+
result = WashOut::Middleware.raise_or_render_rexml_parse_error err, env
|
31
|
+
expect(result[0]).to eq 400
|
32
|
+
end
|
33
|
+
end
|
@@ -18,47 +18,77 @@ describe WashOut::Param do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "loads custom_types" do
|
21
|
-
soap_config =
|
21
|
+
soap_config = WashOut::SoapConfig.new({ camelize_wsdl: false })
|
22
22
|
map = WashOut::Param.parse_def soap_config, Abraka2
|
23
23
|
|
24
|
-
map.
|
25
|
-
map[0].name.
|
26
|
-
map[0].map[0].name.
|
27
|
-
map[0].map[0].map[0].name.should == 'test'
|
24
|
+
expect(map).to be_a_kind_of(Array)
|
25
|
+
expect(map[0].name).to eq 'foo'
|
26
|
+
expect(map[0].map[0].name).to eq 'test'
|
28
27
|
end
|
29
28
|
|
30
29
|
it "respects camelization setting" do
|
31
|
-
soap_config =
|
30
|
+
soap_config = WashOut::SoapConfig.new({ camelize_wsdl: true })
|
32
31
|
|
33
32
|
map = WashOut::Param.parse_def soap_config, Abraka2
|
34
33
|
|
35
|
-
map.
|
36
|
-
map[0].name.
|
37
|
-
map[0].map[0].name.
|
38
|
-
map[0].map[0].map[0].name.should == 'Test'
|
34
|
+
expect(map).to be_a_kind_of(Array)
|
35
|
+
expect(map[0].name).to eq 'Foo'
|
36
|
+
expect(map[0].map[0].name).to eq 'Test'
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
42
40
|
it "should accept nested empty arrays" do
|
43
|
-
soap_config =
|
41
|
+
soap_config = WashOut::SoapConfig.new({ camelize_wsdl: false })
|
44
42
|
map = WashOut::Param.parse_def(soap_config, {:nested => {:some_attr => :string, :empty => [:integer] }} )
|
45
|
-
map[0].load( {:nested => nil}, :nested).
|
43
|
+
expect(map[0].load( {:nested => nil}, :nested)).to eq({})
|
46
44
|
end
|
47
45
|
|
48
46
|
describe "booleans" do
|
49
|
-
let(:soap_config) {
|
47
|
+
let(:soap_config) { WashOut::SoapConfig.new({ camelize_wsdl: false }) }
|
50
48
|
# following http://www.w3.org/TR/xmlschema-2/#boolean, only true, false, 0 and 1 are allowed.
|
51
49
|
# Nori maps the strings true and false to TrueClass and FalseClass, but not 0 and 1.
|
52
50
|
let(:map) { WashOut::Param.parse_def(soap_config, :value => :boolean) }
|
53
51
|
|
54
52
|
it "should accept 'true' and '1'" do
|
55
|
-
map[0].load({:value => true}, :value).
|
56
|
-
map[0].load({:value => "1"}, :value).
|
53
|
+
expect(map[0].load({:value => true}, :value)).to be true
|
54
|
+
expect(map[0].load({:value => "1"}, :value)).to be true
|
57
55
|
end
|
58
56
|
|
59
57
|
it "should accept 'false' and '0'" do
|
60
|
-
map[0].load({:value => false}, :value).
|
61
|
-
map[0].load({:value => "0"}, :value).
|
58
|
+
expect(map[0].load({:value => false}, :value)).to be false
|
59
|
+
expect(map[0].load({:value => "0"}, :value)).to be false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'longs' do
|
64
|
+
let(:soap_config) { WashOut::SoapConfig.new({ camelize_wsdl: false }) }
|
65
|
+
let(:map) { WashOut::Param.parse_def(soap_config, :value => :long) }
|
66
|
+
|
67
|
+
it "should accept positive long" do
|
68
|
+
expect(map[0].load({:value => 9223372036854775807}, :value)).to eq 9223372036854775807
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should accept negative long" do
|
72
|
+
expect(map[0].load({:value => -9223372036854775807}, :value)).to eq -9223372036854775807
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#flat_copy' do
|
77
|
+
it 'should copy everything' do
|
78
|
+
soap_config = WashOut::SoapConfig.new({})
|
79
|
+
type = :foo
|
80
|
+
multiplied = "of course"
|
81
|
+
|
82
|
+
param = WashOut::Param.new(soap_config, 'name', type, multiplied)
|
83
|
+
param.source_class = "middle class"
|
84
|
+
evil_clone = param.flat_copy
|
85
|
+
|
86
|
+
expect(evil_clone.source_class).to eq "middle class"
|
87
|
+
expect(evil_clone.name).to eq 'name'
|
88
|
+
expect(evil_clone.raw_name).to eq 'name'
|
89
|
+
expect(evil_clone.type).to eq "foo"
|
90
|
+
expect(evil_clone.multiplied).to eq "of course"
|
91
|
+
expect(evil_clone.soap_config).to eq soap_config
|
62
92
|
end
|
63
93
|
end
|
64
94
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'wash_out/router'
|
3
|
+
|
4
|
+
describe WashOut::Router do
|
5
|
+
it 'returns a 200 with empty soap action' do
|
6
|
+
|
7
|
+
mock_controller do
|
8
|
+
# nothing
|
9
|
+
end
|
10
|
+
|
11
|
+
env = {}
|
12
|
+
env['REQUEST_METHOD'] = 'GET'
|
13
|
+
env['rack.input'] = double 'basic-rack-input', {:string => ''}
|
14
|
+
result = WashOut::Router.new('Api').call env
|
15
|
+
|
16
|
+
expect(result[0]).to eq(200)
|
17
|
+
#expect(result[1]['Content-Type']).to eq('text/xml')
|
18
|
+
|
19
|
+
msg = result[2][0]
|
20
|
+
expect(msg).to eq('OK')
|
21
|
+
end
|
22
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#encoding:utf-8
|
1
|
+
#encoding:utf-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
@@ -15,11 +15,11 @@ describe WashOut::Type do
|
|
15
15
|
map :foo => Abraka1
|
16
16
|
end
|
17
17
|
|
18
|
-
Abraka1.wash_out_param_name.
|
19
|
-
Abraka1.wash_out_param_map.
|
18
|
+
expect(Abraka1.wash_out_param_name).to eq 'abraka1'
|
19
|
+
expect(Abraka1.wash_out_param_map).to eq({:test => :string})
|
20
20
|
|
21
|
-
Abraka2.wash_out_param_name.
|
22
|
-
Abraka2.wash_out_param_map.
|
21
|
+
expect(Abraka2.wash_out_param_name).to eq 'test'
|
22
|
+
expect(Abraka2.wash_out_param_map).to eq({:foo => Abraka1})
|
23
23
|
end
|
24
24
|
|
25
25
|
it "allows arrays inside custom types" do
|
@@ -31,11 +31,11 @@ describe WashOut::Type do
|
|
31
31
|
map :foo => [:bar => Abraka1]
|
32
32
|
end
|
33
33
|
|
34
|
-
Abraka1.wash_out_param_name.
|
35
|
-
Abraka1.wash_out_param_map.
|
34
|
+
expect(Abraka1.wash_out_param_name).to eq 'abraka1'
|
35
|
+
expect(Abraka1.wash_out_param_map).to eq({:test => :string})
|
36
36
|
|
37
|
-
Abraka2.wash_out_param_name.
|
38
|
-
Abraka2.wash_out_param_map.
|
37
|
+
expect(Abraka2.wash_out_param_name).to eq 'test'
|
38
|
+
expect(Abraka2.wash_out_param_map).to eq({:foo => [:bar => Abraka1]})
|
39
39
|
end
|
40
40
|
|
41
41
|
end
|
data/spec/lib/wash_out_spec.rb
CHANGED
@@ -28,19 +28,19 @@ describe WashOut do
|
|
28
28
|
|
29
29
|
describe "Module" do
|
30
30
|
it "includes" do
|
31
|
-
|
31
|
+
expect {
|
32
32
|
mock_controller do
|
33
33
|
# nothing
|
34
34
|
end
|
35
|
-
}.
|
35
|
+
}.not_to raise_exception
|
36
36
|
end
|
37
37
|
|
38
38
|
it "allows definition of a simple action" do
|
39
|
-
|
39
|
+
expect {
|
40
40
|
mock_controller do
|
41
41
|
soap_action "answer", :args => nil, :return => :integer
|
42
42
|
end
|
43
|
-
}.
|
43
|
+
}.not_to raise_exception
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -68,13 +68,13 @@ describe WashOut do
|
|
68
68
|
|
69
69
|
it "lists operations" do
|
70
70
|
operations = xml[:definitions][:binding][:operation]
|
71
|
-
operations.
|
71
|
+
expect(operations).to be_a_kind_of(Array)
|
72
72
|
|
73
|
-
operations.map{|e| e[:'@name']}.sort.
|
73
|
+
expect(operations.map{|e| e[:'@name']}.sort).to eq ['Result', 'getArea', 'rocky'].sort
|
74
74
|
end
|
75
75
|
|
76
76
|
it "defines complex types" do
|
77
|
-
wsdl.include?('<xsd:complexType name="Circle1">').
|
77
|
+
expect(wsdl.include?('<xsd:complexType name="Circle1">')).to be true
|
78
78
|
end
|
79
79
|
|
80
80
|
it "defines arrays" do
|
@@ -82,8 +82,8 @@ describe WashOut do
|
|
82
82
|
find{|x| x[:'@name'] == 'Center'}[:sequence][:element].
|
83
83
|
find{|x| x[:'@name'] == 'X'}
|
84
84
|
|
85
|
-
x[:'@min_occurs'].
|
86
|
-
x[:'@max_occurs'].
|
85
|
+
expect(x[:'@min_occurs']).to eq "0"
|
86
|
+
expect(x[:'@max_occurs']).to eq "unbounded"
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -109,7 +109,7 @@ describe WashOut do
|
|
109
109
|
</env:Envelope>
|
110
110
|
XML
|
111
111
|
|
112
|
-
HTTPI.post("http://app/api/action", request).body.
|
112
|
+
expect(HTTPI.post("http://app/api/action", request).body).to eq <<-XML
|
113
113
|
<?xml version="1.0" encoding="UTF-8"?>
|
114
114
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="false">
|
115
115
|
<soap:Body>
|
@@ -129,8 +129,8 @@ describe WashOut do
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
savon(:answer)[:answer_response][:value].
|
133
|
-
|
132
|
+
expect(savon(:answer)[:answer_response][:value]).
|
133
|
+
to eq "42"
|
134
134
|
end
|
135
135
|
|
136
136
|
it "accept insufficient parameters" do
|
@@ -141,8 +141,8 @@ describe WashOut do
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
savon(:answer)[:answer_response][:value].
|
145
|
-
|
144
|
+
expect(savon(:answer)[:answer_response][:value]).
|
145
|
+
to eq "42"
|
146
146
|
end
|
147
147
|
|
148
148
|
it "accept empty parameter" do
|
@@ -152,8 +152,8 @@ describe WashOut do
|
|
152
152
|
render :soap => {:a => params[:a]}
|
153
153
|
end
|
154
154
|
end
|
155
|
-
savon(:answer, :a => '')[:answer_response][:a].
|
156
|
-
|
155
|
+
expect(savon(:answer, :a => '')[:answer_response][:a]).
|
156
|
+
to eq({:"@xsi:type"=>"xsd:string"})
|
157
157
|
end
|
158
158
|
|
159
159
|
it "accept one parameter" do
|
@@ -164,8 +164,8 @@ describe WashOut do
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
|
-
savon(:check_answer, 42)[:check_answer_response][:value].
|
168
|
-
savon(:check_answer, 13)[:check_answer_response][:value].
|
167
|
+
expect(savon(:check_answer, 42)[:check_answer_response][:value]).to be true
|
168
|
+
expect(savon(:check_answer, 13)[:check_answer_response][:value]).to be false
|
169
169
|
end
|
170
170
|
|
171
171
|
it "accept two parameters" do
|
@@ -176,7 +176,7 @@ describe WashOut do
|
|
176
176
|
end
|
177
177
|
end
|
178
178
|
|
179
|
-
savon(:funky, :a => 42, :b => 'k')[:funky_response][:value].
|
179
|
+
expect(savon(:funky, :a => 42, :b => 'k')[:funky_response][:value]).to eq '420k'
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
@@ -199,8 +199,8 @@ describe WashOut do
|
|
199
199
|
message = { :circle => { :center => { :x => 3, :y => 4 },
|
200
200
|
:radius => 5 } }
|
201
201
|
|
202
|
-
savon(:get_area, message)[:get_area_response].
|
203
|
-
|
202
|
+
expect(savon(:get_area, message)[:get_area_response]).
|
203
|
+
to eq ({ :area => (Math::PI * 25).to_s, :distance_from_o => (5.0).to_s })
|
204
204
|
end
|
205
205
|
|
206
206
|
it "accept arrays" do
|
@@ -211,7 +211,7 @@ describe WashOut do
|
|
211
211
|
},
|
212
212
|
:return => nil
|
213
213
|
def rumba
|
214
|
-
params.
|
214
|
+
expect(params).to eq({"rumbas" => [1, 2, 3]})
|
215
215
|
render :soap => nil
|
216
216
|
end
|
217
217
|
end
|
@@ -227,7 +227,7 @@ describe WashOut do
|
|
227
227
|
},
|
228
228
|
:return => nil
|
229
229
|
def rumba
|
230
|
-
params.
|
230
|
+
expect(params).to eq({})
|
231
231
|
render :soap => nil
|
232
232
|
end
|
233
233
|
end
|
@@ -242,7 +242,7 @@ describe WashOut do
|
|
242
242
|
},
|
243
243
|
:return => nil
|
244
244
|
def rumba
|
245
|
-
params.
|
245
|
+
expect(params).to eq({"nested" => {}})
|
246
246
|
render :soap => nil
|
247
247
|
end
|
248
248
|
end
|
@@ -260,12 +260,12 @@ describe WashOut do
|
|
260
260
|
},
|
261
261
|
:return => nil
|
262
262
|
def rumba
|
263
|
-
params.
|
263
|
+
expect(params).to eq({
|
264
264
|
"rumbas" => [
|
265
265
|
{"zombies" => 'suck', "puppies" => 'rock'},
|
266
266
|
{"zombies" => 'slow', "puppies" => 'fast'}
|
267
267
|
]
|
268
|
-
}
|
268
|
+
})
|
269
269
|
render :soap => nil
|
270
270
|
end
|
271
271
|
end
|
@@ -292,8 +292,15 @@ describe WashOut do
|
|
292
292
|
end
|
293
293
|
end
|
294
294
|
|
295
|
-
savon(:gogogo)[:gogogo_response].
|
296
|
-
|
295
|
+
expect(savon(:gogogo)[:gogogo_response]).
|
296
|
+
to eq({
|
297
|
+
:zoo=>"zoo",
|
298
|
+
:boo=>{
|
299
|
+
:moo=>"moo",
|
300
|
+
:doo=>"doo",
|
301
|
+
:"@xsi:type"=>"tns:Boo"
|
302
|
+
}
|
303
|
+
})
|
297
304
|
end
|
298
305
|
|
299
306
|
it "respond with arrays" do
|
@@ -306,7 +313,9 @@ describe WashOut do
|
|
306
313
|
end
|
307
314
|
end
|
308
315
|
|
309
|
-
savon(:rumba)[:rumba_response].
|
316
|
+
expect(savon(:rumba)[:rumba_response]).to eq({
|
317
|
+
:value => ["1", "2", "3"]
|
318
|
+
})
|
310
319
|
end
|
311
320
|
|
312
321
|
it "respond with complex structures inside arrays" do
|
@@ -314,55 +323,57 @@ describe WashOut do
|
|
314
323
|
soap_action "rumba",
|
315
324
|
:args => nil,
|
316
325
|
:return => {
|
317
|
-
:rumbas => [{:zombies => :string, :puppies => :string}]
|
326
|
+
:rumbas => [{:@level => :integer, :zombies => :string, :puppies => :string}]
|
318
327
|
}
|
319
328
|
def rumba
|
320
329
|
render :soap =>
|
321
330
|
{:rumbas => [
|
322
|
-
{:zombies => "suck1", :puppies => "rock1" },
|
331
|
+
{:@level => 80, :zombies => "suck1", :puppies => "rock1" },
|
323
332
|
{:zombies => "suck2", :puppies => "rock2" }
|
324
333
|
]
|
325
334
|
}
|
326
335
|
end
|
327
336
|
end
|
328
337
|
|
329
|
-
savon(:rumba)[:rumba_response].
|
338
|
+
expect(savon(:rumba)[:rumba_response]).to eq({
|
330
339
|
:rumbas => [
|
331
|
-
{:zombies => "suck1",:puppies => "rock1", :"@xsi:type"=>"tns:Rumbas"},
|
340
|
+
{:zombies => "suck1",:puppies => "rock1", :"@xsi:type"=>"tns:Rumbas", :@level => "80"},
|
332
341
|
{:zombies => "suck2", :puppies => "rock2", :"@xsi:type"=>"tns:Rumbas" }
|
333
342
|
]
|
334
|
-
}
|
343
|
+
})
|
335
344
|
end
|
336
345
|
|
337
346
|
it "respond with structs in structs in arrays" do
|
338
347
|
mock_controller do
|
339
348
|
soap_action "rumba",
|
340
349
|
:args => nil,
|
341
|
-
:return => [{:rumbas => {:zombies => :integer}}]
|
350
|
+
:return => [{:rumbas => {:@level => :integer, :zombies => :integer}}]
|
342
351
|
|
343
352
|
def rumba
|
344
|
-
render :soap => [{:rumbas => {:zombies => 100000}}, {:rumbas => {:zombies => 2}}]
|
353
|
+
render :soap => [{:rumbas => {:@level => 80, :zombies => 100000}}, {:rumbas => {:@level => 90, :zombies => 2}}]
|
345
354
|
end
|
346
355
|
end
|
347
356
|
|
348
|
-
savon(:rumba)[:rumba_response].
|
357
|
+
expect(savon(:rumba)[:rumba_response]).to eq({
|
349
358
|
:value => [
|
350
359
|
{
|
351
360
|
:rumbas => {
|
352
361
|
:zombies => "100000",
|
353
|
-
:"@xsi:type" => "tns:Rumbas"
|
362
|
+
:"@xsi:type" => "tns:Rumbas",
|
363
|
+
:"@level" => "80"
|
354
364
|
},
|
355
365
|
:"@xsi:type" => "tns:Value"
|
356
366
|
},
|
357
367
|
{
|
358
368
|
:rumbas => {
|
359
369
|
:zombies => "2",
|
360
|
-
:"@xsi:type" => "tns:Rumbas"
|
370
|
+
:"@xsi:type" => "tns:Rumbas",
|
371
|
+
:@level => "90",
|
361
372
|
},
|
362
373
|
:"@xsi:type"=>"tns:Value"
|
363
374
|
}
|
364
375
|
]
|
365
|
-
}
|
376
|
+
})
|
366
377
|
end
|
367
378
|
|
368
379
|
context "with arrays missing" do
|
@@ -375,7 +386,7 @@ describe WashOut do
|
|
375
386
|
end
|
376
387
|
end
|
377
388
|
|
378
|
-
savon(:rocknroll)[:rocknroll_response].
|
389
|
+
expect(savon(:rocknroll)[:rocknroll_response]).to be nil
|
379
390
|
end
|
380
391
|
|
381
392
|
it "respond with complext definition" do
|
@@ -387,7 +398,7 @@ describe WashOut do
|
|
387
398
|
end
|
388
399
|
end
|
389
400
|
|
390
|
-
savon(:rocknroll)[:rocknroll_response].
|
401
|
+
expect(savon(:rocknroll)[:rocknroll_response]).to be nil
|
391
402
|
end
|
392
403
|
|
393
404
|
it "respond with nested simple definition" do
|
@@ -399,8 +410,10 @@ describe WashOut do
|
|
399
410
|
end
|
400
411
|
end
|
401
412
|
|
402
|
-
savon(:rocknroll)[:rocknroll_response][:my_value].
|
403
|
-
|
413
|
+
expect(savon(:rocknroll)[:rocknroll_response][:my_value]).
|
414
|
+
to eq({
|
415
|
+
:"@xsi:type" => "tns:MyValue"
|
416
|
+
})
|
404
417
|
end
|
405
418
|
|
406
419
|
it "handles incomplete array response" do
|
@@ -422,13 +435,13 @@ describe WashOut do
|
|
422
435
|
mock_controller do
|
423
436
|
soap_action "true", :args => :boolean, :return => :nil
|
424
437
|
def true
|
425
|
-
params[:value].
|
438
|
+
expect(params[:value]).to be true
|
426
439
|
render :soap => nil
|
427
440
|
end
|
428
441
|
|
429
442
|
soap_action "false", :args => :boolean, :return => :nil
|
430
443
|
def false
|
431
|
-
params[:value].
|
444
|
+
expect(params[:value]).to be false
|
432
445
|
render :soap => nil
|
433
446
|
end
|
434
447
|
end
|
@@ -443,26 +456,26 @@ describe WashOut do
|
|
443
456
|
mock_controller do
|
444
457
|
soap_action "date", :args => :date, :return => :nil
|
445
458
|
def date
|
446
|
-
params[:value].
|
459
|
+
expect(params[:value]).to eq Date.parse('2000-12-30') unless params[:value].blank?
|
447
460
|
render :soap => nil
|
448
461
|
end
|
449
462
|
end
|
450
463
|
|
451
464
|
savon(:date, :value => '2000-12-30')
|
452
|
-
|
465
|
+
expect { savon(:date) }.not_to raise_exception
|
453
466
|
end
|
454
467
|
|
455
468
|
it "recognize base64Binary" do
|
456
469
|
mock_controller do
|
457
470
|
soap_action "base64", :args => :base64Binary, :return => :nil
|
458
471
|
def base64
|
459
|
-
params[:value].
|
472
|
+
expect(params[:value]).to eq('test') unless params[:value].blank?
|
460
473
|
render :soap => nil
|
461
474
|
end
|
462
475
|
end
|
463
476
|
|
464
477
|
savon(:base64, :value => Base64.encode64('test'))
|
465
|
-
|
478
|
+
expect { savon(:base64) }.not_to raise_exception
|
466
479
|
end
|
467
480
|
end
|
468
481
|
|
@@ -477,9 +490,9 @@ describe WashOut do
|
|
477
490
|
end
|
478
491
|
end
|
479
492
|
|
480
|
-
|
493
|
+
expect {
|
481
494
|
savon(:duty, :bad => 42, :good => nil)
|
482
|
-
}.
|
495
|
+
}.to raise_exception(Savon::SOAPFault)
|
483
496
|
end
|
484
497
|
|
485
498
|
it "raise for date in incorrect format" do
|
@@ -489,22 +502,22 @@ describe WashOut do
|
|
489
502
|
render :soap => nil
|
490
503
|
end
|
491
504
|
end
|
492
|
-
|
505
|
+
expect {
|
493
506
|
savon(:date, :value => 'incorrect format')
|
494
|
-
}.
|
507
|
+
}.to raise_exception(Savon::SOAPFault)
|
495
508
|
end
|
496
509
|
|
497
510
|
it "raise to report SOAP errors" do
|
498
511
|
mock_controller do
|
499
512
|
soap_action "error", :args => { :need_error => :boolean }, :return => nil
|
500
513
|
def error
|
501
|
-
raise
|
514
|
+
raise self.class.const_get(:SOAPError), "you wanted one" if params[:need_error]
|
502
515
|
render :soap => nil
|
503
516
|
end
|
504
517
|
end
|
505
518
|
|
506
|
-
|
507
|
-
|
519
|
+
expect { savon(:error, :need_error => false) }.not_to raise_exception
|
520
|
+
expect { savon(:error, :need_error => true) }.to raise_exception(Savon::SOAPFault)
|
508
521
|
end
|
509
522
|
|
510
523
|
it "misses basic exceptions" do
|
@@ -516,8 +529,8 @@ describe WashOut do
|
|
516
529
|
end
|
517
530
|
end
|
518
531
|
|
519
|
-
|
520
|
-
|
532
|
+
expect { savon(:error, :need_error => false) }.not_to raise_exception
|
533
|
+
expect { savon(:error, :need_error => true) }.to raise_exception(Exception)
|
521
534
|
end
|
522
535
|
|
523
536
|
it "raise for manual throws" do
|
@@ -528,7 +541,7 @@ describe WashOut do
|
|
528
541
|
end
|
529
542
|
end
|
530
543
|
|
531
|
-
|
544
|
+
expect { savon(:error) }.to raise_exception(Savon::SOAPFault)
|
532
545
|
end
|
533
546
|
|
534
547
|
it "raise when response structure mismatches" do
|
@@ -561,24 +574,27 @@ describe WashOut do
|
|
561
574
|
end
|
562
575
|
end
|
563
576
|
|
564
|
-
|
565
|
-
WashOut::ProgrammerError,
|
577
|
+
expect { savon(:bad) }.to raise_exception(
|
578
|
+
WashOut::Dispatcher::ProgrammerError,
|
566
579
|
/SOAP response .*wyldness.*Array.*Hash.*stallion/
|
567
580
|
)
|
568
581
|
|
569
|
-
|
570
|
-
WashOut::ProgrammerError,
|
582
|
+
expect { savon(:bad2) }.to raise_exception(
|
583
|
+
WashOut::Dispatcher::ProgrammerError,
|
571
584
|
/SOAP response .*oops.*String.*telephone_booths.*Array/
|
572
585
|
)
|
573
586
|
end
|
574
587
|
end
|
575
588
|
|
576
589
|
context "deprecates" do
|
577
|
-
|
590
|
+
# This test uses deprecated rspec expectations
|
591
|
+
# and it's not clear how to rewrite it.
|
592
|
+
xit "old syntax" do
|
578
593
|
# save rspec context check
|
579
594
|
raise_runtime_exception = raise_exception(RuntimeError)
|
580
595
|
|
581
596
|
mock_controller do
|
597
|
+
|
582
598
|
lambda {
|
583
599
|
soap_action "rumba",
|
584
600
|
:args => :integer,
|
@@ -601,8 +617,7 @@ describe WashOut do
|
|
601
617
|
end
|
602
618
|
end
|
603
619
|
|
604
|
-
savon(name.underscore.to_sym)["#{name.underscore}_response".to_sym][:value].
|
605
|
-
should == "forty two"
|
620
|
+
expect(savon(name.underscore.to_sym)["#{name.underscore}_response".to_sym][:value]).to eq "forty two"
|
606
621
|
end
|
607
622
|
|
608
623
|
it "respects :response_tag option" do
|
@@ -613,14 +628,14 @@ describe WashOut do
|
|
613
628
|
end
|
614
629
|
end
|
615
630
|
|
616
|
-
savon(:specific).
|
631
|
+
expect(savon(:specific)).to eq({:test => {:value=>"test"}})
|
617
632
|
end
|
618
633
|
|
619
634
|
it "handles snakecase option properly" do
|
620
635
|
mock_controller(snakecase_input: false, camelize_wsdl: false) do
|
621
636
|
soap_action "rocknroll", :args => {:ZOMG => :string}, :return => nil
|
622
637
|
def rocknroll
|
623
|
-
params["ZOMG"].
|
638
|
+
expect(params["ZOMG"]).to eq "yam!"
|
624
639
|
render :soap => nil
|
625
640
|
end
|
626
641
|
end
|
@@ -636,8 +651,8 @@ describe WashOut do
|
|
636
651
|
mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
|
637
652
|
soap_action "checkToken", :args => :integer, :return => nil, :to => 'check_token'
|
638
653
|
def check_token
|
639
|
-
request.env['WSSE_TOKEN']['username'].
|
640
|
-
request.env['WSSE_TOKEN']['password'].
|
654
|
+
expect(request.env['WSSE_TOKEN']['username']).to eq "gorilla"
|
655
|
+
expect(request.env['WSSE_TOKEN']['password']).to eq "secret"
|
641
656
|
render :soap => nil
|
642
657
|
end
|
643
658
|
end
|
@@ -656,20 +671,20 @@ describe WashOut do
|
|
656
671
|
end
|
657
672
|
|
658
673
|
# correct auth
|
659
|
-
|
660
|
-
|
674
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
675
|
+
not_to raise_exception
|
661
676
|
|
662
677
|
# wrong user
|
663
|
-
|
664
|
-
|
678
|
+
expect { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret" } }.
|
679
|
+
to raise_exception(Savon::SOAPFault)
|
665
680
|
|
666
681
|
# wrong pass
|
667
|
-
|
668
|
-
|
682
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry" } }.
|
683
|
+
to raise_exception(Savon::SOAPFault)
|
669
684
|
|
670
685
|
# no auth
|
671
|
-
|
672
|
-
|
686
|
+
expect { savon(:check_auth, 42) }.
|
687
|
+
to raise_exception(Savon::SOAPFault)
|
673
688
|
end
|
674
689
|
|
675
690
|
it "handles PasswordDigest auth" do
|
@@ -681,20 +696,57 @@ describe WashOut do
|
|
681
696
|
end
|
682
697
|
|
683
698
|
# correct auth
|
684
|
-
|
685
|
-
|
699
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
700
|
+
not_to raise_exception
|
701
|
+
|
702
|
+
# correct digest auth
|
703
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret", :digest } }.
|
704
|
+
not_to raise_exception
|
705
|
+
|
706
|
+
# wrong user
|
707
|
+
expect { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret", :digest } }.
|
708
|
+
to raise_exception(Savon::SOAPFault)
|
709
|
+
|
710
|
+
# wrong pass
|
711
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry", :digest } }.
|
712
|
+
to raise_exception(Savon::SOAPFault)
|
713
|
+
|
714
|
+
# no auth
|
715
|
+
expect { savon(:check_auth, 42) }.
|
716
|
+
to raise_exception(Savon::SOAPFault)
|
717
|
+
end
|
718
|
+
|
719
|
+
it "handles auth callback" do
|
720
|
+
mock_controller(
|
721
|
+
wsse_auth_callback: lambda {|user, password|
|
722
|
+
return user == "gorilla" && password == "secret"
|
723
|
+
}
|
724
|
+
) do
|
725
|
+
soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
|
726
|
+
def check_auth
|
727
|
+
render :soap => (params[:value] == 42)
|
728
|
+
end
|
729
|
+
end
|
730
|
+
|
731
|
+
# correct auth
|
732
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
733
|
+
not_to raise_exception
|
734
|
+
|
735
|
+
# correct digest auth
|
736
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret", :digest } }.
|
737
|
+
to raise_exception(Savon::SOAPFault)
|
686
738
|
|
687
739
|
# wrong user
|
688
|
-
|
689
|
-
|
740
|
+
expect { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret", :digest } }.
|
741
|
+
to raise_exception(Savon::SOAPFault)
|
690
742
|
|
691
743
|
# wrong pass
|
692
|
-
|
693
|
-
|
744
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry", :digest } }.
|
745
|
+
to raise_exception(Savon::SOAPFault)
|
694
746
|
|
695
747
|
# no auth
|
696
|
-
|
697
|
-
|
748
|
+
expect { savon(:check_auth, 42) }.
|
749
|
+
to raise_exception(Savon::SOAPFault)
|
698
750
|
end
|
699
751
|
|
700
752
|
end
|