wash_out_fork 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +36 -0
- data/Appraisals +25 -0
- data/CHANGELOG.md +102 -0
- data/Gemfile +17 -0
- data/Guardfile +12 -0
- data/LICENSE +22 -0
- data/README.md +242 -0
- data/Rakefile +25 -0
- data/app/helpers/wash_out_fork_helper.rb +110 -0
- data/app/views/wash_out_fork/document/error.builder +9 -0
- data/app/views/wash_out_fork/document/response.builder +8 -0
- data/app/views/wash_out_fork/document/wsdl.builder +68 -0
- data/app/views/wash_out_fork/rpc/error.builder +10 -0
- data/app/views/wash_out_fork/rpc/response.builder +9 -0
- data/app/views/wash_out_fork/rpc/wsdl.builder +68 -0
- data/gemfiles/rails_3.2.13.gemfile +21 -0
- data/gemfiles/rails_4.0.0.gemfile +20 -0
- data/gemfiles/rails_4.1.0.gemfile +20 -0
- data/gemfiles/rails_4.2.0.gemfile +20 -0
- data/gemfiles/rails_5.0.0.beta2.gemfile +19 -0
- data/gemfiles/rails_5.0.0.gemfile +19 -0
- data/init.rb +1 -0
- data/lib/wash_out_fork.rb +60 -0
- data/lib/wash_out_fork/configurable.rb +41 -0
- data/lib/wash_out_fork/dispatcher.rb +232 -0
- data/lib/wash_out_fork/engine.rb +12 -0
- data/lib/wash_out_fork/middleware.rb +41 -0
- data/lib/wash_out_fork/model.rb +29 -0
- data/lib/wash_out_fork/param.rb +200 -0
- data/lib/wash_out_fork/router.rb +131 -0
- data/lib/wash_out_fork/soap.rb +48 -0
- data/lib/wash_out_fork/soap_config.rb +93 -0
- data/lib/wash_out_fork/type.rb +29 -0
- data/lib/wash_out_fork/version.rb +3 -0
- data/lib/wash_out_fork/wsse.rb +101 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +51 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +23 -0
- data/spec/dummy/config/environments/test.rb +30 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +8 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/fixtures/nested_refs_to_arrays.xml +19 -0
- data/spec/fixtures/ref_to_one_array.xml +11 -0
- data/spec/fixtures/refs_to_arrays.xml +16 -0
- data/spec/lib/wash_out/dispatcher_spec.rb +206 -0
- data/spec/lib/wash_out/middleware_spec.rb +33 -0
- data/spec/lib/wash_out/param_spec.rb +94 -0
- data/spec/lib/wash_out/router_spec.rb +50 -0
- data/spec/lib/wash_out/type_spec.rb +41 -0
- data/spec/lib/wash_out_spec.rb +797 -0
- data/spec/spec_helper.rb +88 -0
- data/wash_out_fork.gemspec +20 -0
- metadata +130 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'wash_out_fork/middleware'
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
describe WashOutFork::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
|
+
WashOutFork::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 = WashOutFork::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 = WashOutFork::Middleware.raise_or_render_rexml_parse_error err, env
|
31
|
+
expect(result[0]).to eq 400
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#encoding:utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe WashOutFork::Param do
|
6
|
+
|
7
|
+
context "custom types" do
|
8
|
+
|
9
|
+
class Abraka1 < WashOutFork::Type
|
10
|
+
map(
|
11
|
+
:test => :string
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
class Abraka2 < WashOutFork::Type
|
16
|
+
type_name 'test'
|
17
|
+
map :foo => Abraka1
|
18
|
+
end
|
19
|
+
|
20
|
+
it "loads custom_types" do
|
21
|
+
soap_config = WashOutFork::SoapConfig.new({ camelize_wsdl: false })
|
22
|
+
map = WashOutFork::Param.parse_def soap_config, Abraka2
|
23
|
+
|
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'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "respects camelization setting" do
|
30
|
+
soap_config = WashOutFork::SoapConfig.new({ camelize_wsdl: true })
|
31
|
+
|
32
|
+
map = WashOutFork::Param.parse_def soap_config, Abraka2
|
33
|
+
|
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'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should accept nested empty arrays" do
|
41
|
+
soap_config = WashOutFork::SoapConfig.new({ camelize_wsdl: false })
|
42
|
+
map = WashOutFork::Param.parse_def(soap_config, {:nested => {:some_attr => :string, :empty => [:integer] }} )
|
43
|
+
expect(map[0].load( {:nested => nil}, :nested)).to eq({})
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "booleans" do
|
47
|
+
let(:soap_config) { WashOutFork::SoapConfig.new({ camelize_wsdl: false }) }
|
48
|
+
# following http://www.w3.org/TR/xmlschema-2/#boolean, only true, false, 0 and 1 are allowed.
|
49
|
+
# Nori maps the strings true and false to TrueClass and FalseClass, but not 0 and 1.
|
50
|
+
let(:map) { WashOutFork::Param.parse_def(soap_config, :value => :boolean) }
|
51
|
+
|
52
|
+
it "should accept 'true' and '1'" do
|
53
|
+
expect(map[0].load({:value => true}, :value)).to be true
|
54
|
+
expect(map[0].load({:value => "1"}, :value)).to be true
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should accept 'false' and '0'" do
|
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) { WashOutFork::SoapConfig.new({ camelize_wsdl: false }) }
|
65
|
+
let(:map) { WashOutFork::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 = WashOutFork::SoapConfig.new({})
|
79
|
+
type = :foo
|
80
|
+
multiplied = "of course"
|
81
|
+
|
82
|
+
param = WashOutFork::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
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'wash_out_fork/router'
|
3
|
+
|
4
|
+
describe WashOutFork::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 = WashOutFork::Router.new('Route::Space::Api').call env
|
15
|
+
|
16
|
+
expect(result[0]).to eq(500)
|
17
|
+
expect(result[1]['Content-Type']).to eq('text/xml; charset=utf-8')
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_soap_params_from_xml(filename)
|
21
|
+
xml = File.read(File.expand_path("../../../fixtures/#{filename}", __FILE__))
|
22
|
+
env = {'rack.input' => StringIO.new(xml)}
|
23
|
+
|
24
|
+
router = WashOutFork::Router.new('')
|
25
|
+
controller = double("controller", soap_config: WashOutFork::SoapConfig.new)
|
26
|
+
allow(router).to receive(:controller).and_return(controller)
|
27
|
+
|
28
|
+
router.parse_soap_parameters(env)[:Envelope][:Body]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns refs to arrays correctly" do
|
32
|
+
body = parse_soap_params_from_xml('ref_to_one_array.xml')
|
33
|
+
|
34
|
+
expect(body[:list][:Item]).to eq(["1", "2"])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns refs to multiple arrays correctly" do
|
38
|
+
body = parse_soap_params_from_xml('refs_to_arrays.xml')
|
39
|
+
|
40
|
+
expect(body[:first_list][:Item]).to eq(["1", "2"])
|
41
|
+
expect(body[:second_list][:Item]).to eq(["11", "22"])
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns nested refs to multiple arrays correctly" do
|
45
|
+
body = parse_soap_params_from_xml('nested_refs_to_arrays.xml')
|
46
|
+
|
47
|
+
expect(body[:parent][:first_list][:Item]).to eq(["1", "2"])
|
48
|
+
expect(body[:parent][:second_list][:Item]).to eq(["11", "22"])
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#encoding:utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe WashOutFork::Type do
|
6
|
+
|
7
|
+
it "defines custom type" do
|
8
|
+
|
9
|
+
class Abraka1 < WashOutFork::Type
|
10
|
+
map :test => :string
|
11
|
+
end
|
12
|
+
|
13
|
+
class Abraka2 < WashOutFork::Type
|
14
|
+
type_name 'test'
|
15
|
+
map :foo => Abraka1
|
16
|
+
end
|
17
|
+
|
18
|
+
expect(Abraka1.wash_out_fork_param_name).to eq 'abraka1'
|
19
|
+
expect(Abraka1.wash_out_fork_param_map).to eq({:test => :string})
|
20
|
+
|
21
|
+
expect(Abraka2.wash_out_fork_param_name).to eq 'test'
|
22
|
+
expect(Abraka2.wash_out_fork_param_map).to eq({:foo => Abraka1})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "allows arrays inside custom types" do
|
26
|
+
class Abraka1 < WashOutFork::Type
|
27
|
+
map :test => :string
|
28
|
+
end
|
29
|
+
class Abraka2 < WashOutFork::Type
|
30
|
+
type_name 'test'
|
31
|
+
map :foo => [:bar => Abraka1]
|
32
|
+
end
|
33
|
+
|
34
|
+
expect(Abraka1.wash_out_fork_param_name).to eq 'abraka1'
|
35
|
+
expect(Abraka1.wash_out_fork_param_map).to eq({:test => :string})
|
36
|
+
|
37
|
+
expect(Abraka2.wash_out_fork_param_name).to eq 'test'
|
38
|
+
expect(Abraka2.wash_out_fork_param_map).to eq({:foo => [:bar => Abraka1]})
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,797 @@
|
|
1
|
+
#encoding:utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe WashOutFork do
|
6
|
+
|
7
|
+
let :nori do
|
8
|
+
Nori.new(
|
9
|
+
:strip_namespaces => true,
|
10
|
+
:advanced_typecasting => true,
|
11
|
+
:convert_tags_to => lambda {|x| x.snakecase.to_sym}
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def savon(method, message={}, hashify=true, &block)
|
16
|
+
message = {:value => message} unless message.is_a?(Hash)
|
17
|
+
|
18
|
+
savon = Savon::Client.new(:log => false, :wsdl => 'http://app/route/api/wsdl', &block)
|
19
|
+
result = savon.call(method, :message => message)
|
20
|
+
result = result.to_hash if hashify
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def savon!(method, message={}, &block)
|
25
|
+
message = {:value => message} unless message.is_a?(Hash)
|
26
|
+
|
27
|
+
savon = Savon::Client.new(:log => true, :wsdl => 'http://app/route/api/wsdl', &block)
|
28
|
+
savon.call(method, :message => message).to_hash
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "Module" do
|
32
|
+
it "includes" do
|
33
|
+
expect {
|
34
|
+
mock_controller do
|
35
|
+
# nothing
|
36
|
+
end
|
37
|
+
}.not_to raise_exception
|
38
|
+
end
|
39
|
+
|
40
|
+
it "allows definition of a simple action" do
|
41
|
+
expect {
|
42
|
+
mock_controller do
|
43
|
+
soap_action "answer", :args => nil, :return => :integer
|
44
|
+
end
|
45
|
+
}.not_to raise_exception
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "WSDL" do
|
50
|
+
let :wsdl do
|
51
|
+
mock_controller do
|
52
|
+
soap_action :result, :args => nil, :return => :int
|
53
|
+
|
54
|
+
soap_action "getArea", :args => {
|
55
|
+
:circle => [{
|
56
|
+
:center => { :x => [:integer], :y => :integer },
|
57
|
+
:radius => :double
|
58
|
+
}]},
|
59
|
+
:return => { :area => :double }
|
60
|
+
soap_action "rocky", :args => { :circle1 => { :x => :integer } },
|
61
|
+
:return => { :circle2 => { :y => :integer } }
|
62
|
+
end
|
63
|
+
|
64
|
+
HTTPI.get("http://app/route/api/wsdl").body
|
65
|
+
end
|
66
|
+
|
67
|
+
let :xml do
|
68
|
+
nori.parse wsdl
|
69
|
+
end
|
70
|
+
|
71
|
+
it "lists operations" do
|
72
|
+
operations = xml[:definitions][:binding][:operation]
|
73
|
+
expect(operations).to be_a_kind_of(Array)
|
74
|
+
|
75
|
+
expect(operations.map{|e| e[:'@name']}.sort).to eq ['Result', 'getArea', 'rocky'].sort
|
76
|
+
end
|
77
|
+
|
78
|
+
it "defines complex types" do
|
79
|
+
expect(wsdl.include?('<xsd:complexType name="Circle1">')).to be true
|
80
|
+
end
|
81
|
+
|
82
|
+
it "defines arrays" do
|
83
|
+
x = xml[:definitions][:types][:schema][:complex_type].
|
84
|
+
find{|x| x[:'@name'] == 'Center'}[:sequence][:element].
|
85
|
+
find{|x| x[:'@name'] == 'X'}
|
86
|
+
|
87
|
+
expect(x[:'@min_occurs']).to eq "0"
|
88
|
+
expect(x[:'@max_occurs']).to eq "unbounded"
|
89
|
+
expect(x[:'@nillable']).to eq "true"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "adds nillable to all type definitions" do
|
93
|
+
types = xml[:definitions][:message].map { |d| d[:part] }.compact
|
94
|
+
nillable = types.map { |t| t[:"@xsi:nillable"] }
|
95
|
+
expect(nillable.all? { |v| v == "true" }).to be true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "Dispatcher" do
|
100
|
+
|
101
|
+
context "simple actions" do
|
102
|
+
it "accepts requests with no HTTP header" do
|
103
|
+
mock_controller do
|
104
|
+
soap_action "answer", :args => nil, :return => :int
|
105
|
+
def answer
|
106
|
+
render :soap => "42"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
request = <<-XML
|
111
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
112
|
+
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="false" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
|
113
|
+
<env:Body>
|
114
|
+
<tns:answer>
|
115
|
+
<value>42</value>
|
116
|
+
</tns:answer>
|
117
|
+
</env:Body>
|
118
|
+
</env:Envelope>
|
119
|
+
XML
|
120
|
+
|
121
|
+
expect(HTTPI.post("http://app/route/api/action", request).body).to eq <<-XML
|
122
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
123
|
+
<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">
|
124
|
+
<soap:Body>
|
125
|
+
<tns:answerResponse>
|
126
|
+
<Value xsi:type="xsd:int">42</Value>
|
127
|
+
</tns:answerResponse>
|
128
|
+
</soap:Body>
|
129
|
+
</soap:Envelope>
|
130
|
+
XML
|
131
|
+
end
|
132
|
+
|
133
|
+
it "accept no parameters" do
|
134
|
+
mock_controller do
|
135
|
+
soap_action "answer", :args => nil, :return => :int
|
136
|
+
def answer
|
137
|
+
render :soap => "42"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
expect(savon(:answer)[:answer_response][:value]).
|
142
|
+
to eq "42"
|
143
|
+
end
|
144
|
+
|
145
|
+
it "accept insufficient parameters" do
|
146
|
+
mock_controller do
|
147
|
+
soap_action "answer", :args => {:a => :integer}, :return => :integer
|
148
|
+
def answer
|
149
|
+
render :soap => "42"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
expect(savon(:answer)[:answer_response][:value]).
|
154
|
+
to eq "42"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "shows date in correct format" do
|
158
|
+
mock_controller do
|
159
|
+
soap_action "answer", :args => {}, :return => {:a => :date}
|
160
|
+
def answer
|
161
|
+
render :soap => {:a => DateTime.new(2000, 1, 1)}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
result = Hash.from_xml savon(:answer, {}, false).http.body
|
165
|
+
expect(result['Envelope']['Body']['answerResponse']['A']).to eq '2000-01-01T00:00:00+00:00'
|
166
|
+
end
|
167
|
+
|
168
|
+
it "accept empty parameter" do
|
169
|
+
mock_controller do
|
170
|
+
soap_action "answer", :args => {:a => :string}, :return => {:a => :string}
|
171
|
+
def answer
|
172
|
+
render :soap => {:a => params[:a]}
|
173
|
+
end
|
174
|
+
end
|
175
|
+
expect(savon(:answer, :a => '')[:answer_response][:a]).to be_nil
|
176
|
+
end
|
177
|
+
|
178
|
+
it "accept one parameter" do
|
179
|
+
mock_controller do
|
180
|
+
soap_action "checkAnswer", :args => :integer, :return => :boolean, :to => 'check_answer'
|
181
|
+
def check_answer
|
182
|
+
render :soap => (params[:value] == 42)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
expect(savon(:check_answer, 42)[:check_answer_response][:value]).to be true
|
187
|
+
expect(savon(:check_answer, 13)[:check_answer_response][:value]).to be false
|
188
|
+
end
|
189
|
+
|
190
|
+
it "accept two parameters" do
|
191
|
+
mock_controller do
|
192
|
+
soap_action "funky", :args => { :a => :integer, :b => :string }, :return => :string
|
193
|
+
def funky
|
194
|
+
render :soap => ((params[:a] * 10).to_s + params[:b])
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
expect(savon(:funky, :a => 42, :b => 'k')[:funky_response][:value]).to eq '420k'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "complex actions" do
|
203
|
+
it "accept nested structures" do
|
204
|
+
mock_controller do
|
205
|
+
soap_action "getArea", :args => { :circle => { :center => { :x => :integer,
|
206
|
+
:y => :integer },
|
207
|
+
:radius => :double } },
|
208
|
+
:return => { :area => :double,
|
209
|
+
:distance_from_o => :double },
|
210
|
+
:to => :get_area
|
211
|
+
def get_area
|
212
|
+
circle = params[:circle]
|
213
|
+
render :soap => { :area => Math::PI * circle[:radius] ** 2,
|
214
|
+
:distance_from_o => Math.sqrt(circle[:center][:x] ** 2 + circle[:center][:y] ** 2) }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
message = { :circle => { :center => { :x => 3, :y => 4 },
|
219
|
+
:radius => 5 } }
|
220
|
+
|
221
|
+
expect(savon(:get_area, message)[:get_area_response]).
|
222
|
+
to eq ({ :area => (Math::PI * 25).to_s, :distance_from_o => (5.0).to_s })
|
223
|
+
end
|
224
|
+
|
225
|
+
it "accept arrays" do
|
226
|
+
mock_controller do
|
227
|
+
soap_action "rumba",
|
228
|
+
:args => {
|
229
|
+
:rumbas => [:integer]
|
230
|
+
},
|
231
|
+
:return => nil
|
232
|
+
def rumba
|
233
|
+
expect(params).to eq({"rumbas" => [1, 2, 3]})
|
234
|
+
render :soap => nil
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
savon(:rumba, :rumbas => [1, 2, 3])
|
239
|
+
end
|
240
|
+
|
241
|
+
it "accept empty arrays" do
|
242
|
+
mock_controller do
|
243
|
+
soap_action "rumba",
|
244
|
+
:args => {
|
245
|
+
:my_array => [:integer]
|
246
|
+
},
|
247
|
+
:return => nil
|
248
|
+
def rumba
|
249
|
+
expect(params).to eq({})
|
250
|
+
render :soap => nil
|
251
|
+
end
|
252
|
+
end
|
253
|
+
savon(:rumba, :empty => [])
|
254
|
+
end
|
255
|
+
|
256
|
+
it "accept nested empty arrays" do
|
257
|
+
mock_controller do
|
258
|
+
soap_action "rumba",
|
259
|
+
:args => {
|
260
|
+
:nested => {:my_array => [:integer] }
|
261
|
+
},
|
262
|
+
:return => nil
|
263
|
+
def rumba
|
264
|
+
expect(params).to eq({"nested" => {}})
|
265
|
+
render :soap => nil
|
266
|
+
end
|
267
|
+
end
|
268
|
+
savon(:rumba, :nested => {:my_array => []})
|
269
|
+
end
|
270
|
+
|
271
|
+
it "accept nested structures inside arrays" do
|
272
|
+
mock_controller do
|
273
|
+
soap_action "rumba",
|
274
|
+
:args => {
|
275
|
+
:rumbas => [ {
|
276
|
+
:zombies => :string,
|
277
|
+
:puppies => :string
|
278
|
+
} ]
|
279
|
+
},
|
280
|
+
:return => nil
|
281
|
+
def rumba
|
282
|
+
expect(params).to eq({
|
283
|
+
"rumbas" => [
|
284
|
+
{"zombies" => 'suck', "puppies" => 'rock'},
|
285
|
+
{"zombies" => 'slow', "puppies" => 'fast'}
|
286
|
+
]
|
287
|
+
})
|
288
|
+
render :soap => nil
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
savon :rumba, :rumbas => [
|
293
|
+
{:zombies => 'suck', :puppies => 'rock'},
|
294
|
+
{:zombies => 'slow', :puppies => 'fast'}
|
295
|
+
]
|
296
|
+
end
|
297
|
+
|
298
|
+
it "respond with nested structures" do
|
299
|
+
mock_controller do
|
300
|
+
soap_action "gogogo",
|
301
|
+
:args => nil,
|
302
|
+
:return => {
|
303
|
+
:zoo => :string,
|
304
|
+
:boo => { :moo => :string, :doo => :string }
|
305
|
+
}
|
306
|
+
def gogogo
|
307
|
+
render :soap => {
|
308
|
+
:zoo => 'zoo',
|
309
|
+
:boo => { :moo => 'moo', :doo => 'doo' }
|
310
|
+
}
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
expect(savon(:gogogo)[:gogogo_response]).
|
315
|
+
to eq({
|
316
|
+
:zoo=>"zoo",
|
317
|
+
:boo=>{
|
318
|
+
:moo=>"moo",
|
319
|
+
:doo=>"doo",
|
320
|
+
:"@xsi:type"=>"tns:Boo"
|
321
|
+
}
|
322
|
+
})
|
323
|
+
end
|
324
|
+
|
325
|
+
it "respond with arrays" do
|
326
|
+
mock_controller do
|
327
|
+
soap_action "rumba",
|
328
|
+
:args => nil,
|
329
|
+
:return => [:integer]
|
330
|
+
def rumba
|
331
|
+
render :soap => [1, 2, 3]
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
expect(savon(:rumba)[:rumba_response]).to eq({
|
336
|
+
:value => ["1", "2", "3"]
|
337
|
+
})
|
338
|
+
end
|
339
|
+
|
340
|
+
it "respond with complex structures inside arrays" do
|
341
|
+
mock_controller do
|
342
|
+
soap_action "rumba",
|
343
|
+
:args => nil,
|
344
|
+
:return => {
|
345
|
+
:rumbas => [{:@level => :integer, :zombies => :string, :puppies => :string}]
|
346
|
+
}
|
347
|
+
def rumba
|
348
|
+
render :soap =>
|
349
|
+
{:rumbas => [
|
350
|
+
{:@level => 80, :zombies => "suck1", :puppies => "rock1" },
|
351
|
+
{:zombies => "suck2", :puppies => "rock2" }
|
352
|
+
]
|
353
|
+
}
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
expect(savon(:rumba)[:rumba_response]).to eq({
|
358
|
+
:rumbas => [
|
359
|
+
{:zombies => "suck1",:puppies => "rock1", :"@xsi:type"=>"tns:Rumbas", :@level => "80"},
|
360
|
+
{:zombies => "suck2", :puppies => "rock2", :"@xsi:type"=>"tns:Rumbas" }
|
361
|
+
]
|
362
|
+
})
|
363
|
+
end
|
364
|
+
|
365
|
+
it "respond with structs in structs in arrays" do
|
366
|
+
mock_controller do
|
367
|
+
soap_action "rumba",
|
368
|
+
:args => nil,
|
369
|
+
:return => [{:rumbas => {:@level => :integer, :zombies => :integer}}]
|
370
|
+
|
371
|
+
def rumba
|
372
|
+
render :soap => [{:rumbas => {:@level => 80, :zombies => 100000}}, {:rumbas => {:@level => 90, :zombies => 2}}]
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
expect(savon(:rumba)[:rumba_response]).to eq({
|
377
|
+
:value => [
|
378
|
+
{
|
379
|
+
:rumbas => {
|
380
|
+
:zombies => "100000",
|
381
|
+
:"@xsi:type" => "tns:Rumbas",
|
382
|
+
:"@level" => "80"
|
383
|
+
},
|
384
|
+
:"@xsi:type" => "tns:Value"
|
385
|
+
},
|
386
|
+
{
|
387
|
+
:rumbas => {
|
388
|
+
:zombies => "2",
|
389
|
+
:"@xsi:type" => "tns:Rumbas",
|
390
|
+
:@level => "90",
|
391
|
+
},
|
392
|
+
:"@xsi:type"=>"tns:Value"
|
393
|
+
}
|
394
|
+
]
|
395
|
+
})
|
396
|
+
end
|
397
|
+
|
398
|
+
context "with arrays missing" do
|
399
|
+
it "respond with simple definition" do
|
400
|
+
mock_controller do
|
401
|
+
soap_action "rocknroll",
|
402
|
+
:args => nil, :return => { :my_value => [:integer] }
|
403
|
+
def rocknroll
|
404
|
+
render :soap => {}
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
expect(savon(:rocknroll)[:rocknroll_response]).to be nil
|
409
|
+
end
|
410
|
+
|
411
|
+
it "respond with complext definition" do
|
412
|
+
mock_controller do
|
413
|
+
soap_action "rocknroll",
|
414
|
+
:args => nil, :return => { :my_value => [{ :value => :integer }] }
|
415
|
+
def rocknroll
|
416
|
+
render :soap => {}
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
expect(savon(:rocknroll)[:rocknroll_response]).to be nil
|
421
|
+
end
|
422
|
+
|
423
|
+
it "respond with nested simple definition" do
|
424
|
+
mock_controller do
|
425
|
+
soap_action "rocknroll",
|
426
|
+
:args => nil, :return => { :my_value => { :my_array => [{ :value => :integer }] } }
|
427
|
+
def rocknroll
|
428
|
+
render :soap => {}
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
expect(savon(:rocknroll)[:rocknroll_response][:my_value]).to be_nil
|
433
|
+
end
|
434
|
+
|
435
|
+
it "responds with missing parameters" do
|
436
|
+
mock_controller do
|
437
|
+
soap_action "rocknroll",
|
438
|
+
args: nil,
|
439
|
+
return: {my_value: :integer}
|
440
|
+
def rocknroll
|
441
|
+
render soap: {my_value: nil}
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
expect(savon(:rocknroll)[:rocknroll_response][:my_value]).to be_nil
|
446
|
+
end
|
447
|
+
|
448
|
+
it "handles incomplete array response" do
|
449
|
+
mock_controller do
|
450
|
+
soap_action "rocknroll",
|
451
|
+
:args => nil, :return => { :my_value => [{ :value => :string }] }
|
452
|
+
def rocknroll
|
453
|
+
render :soap => { :my_value => [nil] }
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
expect{savon(:rocknroll)}.not_to raise_error
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
context "types" do
|
463
|
+
it "recognize boolean" do
|
464
|
+
mock_controller do
|
465
|
+
soap_action "true", :args => :boolean, :return => :nil
|
466
|
+
def true
|
467
|
+
expect(params[:value]).to be true
|
468
|
+
render :soap => nil
|
469
|
+
end
|
470
|
+
|
471
|
+
soap_action "false", :args => :boolean, :return => :nil
|
472
|
+
def false
|
473
|
+
expect(params[:value]).to be false
|
474
|
+
render :soap => nil
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
savon(:true, :value => "true")
|
479
|
+
savon(:true, :value => "1")
|
480
|
+
savon(:false, :value => "false")
|
481
|
+
savon(:false, :value => "0")
|
482
|
+
end
|
483
|
+
|
484
|
+
it "recognize dates" do
|
485
|
+
mock_controller do
|
486
|
+
soap_action "date", :args => :date, :return => :nil
|
487
|
+
def date
|
488
|
+
expect(params[:value]).to eq Date.parse('2000-12-30') unless params[:value].blank?
|
489
|
+
render :soap => nil
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
savon(:date, :value => '2000-12-30')
|
494
|
+
expect { savon(:date) }.not_to raise_exception
|
495
|
+
end
|
496
|
+
|
497
|
+
it "recognize base64Binary" do
|
498
|
+
mock_controller do
|
499
|
+
soap_action "base64", :args => :base64Binary, :return => :nil
|
500
|
+
def base64
|
501
|
+
expect(params[:value]).to eq('test') unless params[:value].blank?
|
502
|
+
render :soap => nil
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
savon(:base64, :value => Base64.encode64('test'))
|
507
|
+
expect { savon(:base64) }.not_to raise_exception
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
context "errors" do
|
512
|
+
it "raise for incorrect requests" do
|
513
|
+
mock_controller do
|
514
|
+
soap_action "duty",
|
515
|
+
:args => {:bad => {:a => :string, :b => :string}, :good => {:a => :string, :b => :string}},
|
516
|
+
:return => nil
|
517
|
+
def duty
|
518
|
+
render :soap => nil
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
expect {
|
523
|
+
savon(:duty, :bad => 42, :good => nil)
|
524
|
+
}.to raise_exception(Savon::SOAPFault)
|
525
|
+
end
|
526
|
+
|
527
|
+
it "raise for date in incorrect format" do
|
528
|
+
mock_controller do
|
529
|
+
soap_action "date", :args => :date, :return => :nil
|
530
|
+
def date
|
531
|
+
render :soap => nil
|
532
|
+
end
|
533
|
+
end
|
534
|
+
expect {
|
535
|
+
savon(:date, :value => 'incorrect format')
|
536
|
+
}.to raise_exception(Savon::SOAPFault)
|
537
|
+
end
|
538
|
+
|
539
|
+
it "raise to report SOAP errors" do
|
540
|
+
mock_controller do
|
541
|
+
soap_action "error", :args => { :need_error => :boolean }, :return => nil
|
542
|
+
def error
|
543
|
+
raise self.class.const_get(:SOAPError), "you wanted one" if params[:need_error]
|
544
|
+
render :soap => nil
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
expect { savon(:error, :need_error => false) }.not_to raise_exception
|
549
|
+
expect { savon(:error, :need_error => true) }.to raise_exception(Savon::SOAPFault)
|
550
|
+
end
|
551
|
+
|
552
|
+
it "misses basic exceptions" do
|
553
|
+
mock_controller do
|
554
|
+
soap_action "error", :args => { :need_error => :boolean }, :return => nil
|
555
|
+
def error
|
556
|
+
raise self.class.const_get(:Exception), "you wanted one" if params[:need_error]
|
557
|
+
render :soap => nil
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
expect { savon(:error, :need_error => false) }.not_to raise_exception
|
562
|
+
expect { savon(:error, :need_error => true) }.to raise_exception(Exception)
|
563
|
+
end
|
564
|
+
|
565
|
+
it "raise for manual throws" do
|
566
|
+
mock_controller do
|
567
|
+
soap_action "error", :args => nil, :return => nil
|
568
|
+
def error
|
569
|
+
render_soap_error "a message"
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
expect { savon(:error) }.to raise_exception(Savon::SOAPFault)
|
574
|
+
end
|
575
|
+
|
576
|
+
it "raise when response structure mismatches" do
|
577
|
+
mock_controller do
|
578
|
+
soap_action 'bad', :args => :integer, :return => {
|
579
|
+
:basic => :string,
|
580
|
+
:stallions => {
|
581
|
+
:stallion => [
|
582
|
+
:name => :string,
|
583
|
+
:wyldness => :integer,
|
584
|
+
]
|
585
|
+
},
|
586
|
+
}
|
587
|
+
def bad
|
588
|
+
render :soap => {
|
589
|
+
:basic => 'hi',
|
590
|
+
:stallions => [{:name => 'ted', :wyldness => 11}]
|
591
|
+
}
|
592
|
+
end
|
593
|
+
|
594
|
+
soap_action 'bad2', :args => :integer, :return => {
|
595
|
+
:basic => :string,
|
596
|
+
:telephone_booths => [:string]
|
597
|
+
}
|
598
|
+
def bad2
|
599
|
+
render :soap => {
|
600
|
+
:basic => 'hihi',
|
601
|
+
:telephone_booths => 'oops'
|
602
|
+
}
|
603
|
+
end
|
604
|
+
end
|
605
|
+
|
606
|
+
expect { savon(:bad) }.to raise_exception(
|
607
|
+
WashOutFork::Dispatcher::ProgrammerError,
|
608
|
+
/SOAP response .*wyldness.*Array.*Hash.*stallion/
|
609
|
+
)
|
610
|
+
|
611
|
+
expect { savon(:bad2) }.to raise_exception(
|
612
|
+
WashOutFork::Dispatcher::ProgrammerError,
|
613
|
+
/SOAP response .*oops.*String.*telephone_booths.*Array/
|
614
|
+
)
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
context "deprecates" do
|
619
|
+
# This test uses deprecated rspec expectations
|
620
|
+
# and it's not clear how to rewrite it.
|
621
|
+
xit "old syntax" do
|
622
|
+
# save rspec context check
|
623
|
+
raise_runtime_exception = raise_exception(RuntimeError)
|
624
|
+
|
625
|
+
mock_controller do
|
626
|
+
|
627
|
+
lambda {
|
628
|
+
soap_action "rumba",
|
629
|
+
:args => :integer,
|
630
|
+
:return => []
|
631
|
+
}.should raise_runtime_exception
|
632
|
+
def rumba
|
633
|
+
render :soap => nil
|
634
|
+
end
|
635
|
+
end
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
it "allows arbitrary action names" do
|
640
|
+
name = 'AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything'
|
641
|
+
|
642
|
+
mock_controller do
|
643
|
+
soap_action name, :args => nil, :return => :integer, :to => :answer
|
644
|
+
def answer
|
645
|
+
render :soap => "forty two"
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
expect(savon(name.underscore.to_sym)["#{name.underscore}_response".to_sym][:value]).to eq "forty two"
|
650
|
+
end
|
651
|
+
|
652
|
+
it "respects :response_tag option" do
|
653
|
+
mock_controller do
|
654
|
+
soap_action "specific", :response_tag => "test", :return => :string
|
655
|
+
def specific
|
656
|
+
render :soap => "test"
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
expect(savon(:specific)).to eq({:test => {:value=>"test"}})
|
661
|
+
end
|
662
|
+
|
663
|
+
it "handles snakecase option properly" do
|
664
|
+
mock_controller(snakecase_input: false, camelize_wsdl: false) do
|
665
|
+
soap_action "rocknroll", :args => {:ZOMG => :string}, :return => nil
|
666
|
+
def rocknroll
|
667
|
+
expect(params["ZOMG"]).to eq "yam!"
|
668
|
+
render :soap => nil
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
savon(:rocknroll, "ZOMG" => 'yam!')
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
676
|
+
describe "Router" do
|
677
|
+
it "raises when SOAP message without SOAP Envelope arrives" do
|
678
|
+
mock_controller do; end
|
679
|
+
invalid_request = '<a></a>'
|
680
|
+
response_hash = Nori.new.parse(HTTPI.post("http://app/route/api/action", invalid_request).body)
|
681
|
+
expect(response_hash["soap:Envelope"]["soap:Body"]["soap:Fault"]['faultstring']).to eq "Invalid SOAP request"
|
682
|
+
end
|
683
|
+
|
684
|
+
it "raises when SOAP message without SOAP Body arrives" do
|
685
|
+
mock_controller do; end
|
686
|
+
invalid_request = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"></s:Envelope>'
|
687
|
+
response_hash = Nori.new.parse(HTTPI.post("http://app/route/api/action", invalid_request).body)
|
688
|
+
expect(response_hash["soap:Envelope"]["soap:Body"]["soap:Fault"]['faultstring']).to eq "Invalid SOAP request"
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
describe "WS Security" do
|
693
|
+
it "appends username_token to params" do
|
694
|
+
mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
|
695
|
+
soap_action "checkToken", :args => :integer, :return => nil, :to => 'check_token'
|
696
|
+
def check_token
|
697
|
+
expect(request.env['WSSE_TOKEN']['username']).to eq "gorilla"
|
698
|
+
expect(request.env['WSSE_TOKEN']['password']).to eq "secret"
|
699
|
+
render :soap => nil
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
savon(:check_token, 42) do
|
704
|
+
wsse_auth "gorilla", "secret"
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
it "handles PasswordText auth" do
|
709
|
+
mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
|
710
|
+
soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
|
711
|
+
def check_auth
|
712
|
+
render :soap => (params[:value] == 42)
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
# correct auth
|
717
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
718
|
+
not_to raise_exception
|
719
|
+
|
720
|
+
# wrong user
|
721
|
+
expect { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret" } }.
|
722
|
+
to raise_exception(Savon::SOAPFault)
|
723
|
+
|
724
|
+
# wrong pass
|
725
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry" } }.
|
726
|
+
to raise_exception(Savon::SOAPFault)
|
727
|
+
|
728
|
+
# no auth
|
729
|
+
expect { savon(:check_auth, 42) }.
|
730
|
+
to raise_exception(Savon::SOAPFault)
|
731
|
+
end
|
732
|
+
|
733
|
+
it "handles PasswordDigest auth" do
|
734
|
+
mock_controller(wsse_username: "gorilla", wsse_password: "secret") do
|
735
|
+
soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
|
736
|
+
def check_auth
|
737
|
+
render :soap => (params[:value] == 42)
|
738
|
+
end
|
739
|
+
end
|
740
|
+
|
741
|
+
# correct auth
|
742
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
743
|
+
not_to raise_exception
|
744
|
+
|
745
|
+
# correct digest auth
|
746
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret", :digest } }.
|
747
|
+
not_to raise_exception
|
748
|
+
|
749
|
+
# wrong user
|
750
|
+
expect { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret", :digest } }.
|
751
|
+
to raise_exception(Savon::SOAPFault)
|
752
|
+
|
753
|
+
# wrong pass
|
754
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry", :digest } }.
|
755
|
+
to raise_exception(Savon::SOAPFault)
|
756
|
+
|
757
|
+
# no auth
|
758
|
+
expect { savon(:check_auth, 42) }.
|
759
|
+
to raise_exception(Savon::SOAPFault)
|
760
|
+
end
|
761
|
+
|
762
|
+
it "handles auth callback" do
|
763
|
+
mock_controller(
|
764
|
+
wsse_auth_callback: lambda {|user, password|
|
765
|
+
return user == "gorilla" && password == "secret"
|
766
|
+
}
|
767
|
+
) do
|
768
|
+
soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
|
769
|
+
def check_auth
|
770
|
+
render :soap => (params[:value] == 42)
|
771
|
+
end
|
772
|
+
end
|
773
|
+
|
774
|
+
# correct auth
|
775
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
776
|
+
not_to raise_exception
|
777
|
+
|
778
|
+
# correct digest auth
|
779
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "secret", :digest } }.
|
780
|
+
to raise_exception(Savon::SOAPFault)
|
781
|
+
|
782
|
+
# wrong user
|
783
|
+
expect { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret", :digest } }.
|
784
|
+
to raise_exception(Savon::SOAPFault)
|
785
|
+
|
786
|
+
# wrong pass
|
787
|
+
expect { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry", :digest } }.
|
788
|
+
to raise_exception(Savon::SOAPFault)
|
789
|
+
|
790
|
+
# no auth
|
791
|
+
expect { savon(:check_auth, 42) }.
|
792
|
+
to raise_exception(Savon::SOAPFault)
|
793
|
+
end
|
794
|
+
|
795
|
+
end
|
796
|
+
|
797
|
+
end
|