nogara-wash_out 0.5.2
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.
- data/.gitignore +9 -0
- data/.travis.yml +3 -0
- data/Appraisals +7 -0
- data/CHANGELOG.md +79 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +118 -0
- data/LICENSE +22 -0
- data/README.md +181 -0
- data/Rakefile +14 -0
- data/app/helpers/wash_out_helper.rb +64 -0
- data/app/views/wash_with_soap/error.builder +10 -0
- data/app/views/wash_with_soap/response.builder +13 -0
- data/app/views/wash_with_soap/wsdl.builder +68 -0
- data/gemfiles/rails-3.0.11.gemfile +8 -0
- data/gemfiles/rails-3.0.11.gemfile.lock +130 -0
- data/gemfiles/rails-3.1.3.gemfile +8 -0
- data/gemfiles/rails-3.1.3.gemfile.lock +141 -0
- data/init.rb +1 -0
- data/lib/wash_out.rb +35 -0
- data/lib/wash_out/dispatcher.rb +206 -0
- data/lib/wash_out/engine.rb +30 -0
- data/lib/wash_out/model.rb +25 -0
- data/lib/wash_out/param.rb +176 -0
- data/lib/wash_out/router.rb +36 -0
- data/lib/wash_out/soap.rb +40 -0
- data/lib/wash_out/type.rb +28 -0
- data/lib/wash_out/version.rb +3 -0
- data/lib/wash_out/wsse.rb +79 -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 +42 -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 +7 -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/spec_helper.rb +51 -0
- data/spec/support/httpi-rack.rb +46 -0
- data/spec/wash_out/dispatcher_spec.rb +65 -0
- data/spec/wash_out/param_spec.rb +26 -0
- data/spec/wash_out/type_spec.rb +23 -0
- data/spec/wash_out_spec.rb +686 -0
- data/wash_out.gemspec +21 -0
- metadata +183 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/404.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/422.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/500.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
23
|
+
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
|
6
|
+
require 'rails/commands'
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Configure Rails Envinronment
|
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
|
3
|
+
|
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
|
5
|
+
require "rails/test_help"
|
|
6
|
+
require "rspec/rails"
|
|
7
|
+
|
|
8
|
+
Rails.backtrace_cleaner.remove_silencers!
|
|
9
|
+
|
|
10
|
+
# Load support files
|
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
12
|
+
|
|
13
|
+
RSpec.configure do |config|
|
|
14
|
+
# Remove this line if you don't want RSpec's should and should_not
|
|
15
|
+
# methods or matchers
|
|
16
|
+
require 'rspec/expectations'
|
|
17
|
+
config.include RSpec::Matchers
|
|
18
|
+
|
|
19
|
+
# == Mock Framework
|
|
20
|
+
config.mock_with :rspec
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
require 'savon'
|
|
24
|
+
|
|
25
|
+
Savon.configure do |config|
|
|
26
|
+
config.log = false # disable logging
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
HTTPI.logger = Logger.new(open("/dev/null", 'w'))
|
|
30
|
+
HTTPI.adapter = :rack
|
|
31
|
+
|
|
32
|
+
HTTPI::Adapters::Rack.mount 'app', Dummy::Application
|
|
33
|
+
|
|
34
|
+
Dummy::Application.routes.draw do
|
|
35
|
+
wash_out :api
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def client
|
|
39
|
+
Savon::Client.new do
|
|
40
|
+
wsdl.document = 'http://app/api/wsdl'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def mock_controller(&block)
|
|
45
|
+
Object.send :remove_const, :ApiController if defined?(ApiController)
|
|
46
|
+
Object.send :const_set, :ApiController, Class.new(ApplicationController) {
|
|
47
|
+
include WashOut::SOAP
|
|
48
|
+
|
|
49
|
+
class_exec &block if block
|
|
50
|
+
}
|
|
51
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'httpi'
|
|
2
|
+
require 'httpi/response'
|
|
3
|
+
|
|
4
|
+
module HTTPI
|
|
5
|
+
module Adapters
|
|
6
|
+
# This is an adapter for testing the Rack applications with HTTPI-capable
|
|
7
|
+
# clients.
|
|
8
|
+
class Rack
|
|
9
|
+
class << self
|
|
10
|
+
attr_accessor :mounted_apps
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
self.mounted_apps = {}
|
|
14
|
+
|
|
15
|
+
def self.mount(host, application)
|
|
16
|
+
self.mounted_apps[host] = application
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(request=nil)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def method_missing(method, *args)
|
|
23
|
+
if %w{get post head put delete}.include?(method.to_s)
|
|
24
|
+
request, = args
|
|
25
|
+
|
|
26
|
+
app = self.class.mounted_apps[request.url.host]
|
|
27
|
+
mock_req = ::Rack::MockRequest.new(app)
|
|
28
|
+
|
|
29
|
+
env = {}
|
|
30
|
+
request.headers.each do |header, value|
|
|
31
|
+
env["HTTP_#{header.gsub('-', '_').upcase}"] = value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
mock_resp = mock_req.request(method.to_s.upcase, request.url.to_s,
|
|
35
|
+
{ :fatal => true, :input => request.body.to_s }.merge(env))
|
|
36
|
+
|
|
37
|
+
HTTPI::Response.new(mock_resp.status, mock_resp.headers, mock_resp.body)
|
|
38
|
+
else
|
|
39
|
+
super
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
Adapter::ADAPTERS[:rack] = { :class => Adapters::Rack, :require => 'rack/mock' }
|
|
46
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#encoding:utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe WashOut::Dispatcher do
|
|
6
|
+
|
|
7
|
+
class TestBody
|
|
8
|
+
attr_accessor :read
|
|
9
|
+
def initialize(read); @read = read; end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class TestRequest
|
|
13
|
+
attr_accessor :body
|
|
14
|
+
def initialize(body); @body = body; end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class Dispatcher < ApplicationController
|
|
18
|
+
include WashOut::SOAP
|
|
19
|
+
|
|
20
|
+
def self.mock(text="")
|
|
21
|
+
dispatcher = self.new
|
|
22
|
+
dispatcher.request = TestRequest.new(TestBody.new(text))
|
|
23
|
+
dispatcher
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def params
|
|
27
|
+
@_params
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "finds nested hashes" do
|
|
32
|
+
WashOut::Dispatcher.deep_select(:foo => 1){|k,v| k == :foo}.should == [1]
|
|
33
|
+
WashOut::Dispatcher.deep_select({:foo => {:foo => 1}}){|k,v| k == :foo}.should == [{:foo => 1}, 1]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "replaces nested hashed" do
|
|
37
|
+
WashOut::Dispatcher.deep_replace_href({:foo => {:@href => 1}}, {1 => 2}).should == {:foo => 2}
|
|
38
|
+
WashOut::Dispatcher.deep_replace_href({:bar => {:foo => {:@href => 1}}}, {1 => 2}).should == {:bar => {:foo => 2}}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "parses typical request" do
|
|
42
|
+
dispatcher = Dispatcher.mock("<foo>1</foo>")
|
|
43
|
+
dispatcher._parse_soap_parameters
|
|
44
|
+
dispatcher.params.should == {:foo => "1"}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "parses href request" do
|
|
48
|
+
dispatcher = Dispatcher.mock <<-XML
|
|
49
|
+
<request>
|
|
50
|
+
<entities href="#id1">
|
|
51
|
+
</entities>
|
|
52
|
+
</request>
|
|
53
|
+
<entity id="id1">
|
|
54
|
+
<foo><bar>1</bar></foo>
|
|
55
|
+
<sub href="#id2" />
|
|
56
|
+
</entity>
|
|
57
|
+
<ololo id="id2">
|
|
58
|
+
<foo>1</foo>
|
|
59
|
+
</ololo>
|
|
60
|
+
XML
|
|
61
|
+
dispatcher._parse_soap_parameters
|
|
62
|
+
dispatcher.params[:request][:entities].should == {:foo=>{:bar=>"1"}, :sub=>{:foo=>"1", :@id=>"id2"}, :@id=>"id1"}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#encoding:utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe WashOut::Param do
|
|
6
|
+
|
|
7
|
+
it "loads custom_types" do
|
|
8
|
+
class Abraka1 < WashOut::Type
|
|
9
|
+
map(
|
|
10
|
+
:test => :string
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
class Abraka2 < WashOut::Type
|
|
14
|
+
type_name 'test'
|
|
15
|
+
map :foo => Abraka1
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
map = WashOut::Param.parse_def Abraka2
|
|
19
|
+
|
|
20
|
+
map.should be_a_kind_of(Array)
|
|
21
|
+
map[0].name.should == 'Value'
|
|
22
|
+
map[0].map[0].name.should == 'Foo'
|
|
23
|
+
map[0].map[0].map[0].name.should == 'Test'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#encoding:utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe WashOut::Type do
|
|
6
|
+
|
|
7
|
+
it "defines custom type" do
|
|
8
|
+
class Abraka1 < WashOut::Type
|
|
9
|
+
map :test => :string
|
|
10
|
+
end
|
|
11
|
+
class Abraka2 < WashOut::Type
|
|
12
|
+
type_name 'test'
|
|
13
|
+
map :foo => Abraka1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Abraka1.wash_out_param_name.should == 'Abraka1'
|
|
17
|
+
Abraka1.wash_out_param_map.should == {:test => :string}
|
|
18
|
+
|
|
19
|
+
Abraka2.wash_out_param_name.should == 'Test'
|
|
20
|
+
Abraka2.wash_out_param_map.should == {:foo => Abraka1}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
#encoding:utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe WashOut do
|
|
6
|
+
before(:each) do
|
|
7
|
+
WashOut::Engine.snakecase_input = true
|
|
8
|
+
WashOut::Engine.camelize_wsdl = true
|
|
9
|
+
WashOut::Engine.namespace = false
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should be valid" do
|
|
13
|
+
WashOut.should be_a(Module)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should allow to include SOAP module" do
|
|
17
|
+
lambda {
|
|
18
|
+
mock_controller do
|
|
19
|
+
# nothing
|
|
20
|
+
end
|
|
21
|
+
}.should_not raise_exception
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should generate WSDL" do
|
|
25
|
+
mock_controller do
|
|
26
|
+
soap_action :result, :args => nil, :return => :int
|
|
27
|
+
def answer
|
|
28
|
+
render :soap => "42"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
soap_action "getArea", :args => { :circle => { :center => { :x => [:integer],
|
|
32
|
+
:y => :integer },
|
|
33
|
+
:radius => :double } },
|
|
34
|
+
:return => { :area => :double,
|
|
35
|
+
:distance_from_o => :double },
|
|
36
|
+
:to => :get_area
|
|
37
|
+
def get_area
|
|
38
|
+
circle = params[:circle]
|
|
39
|
+
render :soap => { :area => Math::PI * circle[:radius] ** 2,
|
|
40
|
+
:distance_from_o => Math.sqrt(circle[:center][:x] ** 2 + circle[:center][:y] ** 2) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
soap_action "rocky", :args => { :circle1 => { :x => :integer } },
|
|
44
|
+
:return => { :circle2 => { :y => :integer } }
|
|
45
|
+
def rocky; end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
xml = Nori.parse client.wsdl.xml
|
|
49
|
+
|
|
50
|
+
# Savon underscores method names so we
|
|
51
|
+
# get back just what we have at controller
|
|
52
|
+
client.wsdl.soap_actions.map{|x| x.to_s}.sort.should == [:result, :get_area, :rocky].map{|x| x.to_s}.sort
|
|
53
|
+
|
|
54
|
+
x = xml[:definitions][:types][:schema][:complex_type].find{|x| x[:'@name'] == 'Center'}[:sequence][:element].find{|x| x[:'@name'] == 'X'}
|
|
55
|
+
x[:'@min_occurs'].should == "0"
|
|
56
|
+
x[:'@max_occurs'].should == "unbounded"
|
|
57
|
+
|
|
58
|
+
xml[:definitions][:binding][:operation].map{|e| e[:'@name']}.sort.should == ['Result', 'getArea', 'rocky'].sort
|
|
59
|
+
|
|
60
|
+
client.wsdl.xml.include?('<xsd:complexType name="Circle1">').should == true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should allow definition of a simple action" do
|
|
64
|
+
lambda {
|
|
65
|
+
mock_controller do
|
|
66
|
+
soap_action "answer", :args => nil, :return => :integer
|
|
67
|
+
end
|
|
68
|
+
}.should_not raise_exception
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should answer to request without parameters" do
|
|
72
|
+
mock_controller do
|
|
73
|
+
soap_action "answer", :args => nil, :return => :int
|
|
74
|
+
def answer
|
|
75
|
+
render :soap => "42"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
client.request(:answer).to_hash[:answer_response][:value].should == "42"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should respond to request with insufficient parameters" do
|
|
83
|
+
mock_controller do
|
|
84
|
+
soap_action "answer", :args => {:a => :integer}, :return => :integer
|
|
85
|
+
def answer
|
|
86
|
+
render :soap => "42"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
client.request(:answer).to_hash[:answer_response][:value].should == "42"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should answer to request with empty parameter" do
|
|
94
|
+
mock_controller do
|
|
95
|
+
soap_action "answer", :args => {:a => :string}, :return => {:a => :string}
|
|
96
|
+
def answer
|
|
97
|
+
render :soap => {:a => params[:a]}
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
client.request(:answer) do
|
|
102
|
+
soap.body = { :a => '' }
|
|
103
|
+
end.to_hash[:answer_response][:a].should == {:"@xsi:type"=>"xsd:string"}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "should answer to request with one parameter" do
|
|
107
|
+
mock_controller do
|
|
108
|
+
soap_action "checkAnswer", :args => :integer, :return => :boolean, :to => 'check_answer'
|
|
109
|
+
def check_answer
|
|
110
|
+
render :soap => (params[:value] == 42)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
client.request(:check_answer) do
|
|
115
|
+
soap.body = { :value => 42 }
|
|
116
|
+
end.to_hash[:check_answer_response][:value].should == true
|
|
117
|
+
client.request(:check_answer) do
|
|
118
|
+
soap.body = { :value => 13 }
|
|
119
|
+
end.to_hash[:check_answer_response][:value].should == false
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "handles incorrect requests" do
|
|
123
|
+
mock_controller do
|
|
124
|
+
soap_action "duty",
|
|
125
|
+
:args => {:bad => {:a => :string, :b => :string}, :good => {:a => :string, :b => :string}},
|
|
126
|
+
:return => nil
|
|
127
|
+
def duty
|
|
128
|
+
render :soap => nil
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
lambda {
|
|
133
|
+
client.request(:duty) do
|
|
134
|
+
soap.body = { :bad => 42, :good => nil }
|
|
135
|
+
end
|
|
136
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should handle snakecase option properly" do
|
|
140
|
+
WashOut::Engine.snakecase_input = false
|
|
141
|
+
WashOut::Engine.camelize_wsdl = false
|
|
142
|
+
|
|
143
|
+
mock_controller do
|
|
144
|
+
soap_action "rocknroll", :args => {:ZOMG => :string}, :return => nil
|
|
145
|
+
def rocknroll
|
|
146
|
+
params["ZOMG"].should == "yam!"
|
|
147
|
+
render :soap => nil
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
client.request(:rocknroll) do
|
|
152
|
+
soap.body = { "ZOMG" => 'yam!' }
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context "optional arrays" do
|
|
157
|
+
it "should answer for simple structure" do
|
|
158
|
+
mock_controller do
|
|
159
|
+
soap_action "rocknroll",
|
|
160
|
+
:args => nil, :return => { :my_value => [:integer] }
|
|
161
|
+
def rocknroll
|
|
162
|
+
render :soap => {}
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
client.request(:rocknroll).to_hash[:rocknroll_response].should be_nil
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should answer for complex structure" do
|
|
170
|
+
mock_controller do
|
|
171
|
+
soap_action "rocknroll",
|
|
172
|
+
:args => nil, :return => { :my_value => [{ :value => :integer}] }
|
|
173
|
+
def rocknroll
|
|
174
|
+
render :soap => {}
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
client.request(:rocknroll).to_hash[:rocknroll_response].should be_nil
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should answer for nested complex structure" do
|
|
182
|
+
mock_controller do
|
|
183
|
+
soap_action "rocknroll",
|
|
184
|
+
:args => nil, :return => { :my_value => { :my_array => [{ :value => :integer}] } }
|
|
185
|
+
def rocknroll
|
|
186
|
+
render :soap => {}
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
client.request(:rocknroll).to_hash[:rocknroll_response][:my_value].should == { :"@xsi:type" => "tns:MyValue" }
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should answer to request with two parameter" do
|
|
195
|
+
mock_controller do
|
|
196
|
+
soap_action "funky", :args => { :a => :integer, :b => :string }, :return => :string
|
|
197
|
+
def funky
|
|
198
|
+
render :soap => ((params[:a] * 10).to_s + params[:b])
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
client.request(:funky) do
|
|
203
|
+
soap.body = { :a => 42, :b => 'k' }
|
|
204
|
+
end.to_hash[:funky_response][:value].should == '420k'
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "should understand nested parameter specifications" do
|
|
208
|
+
mock_controller do
|
|
209
|
+
soap_action "getArea", :args => { :circle => { :center => { :x => :integer,
|
|
210
|
+
:y => :integer },
|
|
211
|
+
:radius => :double } },
|
|
212
|
+
:return => { :area => :double,
|
|
213
|
+
:distance_from_o => :double },
|
|
214
|
+
:to => :get_area
|
|
215
|
+
def get_area
|
|
216
|
+
circle = params[:circle]
|
|
217
|
+
render :soap => { :area => Math::PI * circle[:radius] ** 2,
|
|
218
|
+
:distance_from_o => Math.sqrt(circle[:center][:x] ** 2 + circle[:center][:y] ** 2) }
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
client.request(:get_area) do
|
|
223
|
+
soap.body = { :circle => { :center => { :x => 3, :y => 4 },
|
|
224
|
+
:radius => 5 } }
|
|
225
|
+
end.to_hash[:get_area_response].should == ({ :area => (Math::PI * 25).to_s, :distance_from_o => (5.0).to_s })
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "should allow arbitrary action names" do
|
|
229
|
+
name = 'AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything'
|
|
230
|
+
|
|
231
|
+
mock_controller do
|
|
232
|
+
soap_action name,
|
|
233
|
+
:args => nil, :return => :integer, :to => :answer
|
|
234
|
+
def answer
|
|
235
|
+
render :soap => "forty two"
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
client.request(name).to_hash["#{name.underscore}_response".to_sym][:value].should == "forty two"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should correctly report SOAP errors" do
|
|
243
|
+
mock_controller do
|
|
244
|
+
soap_action "error", :args => { :need_error => :boolean }, :return => nil
|
|
245
|
+
def error
|
|
246
|
+
raise self.class.const_get(:SOAPError), "you wanted one" if params[:need_error]
|
|
247
|
+
|
|
248
|
+
render :soap => nil
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
lambda {
|
|
253
|
+
client.request(:error) do
|
|
254
|
+
soap.body = { :need_error => false }
|
|
255
|
+
end
|
|
256
|
+
}.should_not raise_exception
|
|
257
|
+
lambda {
|
|
258
|
+
client.request(:error) do
|
|
259
|
+
soap.body = { :need_error => true }
|
|
260
|
+
end
|
|
261
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "should report a SOAP error if method does not exists" do
|
|
265
|
+
mock_controller
|
|
266
|
+
|
|
267
|
+
lambda {
|
|
268
|
+
client.request(:nonexistent)
|
|
269
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "should be possible to explicitly render a SOAP error" do
|
|
273
|
+
mock_controller do
|
|
274
|
+
soap_action "error", :args => nil, :return => nil
|
|
275
|
+
def error
|
|
276
|
+
render_soap_error "a message"
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
lambda {
|
|
281
|
+
client.request(:error)
|
|
282
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "should handle nested returns" do
|
|
286
|
+
mock_controller do
|
|
287
|
+
soap_action "gogogo",
|
|
288
|
+
:args => nil,
|
|
289
|
+
:return => {
|
|
290
|
+
:zoo => :string,
|
|
291
|
+
:boo => {
|
|
292
|
+
:moo => :string,
|
|
293
|
+
:doo => :string
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
def gogogo
|
|
297
|
+
render :soap => {
|
|
298
|
+
:zoo => 'zoo',
|
|
299
|
+
:boo => {
|
|
300
|
+
:moo => 'moo',
|
|
301
|
+
:doo => 'doo'
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
client.request(:gogogo)[:gogogo_response].should == {:zoo=>"zoo", :boo=>{:moo=>"moo", :doo=>"doo", :"@xsi:type"=>"tns:Boo"}}
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "should handle arrays" do
|
|
311
|
+
mock_controller do
|
|
312
|
+
soap_action "rumba",
|
|
313
|
+
:args => {
|
|
314
|
+
:rumbas => [:integer]
|
|
315
|
+
},
|
|
316
|
+
:return => nil
|
|
317
|
+
def rumba
|
|
318
|
+
params.should == {"rumbas" => [1, 2, 3]}
|
|
319
|
+
render :soap => nil
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
client.request(:rumba) do
|
|
324
|
+
soap.body = {
|
|
325
|
+
:rumbas => [1, 2, 3]
|
|
326
|
+
}
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "should handle complex structures inside arrays" do
|
|
331
|
+
mock_controller do
|
|
332
|
+
soap_action "rumba",
|
|
333
|
+
:args => {
|
|
334
|
+
:rumbas => [ {
|
|
335
|
+
:zombies => :string,
|
|
336
|
+
:puppies => :string
|
|
337
|
+
} ]
|
|
338
|
+
},
|
|
339
|
+
:return => nil
|
|
340
|
+
def rumba
|
|
341
|
+
params.should == {
|
|
342
|
+
"rumbas" => [
|
|
343
|
+
{"zombies" => 'suck', "puppies" => 'rock'},
|
|
344
|
+
{"zombies" => 'slow', "puppies" => 'fast'}
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
render :soap => nil
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
client.request(:rumba) do
|
|
352
|
+
soap.body = {
|
|
353
|
+
:rumbas => [
|
|
354
|
+
{:zombies => 'suck', :puppies => 'rock'},
|
|
355
|
+
{:zombies => 'slow', :puppies => 'fast'}
|
|
356
|
+
]
|
|
357
|
+
}
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
it "should be able to return arrays" do
|
|
362
|
+
mock_controller do
|
|
363
|
+
soap_action "rumba",
|
|
364
|
+
:args => nil,
|
|
365
|
+
:return => [:integer]
|
|
366
|
+
def rumba
|
|
367
|
+
render :soap => [1, 2, 3]
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
client.request(:rumba).to_hash[:rumba_response].should == {:value => ["1", "2", "3"]}
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "should deprecate old syntax" do
|
|
375
|
+
# save rspec context check
|
|
376
|
+
raise_runtime_exception = raise_exception(RuntimeError)
|
|
377
|
+
|
|
378
|
+
mock_controller do
|
|
379
|
+
lambda {
|
|
380
|
+
soap_action "rumba",
|
|
381
|
+
:args => :integer,
|
|
382
|
+
:return => []
|
|
383
|
+
}.should raise_runtime_exception
|
|
384
|
+
def rumba
|
|
385
|
+
render :soap => nil
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
it "should handle return of complex structures inside arrays" do
|
|
391
|
+
mock_controller do
|
|
392
|
+
soap_action "rumba",
|
|
393
|
+
:args => nil,
|
|
394
|
+
:return => {
|
|
395
|
+
:rumbas => [{:zombies => :string, :puppies => :string}]
|
|
396
|
+
}
|
|
397
|
+
def rumba
|
|
398
|
+
render :soap =>
|
|
399
|
+
{:rumbas => [
|
|
400
|
+
{:zombies => "suck1", :puppies => "rock1" },
|
|
401
|
+
{:zombies => "suck2", :puppies => "rock2" }
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
client.request(:rumba)[:rumba_response].should == {
|
|
408
|
+
:rumbas => [
|
|
409
|
+
{:zombies => "suck1",:puppies => "rock1", :"@xsi:type"=>"tns:Rumbas"},
|
|
410
|
+
{:zombies => "suck2", :puppies => "rock2", :"@xsi:type"=>"tns:Rumbas" }
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
it "should handle return of structs in structs in arrays" do
|
|
416
|
+
mock_controller do
|
|
417
|
+
soap_action "rumba",
|
|
418
|
+
:args => nil,
|
|
419
|
+
:return => [{:rumbas => {:zombies => :integer}}]
|
|
420
|
+
|
|
421
|
+
def rumba
|
|
422
|
+
render :soap => [{:rumbas => {:zombies => 100000}}, {:rumbas => {:zombies => 2}}]
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
client.request(:rumba)[:rumba_response].should == {
|
|
427
|
+
:value => [
|
|
428
|
+
{
|
|
429
|
+
:rumbas => {
|
|
430
|
+
:zombies => "100000",
|
|
431
|
+
:"@xsi:type" => "tns:Rumbas"
|
|
432
|
+
},
|
|
433
|
+
:"@xsi:type" => "tns:Value"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
:rumbas => {
|
|
437
|
+
:zombies => "2",
|
|
438
|
+
:"@xsi:type" => "tns:Rumbas"
|
|
439
|
+
},
|
|
440
|
+
:"@xsi:type"=>"tns:Value"
|
|
441
|
+
}
|
|
442
|
+
]
|
|
443
|
+
}
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
it "should handle complex structs/arrays" do
|
|
447
|
+
mock_controller do
|
|
448
|
+
soap_action "rumba",
|
|
449
|
+
:args => nil,
|
|
450
|
+
:return => {
|
|
451
|
+
:rumbas => [
|
|
452
|
+
{
|
|
453
|
+
:zombies => :string,
|
|
454
|
+
:puppies => [
|
|
455
|
+
{:kittens => :integer}
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
def rumba
|
|
462
|
+
render :soap => {
|
|
463
|
+
:rumbas => [
|
|
464
|
+
{
|
|
465
|
+
:zombies => "abc",
|
|
466
|
+
:puppies => [
|
|
467
|
+
{:kittens => 1},
|
|
468
|
+
{:kittens => 5},
|
|
469
|
+
]
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
:zombies => "def",
|
|
473
|
+
:puppies => [
|
|
474
|
+
{:kittens => 4}
|
|
475
|
+
]
|
|
476
|
+
}
|
|
477
|
+
]
|
|
478
|
+
}
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
client.request(:rumba)[:rumba_response].should == {
|
|
483
|
+
:rumbas => [
|
|
484
|
+
{
|
|
485
|
+
:zombies => "abc",
|
|
486
|
+
:puppies => [
|
|
487
|
+
{
|
|
488
|
+
:kittens => "1",
|
|
489
|
+
:"@xsi:type" => "tns:Puppies"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
:kittens => "5",
|
|
493
|
+
:"@xsi:type" => "tns:Puppies"
|
|
494
|
+
}
|
|
495
|
+
],
|
|
496
|
+
:"@xsi:type"=>"tns:Rumbas"
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
:zombies => "def",
|
|
500
|
+
:puppies => {
|
|
501
|
+
:kittens => "4",
|
|
502
|
+
:"@xsi:type" => "tns:Puppies"
|
|
503
|
+
},
|
|
504
|
+
:"@xsi:type"=>"tns:Rumbas"
|
|
505
|
+
}
|
|
506
|
+
]
|
|
507
|
+
}
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
it "handles dates" do
|
|
511
|
+
mock_controller do
|
|
512
|
+
soap_action "date",
|
|
513
|
+
:args => :date,
|
|
514
|
+
:return => :nil
|
|
515
|
+
def date
|
|
516
|
+
params[:value].should == Date.parse('2000-12-30') unless params[:value].blank?
|
|
517
|
+
render :soap => nil
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
client.request(:date) do
|
|
522
|
+
soap.body = {
|
|
523
|
+
:value => '2000-12-30'
|
|
524
|
+
}
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
lambda {
|
|
528
|
+
client.request(:date) do
|
|
529
|
+
soap.body = {
|
|
530
|
+
:value => nil
|
|
531
|
+
}
|
|
532
|
+
end
|
|
533
|
+
}.should_not raise_exception
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
describe "ws-security" do
|
|
537
|
+
|
|
538
|
+
it "should append username_token to params, if present" do
|
|
539
|
+
WashOut::Engine.wsse_username = nil
|
|
540
|
+
WashOut::Engine.wsse_password = nil
|
|
541
|
+
|
|
542
|
+
mock_controller do
|
|
543
|
+
soap_action "checkToken", :args => :integer, :return => nil, :to => 'check_token'
|
|
544
|
+
def check_token
|
|
545
|
+
request.env['WSSE_TOKEN']['username'].should == "gorilla"
|
|
546
|
+
request.env['WSSE_TOKEN']['password'].should == "secret"
|
|
547
|
+
render :soap => nil
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
client.request(:check_token) do
|
|
552
|
+
wsse.username = "gorilla"
|
|
553
|
+
wsse.password = "secret"
|
|
554
|
+
soap.body = { :value => 42 }
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
it "should handle PasswordText auth" do
|
|
559
|
+
WashOut::Engine.wsse_username = "gorilla"
|
|
560
|
+
WashOut::Engine.wsse_password = "secret"
|
|
561
|
+
|
|
562
|
+
mock_controller do
|
|
563
|
+
soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
|
|
564
|
+
def check_auth
|
|
565
|
+
render :soap => (params[:value] == 42)
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
# correct auth
|
|
570
|
+
lambda {
|
|
571
|
+
client.request(:check_auth) do
|
|
572
|
+
wsse.username = "gorilla"
|
|
573
|
+
wsse.password = "secret"
|
|
574
|
+
soap.body = { :value => 42 }
|
|
575
|
+
end
|
|
576
|
+
}.should_not raise_exception
|
|
577
|
+
# wrong user
|
|
578
|
+
lambda {
|
|
579
|
+
client.request(:check_auth) do
|
|
580
|
+
wsse.username = "chimpanzee"
|
|
581
|
+
wsse.password = "secret"
|
|
582
|
+
soap.body = { :value => 42 }
|
|
583
|
+
end
|
|
584
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
585
|
+
# wrong pass
|
|
586
|
+
lambda {
|
|
587
|
+
client.request(:check_auth) do
|
|
588
|
+
wsse.username = "gorilla"
|
|
589
|
+
wsse.password = "nicetry"
|
|
590
|
+
soap.body = { :value => 42 }
|
|
591
|
+
end
|
|
592
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
593
|
+
# no auth
|
|
594
|
+
lambda {
|
|
595
|
+
client.request(:check_auth) do
|
|
596
|
+
soap.body = { :value => 42 }
|
|
597
|
+
end
|
|
598
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
it "should handle PasswordDigest auth" do
|
|
602
|
+
WashOut::Engine.wsse_username = "gorilla"
|
|
603
|
+
WashOut::Engine.wsse_password = "secret"
|
|
604
|
+
|
|
605
|
+
mock_controller do
|
|
606
|
+
soap_action "checkAuth", :args => :integer, :return => :boolean, :to => 'check_auth'
|
|
607
|
+
def check_auth
|
|
608
|
+
render :soap => (params[:value] == 42)
|
|
609
|
+
end
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
# correct auth
|
|
613
|
+
lambda {
|
|
614
|
+
client.request(:check_auth) do
|
|
615
|
+
wsse.credentials "gorilla", "secret", :digest
|
|
616
|
+
soap.body = { :value => 42 }
|
|
617
|
+
end
|
|
618
|
+
}.should_not raise_exception
|
|
619
|
+
# wrong user
|
|
620
|
+
lambda {
|
|
621
|
+
client.request(:check_auth) do
|
|
622
|
+
wsse.credentials "chimpanzee", "secret", :digest
|
|
623
|
+
soap.body = { :value => 42 }
|
|
624
|
+
end
|
|
625
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
626
|
+
# wrong pass
|
|
627
|
+
lambda {
|
|
628
|
+
client.request(:check_auth) do
|
|
629
|
+
wsse.credentials "gorilla", "nicetry", :digest
|
|
630
|
+
soap.body = { :value => 42 }
|
|
631
|
+
end
|
|
632
|
+
}.should raise_exception(Savon::SOAP::Fault)
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
it 'will not let you pass an Array in the place of a Hash' do
|
|
638
|
+
mock_controller do
|
|
639
|
+
soap_action 'bad', :args => :integer, :return => {
|
|
640
|
+
:basic => :string,
|
|
641
|
+
:stallions => {
|
|
642
|
+
:stallion => [
|
|
643
|
+
:name => :string,
|
|
644
|
+
:wyldness => :integer,
|
|
645
|
+
]
|
|
646
|
+
},
|
|
647
|
+
}
|
|
648
|
+
def bad
|
|
649
|
+
render :soap => {
|
|
650
|
+
:basic => 'hi',
|
|
651
|
+
:stallions => [{:name => 'ted', :wyldness => 11}]
|
|
652
|
+
}
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
lambda {
|
|
657
|
+
client.request(:bad).to_hash(:bad_response)
|
|
658
|
+
}.should raise_exception(
|
|
659
|
+
WashOut::Dispatcher::ProgrammerError,
|
|
660
|
+
/SOAP response .*wyldness.*Array.*Hash.*stallion/
|
|
661
|
+
)
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
it 'loudly fails if you return a string in place of an Array' do
|
|
665
|
+
mock_controller do
|
|
666
|
+
soap_action 'bad2', :args => :integer, :return => {
|
|
667
|
+
:basic => :string,
|
|
668
|
+
:telephone_booths => [:string]
|
|
669
|
+
}
|
|
670
|
+
def bad2
|
|
671
|
+
render :soap => {
|
|
672
|
+
:basic => 'hihi',
|
|
673
|
+
:telephone_booths => 'oops'
|
|
674
|
+
}
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
lambda {
|
|
679
|
+
client.request(:bad2).to_hash[:bad_response]
|
|
680
|
+
}.should raise_exception(
|
|
681
|
+
WashOut::Dispatcher::ProgrammerError,
|
|
682
|
+
/SOAP response .*oops.*String.*telephone_booths.*Array/
|
|
683
|
+
)
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
end
|