wash_out 0.5.6 → 0.6.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.
- data/CHANGELOG.md +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +21 -19
- data/lib/wash_out/dispatcher.rb +10 -22
- data/lib/wash_out/param.rb +1 -1
- data/lib/wash_out/version.rb +1 -1
- data/lib/wash_out/wsse.rb +3 -3
- data/spec/lib/wash_out/dispatcher_spec.rb +19 -23
- data/spec/lib/wash_out_spec.rb +446 -538
- data/spec/spec_helper.rb +4 -16
- data/wash_out.gemspec +1 -11
- metadata +20 -125
- data/spec/support/httpi-rack.rb +0 -46
data/spec/lib/wash_out_spec.rb
CHANGED
@@ -3,550 +3,530 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe WashOut do
|
6
|
-
before
|
6
|
+
before :each do
|
7
7
|
WashOut::Engine.snakecase_input = true
|
8
8
|
WashOut::Engine.camelize_wsdl = true
|
9
9
|
WashOut::Engine.namespace = false
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
let :nori do
|
13
|
+
Nori.new(
|
14
|
+
:strip_namespaces => true,
|
15
|
+
:advanced_typecasting => true,
|
16
|
+
:convert_tags_to => lambda {|x| x.snakecase.to_sym}
|
17
|
+
)
|
14
18
|
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
mock_controller do
|
19
|
-
# nothing
|
20
|
-
end
|
21
|
-
}.should_not raise_exception
|
22
|
-
end
|
20
|
+
def savon(method, message={}, &block)
|
21
|
+
message = {:value => message} unless message.is_a?(Hash)
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def answer
|
28
|
-
render :soap => "42"
|
29
|
-
end
|
23
|
+
savon = Savon::Client.new(:log => false, :wsdl => 'http://app/api/wsdl', &block)
|
24
|
+
savon.call(method, :message => message).to_hash
|
25
|
+
end
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
27
|
+
describe "Module" do
|
28
|
+
it "includes" do
|
29
|
+
lambda {
|
30
|
+
mock_controller do
|
31
|
+
# nothing
|
32
|
+
end
|
33
|
+
}.should_not raise_exception
|
34
|
+
end
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
it "allows definition of a simple action" do
|
37
|
+
lambda {
|
38
|
+
mock_controller do
|
39
|
+
soap_action "answer", :args => nil, :return => :integer
|
40
|
+
end
|
41
|
+
}.should_not raise_exception
|
46
42
|
end
|
43
|
+
end
|
47
44
|
|
48
|
-
|
45
|
+
describe "WSDL" do
|
46
|
+
let :wsdl do
|
47
|
+
mock_controller do
|
48
|
+
soap_action :result, :args => nil, :return => :int
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
soap_action "getArea", :args => { :circle => { :center => { :x => [:integer],
|
51
|
+
:y => :integer },
|
52
|
+
:radius => :double } },
|
53
|
+
:return => { :area => :double }
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
soap_action "rocky", :args => { :circle1 => { :x => :integer } },
|
56
|
+
:return => { :circle2 => { :y => :integer } }
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
+
HTTPI.get("http://app/api/wsdl").body
|
60
|
+
end
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
+
let :xml do
|
63
|
+
nori.parse wsdl
|
64
|
+
end
|
62
65
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
soap_action "answer", :args => nil, :return => :integer
|
67
|
-
end
|
68
|
-
}.should_not raise_exception
|
69
|
-
end
|
66
|
+
it "lists operations" do
|
67
|
+
operations = xml[:definitions][:binding][:operation]
|
68
|
+
operations.should be_a_kind_of(Array)
|
70
69
|
|
71
|
-
|
72
|
-
mock_controller do
|
73
|
-
soap_action "answer", :args => nil, :return => :int
|
74
|
-
def answer
|
75
|
-
render :soap => "42"
|
76
|
-
end
|
70
|
+
operations.map{|e| e[:'@name']}.sort.should == ['Result', 'getArea', 'rocky'].sort
|
77
71
|
end
|
78
72
|
|
79
|
-
|
80
|
-
|
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
|
73
|
+
it "defines complex types" do
|
74
|
+
wsdl.include?('<xsd:complexType name="Circle1">').should == true
|
88
75
|
end
|
89
76
|
|
90
|
-
|
91
|
-
|
77
|
+
it "defines arrays" do
|
78
|
+
x = xml[:definitions][:types][:schema][:complex_type].
|
79
|
+
find{|x| x[:'@name'] == 'Center'}[:sequence][:element].
|
80
|
+
find{|x| x[:'@name'] == 'X'}
|
92
81
|
|
93
|
-
|
94
|
-
|
95
|
-
soap_action "answer", :args => {:a => :string}, :return => {:a => :string}
|
96
|
-
def answer
|
97
|
-
render :soap => {:a => params[:a]}
|
98
|
-
end
|
82
|
+
x[:'@min_occurs'].should == "0"
|
83
|
+
x[:'@max_occurs'].should == "unbounded"
|
99
84
|
end
|
100
|
-
|
101
|
-
client.request(:answer) do
|
102
|
-
soap.body = { :a => '' }
|
103
|
-
end.to_hash[:answer_response][:a].should == {:"@xsi:type"=>"xsd:string"}
|
104
85
|
end
|
105
86
|
|
106
|
-
|
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
|
87
|
+
describe "Dispatcher" do
|
113
88
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
89
|
+
context "simple actions" do
|
90
|
+
it "accept no parameters" do
|
91
|
+
mock_controller do
|
92
|
+
soap_action "answer", :args => nil, :return => :int
|
93
|
+
def answer
|
94
|
+
render :soap => "42"
|
95
|
+
end
|
96
|
+
end
|
121
97
|
|
122
|
-
|
123
|
-
|
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
|
98
|
+
savon(:answer)[:answer_response][:value].
|
99
|
+
should == "42"
|
129
100
|
end
|
130
|
-
end
|
131
101
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
102
|
+
it "accept insufficient parameters" do
|
103
|
+
mock_controller do
|
104
|
+
soap_action "answer", :args => {:a => :integer}, :return => :integer
|
105
|
+
def answer
|
106
|
+
render :soap => "42"
|
107
|
+
end
|
108
|
+
end
|
138
109
|
|
139
|
-
|
140
|
-
|
141
|
-
soap_action "specific", :response_tag => "test", :return => :string
|
142
|
-
def specific
|
143
|
-
render :soap => "test"
|
110
|
+
savon(:answer)[:answer_response][:value].
|
111
|
+
should == "42"
|
144
112
|
end
|
145
|
-
end
|
146
113
|
|
147
|
-
|
148
|
-
|
114
|
+
it "accept empty parameter" do
|
115
|
+
mock_controller do
|
116
|
+
soap_action "answer", :args => {:a => :string}, :return => {:a => :string}
|
117
|
+
def answer
|
118
|
+
render :soap => {:a => params[:a]}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
savon(:answer, :a => '')[:answer_response][:a].
|
122
|
+
should == {:"@xsi:type"=>"xsd:string"}
|
123
|
+
end
|
149
124
|
|
150
|
-
|
151
|
-
|
152
|
-
|
125
|
+
it "accept one parameter" do
|
126
|
+
mock_controller do
|
127
|
+
soap_action "checkAnswer", :args => :integer, :return => :boolean, :to => 'check_answer'
|
128
|
+
def check_answer
|
129
|
+
render :soap => (params[:value] == 42)
|
130
|
+
end
|
131
|
+
end
|
153
132
|
|
154
|
-
|
155
|
-
|
156
|
-
def rocknroll
|
157
|
-
params["ZOMG"].should == "yam!"
|
158
|
-
render :soap => nil
|
133
|
+
savon(:check_answer, 42)[:check_answer_response][:value].should == true
|
134
|
+
savon(:check_answer, 13)[:check_answer_response][:value].should == false
|
159
135
|
end
|
160
|
-
end
|
161
|
-
|
162
|
-
client.request(:rocknroll) do
|
163
|
-
soap.body = { "ZOMG" => 'yam!' }
|
164
|
-
end
|
165
|
-
end
|
166
136
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
render :soap => {}
|
137
|
+
it "accept two parameters" do
|
138
|
+
mock_controller do
|
139
|
+
soap_action "funky", :args => { :a => :integer, :b => :string }, :return => :string
|
140
|
+
def funky
|
141
|
+
render :soap => ((params[:a] * 10).to_s + params[:b])
|
142
|
+
end
|
174
143
|
end
|
175
|
-
end
|
176
144
|
|
177
|
-
|
145
|
+
savon(:funky, :a => 42, :b => 'k')[:funky_response][:value].should == '420k'
|
146
|
+
end
|
178
147
|
end
|
179
148
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
149
|
+
context "complex actions" do
|
150
|
+
it "accept nested structures" do
|
151
|
+
mock_controller do
|
152
|
+
soap_action "getArea", :args => { :circle => { :center => { :x => :integer,
|
153
|
+
:y => :integer },
|
154
|
+
:radius => :double } },
|
155
|
+
:return => { :area => :double,
|
156
|
+
:distance_from_o => :double },
|
157
|
+
:to => :get_area
|
158
|
+
def get_area
|
159
|
+
circle = params[:circle]
|
160
|
+
render :soap => { :area => Math::PI * circle[:radius] ** 2,
|
161
|
+
:distance_from_o => Math.sqrt(circle[:center][:x] ** 2 + circle[:center][:y] ** 2) }
|
162
|
+
end
|
186
163
|
end
|
187
|
-
end
|
188
164
|
|
189
|
-
|
190
|
-
|
165
|
+
message = { :circle => { :center => { :x => 3, :y => 4 },
|
166
|
+
:radius => 5 } }
|
191
167
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
168
|
+
savon(:get_area, message)[:get_area_response].
|
169
|
+
should == ({ :area => (Math::PI * 25).to_s, :distance_from_o => (5.0).to_s })
|
170
|
+
end
|
171
|
+
|
172
|
+
it "accept arrays" do
|
173
|
+
mock_controller do
|
174
|
+
soap_action "rumba",
|
175
|
+
:args => {
|
176
|
+
:rumbas => [:integer]
|
177
|
+
},
|
178
|
+
:return => nil
|
179
|
+
def rumba
|
180
|
+
params.should == {"rumbas" => [1, 2, 3]}
|
181
|
+
render :soap => nil
|
182
|
+
end
|
198
183
|
end
|
199
|
-
end
|
200
184
|
|
201
|
-
|
202
|
-
|
203
|
-
|
185
|
+
savon(:rumba, :rumbas => [1, 2, 3])
|
186
|
+
end
|
187
|
+
|
188
|
+
it "accept nested structures inside arrays" do
|
189
|
+
mock_controller do
|
190
|
+
soap_action "rumba",
|
191
|
+
:args => {
|
192
|
+
:rumbas => [ {
|
193
|
+
:zombies => :string,
|
194
|
+
:puppies => :string
|
195
|
+
} ]
|
196
|
+
},
|
197
|
+
:return => nil
|
198
|
+
def rumba
|
199
|
+
params.should == {
|
200
|
+
"rumbas" => [
|
201
|
+
{"zombies" => 'suck', "puppies" => 'rock'},
|
202
|
+
{"zombies" => 'slow', "puppies" => 'fast'}
|
203
|
+
]
|
204
|
+
}
|
205
|
+
render :soap => nil
|
206
|
+
end
|
207
|
+
end
|
204
208
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
render :soap => ((params[:a] * 10).to_s + params[:b])
|
209
|
+
savon :rumba, :rumbas => [
|
210
|
+
{:zombies => 'suck', :puppies => 'rock'},
|
211
|
+
{:zombies => 'slow', :puppies => 'fast'}
|
212
|
+
]
|
210
213
|
end
|
211
|
-
end
|
212
214
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
215
|
+
it "respond with nested structures" do
|
216
|
+
mock_controller do
|
217
|
+
soap_action "gogogo",
|
218
|
+
:args => nil,
|
219
|
+
:return => {
|
220
|
+
:zoo => :string,
|
221
|
+
:boo => { :moo => :string, :doo => :string }
|
222
|
+
}
|
223
|
+
def gogogo
|
224
|
+
render :soap => {
|
225
|
+
:zoo => 'zoo',
|
226
|
+
:boo => { :moo => 'moo', :doo => 'doo' }
|
227
|
+
}
|
228
|
+
end
|
229
|
+
end
|
217
230
|
|
218
|
-
|
219
|
-
|
220
|
-
soap_action "getArea", :args => { :circle => { :center => { :x => :integer,
|
221
|
-
:y => :integer },
|
222
|
-
:radius => :double } },
|
223
|
-
:return => { :area => :double,
|
224
|
-
:distance_from_o => :double },
|
225
|
-
:to => :get_area
|
226
|
-
def get_area
|
227
|
-
circle = params[:circle]
|
228
|
-
render :soap => { :area => Math::PI * circle[:radius] ** 2,
|
229
|
-
:distance_from_o => Math.sqrt(circle[:center][:x] ** 2 + circle[:center][:y] ** 2) }
|
231
|
+
savon(:gogogo)[:gogogo_response].
|
232
|
+
should == {:zoo=>"zoo", :boo=>{:moo=>"moo", :doo=>"doo", :"@xsi:type"=>"tns:Boo"}}
|
230
233
|
end
|
231
|
-
end
|
232
234
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
235
|
+
it "respond with arrays" do
|
236
|
+
mock_controller do
|
237
|
+
soap_action "rumba",
|
238
|
+
:args => nil,
|
239
|
+
:return => [:integer]
|
240
|
+
def rumba
|
241
|
+
render :soap => [1, 2, 3]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
savon(:rumba)[:rumba_response].should == {:value => ["1", "2", "3"]}
|
246
|
+
end
|
238
247
|
|
239
|
-
|
240
|
-
|
248
|
+
it "respond with complex structures inside arrays" do
|
249
|
+
mock_controller do
|
250
|
+
soap_action "rumba",
|
251
|
+
:args => nil,
|
252
|
+
:return => {
|
253
|
+
:rumbas => [{:zombies => :string, :puppies => :string}]
|
254
|
+
}
|
255
|
+
def rumba
|
256
|
+
render :soap =>
|
257
|
+
{:rumbas => [
|
258
|
+
{:zombies => "suck1", :puppies => "rock1" },
|
259
|
+
{:zombies => "suck2", :puppies => "rock2" }
|
260
|
+
]
|
261
|
+
}
|
262
|
+
end
|
263
|
+
end
|
241
264
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
265
|
+
savon(:rumba)[:rumba_response].should == {
|
266
|
+
:rumbas => [
|
267
|
+
{:zombies => "suck1",:puppies => "rock1", :"@xsi:type"=>"tns:Rumbas"},
|
268
|
+
{:zombies => "suck2", :puppies => "rock2", :"@xsi:type"=>"tns:Rumbas" }
|
269
|
+
]
|
270
|
+
}
|
247
271
|
end
|
248
|
-
end
|
249
272
|
|
250
|
-
|
251
|
-
|
273
|
+
it "respond with structs in structs in arrays" do
|
274
|
+
mock_controller do
|
275
|
+
soap_action "rumba",
|
276
|
+
:args => nil,
|
277
|
+
:return => [{:rumbas => {:zombies => :integer}}]
|
252
278
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
raise self.class.const_get(:SOAPError), "you wanted one" if params[:need_error]
|
279
|
+
def rumba
|
280
|
+
render :soap => [{:rumbas => {:zombies => 100000}}, {:rumbas => {:zombies => 2}}]
|
281
|
+
end
|
282
|
+
end
|
258
283
|
|
259
|
-
|
284
|
+
savon(:rumba)[:rumba_response].should == {
|
285
|
+
:value => [
|
286
|
+
{
|
287
|
+
:rumbas => {
|
288
|
+
:zombies => "100000",
|
289
|
+
:"@xsi:type" => "tns:Rumbas"
|
290
|
+
},
|
291
|
+
:"@xsi:type" => "tns:Value"
|
292
|
+
},
|
293
|
+
{
|
294
|
+
:rumbas => {
|
295
|
+
:zombies => "2",
|
296
|
+
:"@xsi:type" => "tns:Rumbas"
|
297
|
+
},
|
298
|
+
:"@xsi:type"=>"tns:Value"
|
299
|
+
}
|
300
|
+
]
|
301
|
+
}
|
260
302
|
end
|
261
|
-
end
|
262
303
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
}.should raise_exception(Savon::SOAP::Fault)
|
273
|
-
end
|
304
|
+
context "with arrays missing" do
|
305
|
+
it "respond with simple definition" do
|
306
|
+
mock_controller do
|
307
|
+
soap_action "rocknroll",
|
308
|
+
:args => nil, :return => { :my_value => [:integer] }
|
309
|
+
def rocknroll
|
310
|
+
render :soap => {}
|
311
|
+
end
|
312
|
+
end
|
274
313
|
|
275
|
-
|
276
|
-
|
314
|
+
savon(:rocknroll)[:rocknroll_response].should be_nil
|
315
|
+
end
|
277
316
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
317
|
+
it "respond with complext definition" do
|
318
|
+
mock_controller do
|
319
|
+
soap_action "rocknroll",
|
320
|
+
:args => nil, :return => { :my_value => [{ :value => :integer}] }
|
321
|
+
def rocknroll
|
322
|
+
render :soap => {}
|
323
|
+
end
|
324
|
+
end
|
282
325
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
326
|
+
savon(:rocknroll)[:rocknroll_response].should be_nil
|
327
|
+
end
|
328
|
+
|
329
|
+
it "respond with nested simple definition" do
|
330
|
+
mock_controller do
|
331
|
+
soap_action "rocknroll",
|
332
|
+
:args => nil, :return => { :my_value => { :my_array => [{ :value => :integer}] } }
|
333
|
+
def rocknroll
|
334
|
+
render :soap => {}
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
savon(:rocknroll)[:rocknroll_response][:my_value].
|
339
|
+
should == { :"@xsi:type" => "tns:MyValue" }
|
340
|
+
end
|
288
341
|
end
|
289
342
|
end
|
290
343
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
344
|
+
context "types" do
|
345
|
+
it "recognize boolean" do
|
346
|
+
mock_controller do
|
347
|
+
soap_action "true", :args => :boolean, :return => :nil
|
348
|
+
def true
|
349
|
+
params[:value].should == true
|
350
|
+
render :soap => nil
|
351
|
+
end
|
295
352
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
}
|
306
|
-
}
|
307
|
-
def gogogo
|
308
|
-
render :soap => {
|
309
|
-
:zoo => 'zoo',
|
310
|
-
:boo => {
|
311
|
-
:moo => 'moo',
|
312
|
-
:doo => 'doo'
|
313
|
-
}
|
314
|
-
}
|
353
|
+
soap_action "false", :args => :boolean, :return => :nil
|
354
|
+
def false
|
355
|
+
params[:value].should == false
|
356
|
+
render :soap => nil
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
savon(:true, :value => true)
|
361
|
+
savon(:false, :value => false)
|
315
362
|
end
|
316
|
-
end
|
317
363
|
|
318
|
-
|
319
|
-
|
364
|
+
it "recognize dates" do
|
365
|
+
mock_controller do
|
366
|
+
soap_action "date", :args => :date, :return => :nil
|
367
|
+
def date
|
368
|
+
params[:value].should == Date.parse('2000-12-30') unless params[:value].blank?
|
369
|
+
render :soap => nil
|
370
|
+
end
|
371
|
+
end
|
320
372
|
|
321
|
-
|
322
|
-
|
323
|
-
soap_action "rumba",
|
324
|
-
:args => {
|
325
|
-
:rumbas => [:integer]
|
326
|
-
},
|
327
|
-
:return => nil
|
328
|
-
def rumba
|
329
|
-
params.should == {"rumbas" => [1, 2, 3]}
|
330
|
-
render :soap => nil
|
373
|
+
savon(:date, :value => '2000-12-30')
|
374
|
+
lambda { savon(:date) }.should_not raise_exception
|
331
375
|
end
|
332
376
|
end
|
333
377
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
378
|
+
context "errors" do
|
379
|
+
it "raise for incorrect requests" do
|
380
|
+
mock_controller do
|
381
|
+
soap_action "duty",
|
382
|
+
:args => {:bad => {:a => :string, :b => :string}, :good => {:a => :string, :b => :string}},
|
383
|
+
:return => nil
|
384
|
+
def duty
|
385
|
+
render :soap => nil
|
386
|
+
end
|
387
|
+
end
|
340
388
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
:args => {
|
345
|
-
:rumbas => [ {
|
346
|
-
:zombies => :string,
|
347
|
-
:puppies => :string
|
348
|
-
} ]
|
349
|
-
},
|
350
|
-
:return => nil
|
351
|
-
def rumba
|
352
|
-
params.should == {
|
353
|
-
"rumbas" => [
|
354
|
-
{"zombies" => 'suck', "puppies" => 'rock'},
|
355
|
-
{"zombies" => 'slow', "puppies" => 'fast'}
|
356
|
-
]
|
357
|
-
}
|
358
|
-
render :soap => nil
|
389
|
+
lambda {
|
390
|
+
savon(:duty, :bad => 42, :good => nil)
|
391
|
+
}.should raise_exception(Savon::SOAPFault)
|
359
392
|
end
|
360
|
-
end
|
361
393
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
end
|
394
|
+
it "raise to report SOAP errors" do
|
395
|
+
mock_controller do
|
396
|
+
soap_action "error", :args => { :need_error => :boolean }, :return => nil
|
397
|
+
def error
|
398
|
+
raise self.class.const_get(:SOAPError), "you wanted one" if params[:need_error]
|
399
|
+
render :soap => nil
|
400
|
+
end
|
401
|
+
end
|
371
402
|
|
372
|
-
|
373
|
-
|
374
|
-
soap_action "rumba",
|
375
|
-
:args => nil,
|
376
|
-
:return => [:integer]
|
377
|
-
def rumba
|
378
|
-
render :soap => [1, 2, 3]
|
403
|
+
lambda { savon(:error, :need_error => false) }.should_not raise_exception
|
404
|
+
lambda { savon(:error, :need_error => true) }.should raise_exception(Savon::SOAPFault)
|
379
405
|
end
|
380
|
-
end
|
381
406
|
|
382
|
-
|
383
|
-
|
407
|
+
# TODO: New Savon doesn't allow you to call methods that are not available among WSDL
|
408
|
+
xit "raise for nonexistent method" do
|
409
|
+
mock_controller
|
384
410
|
|
385
|
-
|
386
|
-
|
387
|
-
raise_runtime_exception = raise_exception(RuntimeError)
|
411
|
+
lambda { savon(:nonexistent) }.should raise_exception(Savon::SOAPFault)
|
412
|
+
end
|
388
413
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
414
|
+
it "raise for manual throws" do
|
415
|
+
mock_controller do
|
416
|
+
soap_action "error", :args => nil, :return => nil
|
417
|
+
def error
|
418
|
+
render_soap_error "a message"
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
lambda { savon(:error) }.should raise_exception(Savon::SOAPFault)
|
397
423
|
end
|
398
|
-
end
|
399
|
-
end
|
400
424
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
{:zombies => "suck1", :puppies => "rock1" },
|
412
|
-
{:zombies => "suck2", :puppies => "rock2" }
|
413
|
-
]
|
425
|
+
it "raise when response structure mismatches" do
|
426
|
+
mock_controller do
|
427
|
+
soap_action 'bad', :args => :integer, :return => {
|
428
|
+
:basic => :string,
|
429
|
+
:stallions => {
|
430
|
+
:stallion => [
|
431
|
+
:name => :string,
|
432
|
+
:wyldness => :integer,
|
433
|
+
]
|
434
|
+
},
|
414
435
|
}
|
415
|
-
|
416
|
-
|
436
|
+
def bad
|
437
|
+
render :soap => {
|
438
|
+
:basic => 'hi',
|
439
|
+
:stallions => [{:name => 'ted', :wyldness => 11}]
|
440
|
+
}
|
441
|
+
end
|
417
442
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
443
|
+
soap_action 'bad2', :args => :integer, :return => {
|
444
|
+
:basic => :string,
|
445
|
+
:telephone_booths => [:string]
|
446
|
+
}
|
447
|
+
def bad2
|
448
|
+
render :soap => {
|
449
|
+
:basic => 'hihi',
|
450
|
+
:telephone_booths => 'oops'
|
451
|
+
}
|
452
|
+
end
|
453
|
+
end
|
425
454
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
:return => [{:rumbas => {:zombies => :integer}}]
|
455
|
+
lambda { savon(:bad) }.should raise_exception(
|
456
|
+
WashOut::Dispatcher::ProgrammerError,
|
457
|
+
/SOAP response .*wyldness.*Array.*Hash.*stallion/
|
458
|
+
)
|
431
459
|
|
432
|
-
|
433
|
-
|
460
|
+
lambda { savon(:bad2) }.should raise_exception(
|
461
|
+
WashOut::Dispatcher::ProgrammerError,
|
462
|
+
/SOAP response .*oops.*String.*telephone_booths.*Array/
|
463
|
+
)
|
434
464
|
end
|
435
465
|
end
|
436
466
|
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
:zombies => "100000",
|
442
|
-
:"@xsi:type" => "tns:Rumbas"
|
443
|
-
},
|
444
|
-
:"@xsi:type" => "tns:Value"
|
445
|
-
},
|
446
|
-
{
|
447
|
-
:rumbas => {
|
448
|
-
:zombies => "2",
|
449
|
-
:"@xsi:type" => "tns:Rumbas"
|
450
|
-
},
|
451
|
-
:"@xsi:type"=>"tns:Value"
|
452
|
-
}
|
453
|
-
]
|
454
|
-
}
|
455
|
-
end
|
456
|
-
|
457
|
-
it "should handle complex structs/arrays" do
|
458
|
-
mock_controller do
|
459
|
-
soap_action "rumba",
|
460
|
-
:args => nil,
|
461
|
-
:return => {
|
462
|
-
:rumbas => [
|
463
|
-
{
|
464
|
-
:zombies => :string,
|
465
|
-
:puppies => [
|
466
|
-
{:kittens => :integer}
|
467
|
-
]
|
468
|
-
}
|
469
|
-
]
|
470
|
-
}
|
467
|
+
context "deprecates" do
|
468
|
+
it "old syntax" do
|
469
|
+
# save rspec context check
|
470
|
+
raise_runtime_exception = raise_exception(RuntimeError)
|
471
471
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
{
|
483
|
-
:zombies => "def",
|
484
|
-
:puppies => [
|
485
|
-
{:kittens => 4}
|
486
|
-
]
|
487
|
-
}
|
488
|
-
]
|
489
|
-
}
|
472
|
+
mock_controller do
|
473
|
+
lambda {
|
474
|
+
soap_action "rumba",
|
475
|
+
:args => :integer,
|
476
|
+
:return => []
|
477
|
+
}.should raise_runtime_exception
|
478
|
+
def rumba
|
479
|
+
render :soap => nil
|
480
|
+
end
|
481
|
+
end
|
490
482
|
end
|
491
483
|
end
|
492
484
|
|
493
|
-
|
494
|
-
|
495
|
-
{
|
496
|
-
:zombies => "abc",
|
497
|
-
:puppies => [
|
498
|
-
{
|
499
|
-
:kittens => "1",
|
500
|
-
:"@xsi:type" => "tns:Puppies"
|
501
|
-
},
|
502
|
-
{
|
503
|
-
:kittens => "5",
|
504
|
-
:"@xsi:type" => "tns:Puppies"
|
505
|
-
}
|
506
|
-
],
|
507
|
-
:"@xsi:type"=>"tns:Rumbas"
|
508
|
-
},
|
509
|
-
{
|
510
|
-
:zombies => "def",
|
511
|
-
:puppies => {
|
512
|
-
:kittens => "4",
|
513
|
-
:"@xsi:type" => "tns:Puppies"
|
514
|
-
},
|
515
|
-
:"@xsi:type"=>"tns:Rumbas"
|
516
|
-
}
|
517
|
-
]
|
518
|
-
}
|
519
|
-
end
|
485
|
+
it "allows arbitrary action names" do
|
486
|
+
name = 'AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything'
|
520
487
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
def date
|
527
|
-
params[:value].should == Date.parse('2000-12-30') unless params[:value].blank?
|
528
|
-
render :soap => nil
|
488
|
+
mock_controller do
|
489
|
+
soap_action name, :args => nil, :return => :integer, :to => :answer
|
490
|
+
def answer
|
491
|
+
render :soap => "forty two"
|
492
|
+
end
|
529
493
|
end
|
494
|
+
|
495
|
+
savon(name.underscore.to_sym)["#{name.underscore}_response".to_sym][:value].
|
496
|
+
should == "forty two"
|
530
497
|
end
|
531
498
|
|
532
|
-
|
533
|
-
|
534
|
-
:
|
535
|
-
|
499
|
+
it "respects :response_tag option" do
|
500
|
+
mock_controller do
|
501
|
+
soap_action "specific", :response_tag => "test", :return => :string
|
502
|
+
def specific
|
503
|
+
render :soap => "test"
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
savon(:specific).should == {:test => {:value=>"test"}}
|
536
508
|
end
|
537
509
|
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
510
|
+
it "handles snakecase option properly" do
|
511
|
+
WashOut::Engine.snakecase_input = false
|
512
|
+
WashOut::Engine.camelize_wsdl = false
|
513
|
+
|
514
|
+
mock_controller do
|
515
|
+
soap_action "rocknroll", :args => {:ZOMG => :string}, :return => nil
|
516
|
+
def rocknroll
|
517
|
+
params["ZOMG"].should == "yam!"
|
518
|
+
render :soap => nil
|
519
|
+
end
|
543
520
|
end
|
544
|
-
|
521
|
+
|
522
|
+
savon(:rocknroll, "ZOMG" => 'yam!')
|
523
|
+
end
|
524
|
+
|
545
525
|
end
|
546
526
|
|
547
|
-
describe "
|
527
|
+
describe "WS Security" do
|
548
528
|
|
549
|
-
it "
|
529
|
+
it "appends username_token to params" do
|
550
530
|
WashOut::Engine.wsse_username = nil
|
551
531
|
WashOut::Engine.wsse_password = nil
|
552
532
|
|
@@ -559,14 +539,12 @@ describe WashOut do
|
|
559
539
|
end
|
560
540
|
end
|
561
541
|
|
562
|
-
|
563
|
-
|
564
|
-
wsse.password = "secret"
|
565
|
-
soap.body = { :value => 42 }
|
542
|
+
savon(:check_token, 42) do
|
543
|
+
wsse_auth "gorilla", "secret"
|
566
544
|
end
|
567
545
|
end
|
568
546
|
|
569
|
-
it "
|
547
|
+
it "handles PasswordText auth" do
|
570
548
|
WashOut::Engine.wsse_username = "gorilla"
|
571
549
|
WashOut::Engine.wsse_password = "secret"
|
572
550
|
|
@@ -578,38 +556,23 @@ describe WashOut do
|
|
578
556
|
end
|
579
557
|
|
580
558
|
# correct auth
|
581
|
-
lambda {
|
582
|
-
|
583
|
-
|
584
|
-
wsse.password = "secret"
|
585
|
-
soap.body = { :value => 42 }
|
586
|
-
end
|
587
|
-
}.should_not raise_exception
|
559
|
+
lambda { savon(:check_auth, 42){ wsse_auth "gorilla", "secret" } }.
|
560
|
+
should_not raise_exception
|
561
|
+
|
588
562
|
# wrong user
|
589
|
-
lambda {
|
590
|
-
|
591
|
-
|
592
|
-
wsse.password = "secret"
|
593
|
-
soap.body = { :value => 42 }
|
594
|
-
end
|
595
|
-
}.should raise_exception(Savon::SOAP::Fault)
|
563
|
+
lambda { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret" } }.
|
564
|
+
should raise_exception(Savon::SOAPFault)
|
565
|
+
|
596
566
|
# wrong pass
|
597
|
-
lambda {
|
598
|
-
|
599
|
-
|
600
|
-
wsse.password = "nicetry"
|
601
|
-
soap.body = { :value => 42 }
|
602
|
-
end
|
603
|
-
}.should raise_exception(Savon::SOAP::Fault)
|
567
|
+
lambda { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry" } }.
|
568
|
+
should raise_exception(Savon::SOAPFault)
|
569
|
+
|
604
570
|
# no auth
|
605
|
-
lambda {
|
606
|
-
|
607
|
-
soap.body = { :value => 42 }
|
608
|
-
end
|
609
|
-
}.should raise_exception(Savon::SOAP::Fault)
|
571
|
+
lambda { savon(:check_auth, 42) }.
|
572
|
+
should raise_exception(Savon::SOAPFault)
|
610
573
|
end
|
611
574
|
|
612
|
-
it "
|
575
|
+
it "handles PasswordDigest auth" do
|
613
576
|
WashOut::Engine.wsse_username = "gorilla"
|
614
577
|
WashOut::Engine.wsse_password = "secret"
|
615
578
|
|
@@ -621,77 +584,22 @@ describe WashOut do
|
|
621
584
|
end
|
622
585
|
|
623
586
|
# correct auth
|
624
|
-
lambda {
|
625
|
-
|
626
|
-
wsse.credentials "gorilla", "secret", :digest
|
627
|
-
soap.body = { :value => 42 }
|
628
|
-
end
|
629
|
-
}.should_not raise_exception
|
630
|
-
# wrong user
|
631
|
-
lambda {
|
632
|
-
client.request(:check_auth) do
|
633
|
-
wsse.credentials "chimpanzee", "secret", :digest
|
634
|
-
soap.body = { :value => 42 }
|
635
|
-
end
|
636
|
-
}.should raise_exception(Savon::SOAP::Fault)
|
637
|
-
# wrong pass
|
638
|
-
lambda {
|
639
|
-
client.request(:check_auth) do
|
640
|
-
wsse.credentials "gorilla", "nicetry", :digest
|
641
|
-
soap.body = { :value => 42 }
|
642
|
-
end
|
643
|
-
}.should raise_exception(Savon::SOAP::Fault)
|
644
|
-
end
|
587
|
+
lambda { savon(:check_auth, 42){ wsse_auth "gorilla", "secret", :digest } }.
|
588
|
+
should_not raise_exception
|
645
589
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
mock_controller do
|
650
|
-
soap_action 'bad', :args => :integer, :return => {
|
651
|
-
:basic => :string,
|
652
|
-
:stallions => {
|
653
|
-
:stallion => [
|
654
|
-
:name => :string,
|
655
|
-
:wyldness => :integer,
|
656
|
-
]
|
657
|
-
},
|
658
|
-
}
|
659
|
-
def bad
|
660
|
-
render :soap => {
|
661
|
-
:basic => 'hi',
|
662
|
-
:stallions => [{:name => 'ted', :wyldness => 11}]
|
663
|
-
}
|
664
|
-
end
|
665
|
-
end
|
590
|
+
# wrong user
|
591
|
+
lambda { savon(:check_auth, 42){ wsse_auth "chimpanzee", "secret", :digest } }.
|
592
|
+
should raise_exception(Savon::SOAPFault)
|
666
593
|
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
WashOut::Dispatcher::ProgrammerError,
|
671
|
-
/SOAP response .*wyldness.*Array.*Hash.*stallion/
|
672
|
-
)
|
673
|
-
end
|
594
|
+
# wrong pass
|
595
|
+
lambda { savon(:check_auth, 42){ wsse_auth "gorilla", "nicetry", :digest } }.
|
596
|
+
should raise_exception(Savon::SOAPFault)
|
674
597
|
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
:basic => :string,
|
679
|
-
:telephone_booths => [:string]
|
680
|
-
}
|
681
|
-
def bad2
|
682
|
-
render :soap => {
|
683
|
-
:basic => 'hihi',
|
684
|
-
:telephone_booths => 'oops'
|
685
|
-
}
|
686
|
-
end
|
598
|
+
# no auth
|
599
|
+
lambda { savon(:check_auth, 42) }.
|
600
|
+
should raise_exception(Savon::SOAPFault)
|
687
601
|
end
|
688
602
|
|
689
|
-
lambda {
|
690
|
-
client.request(:bad2).to_hash[:bad_response]
|
691
|
-
}.should raise_exception(
|
692
|
-
WashOut::Dispatcher::ProgrammerError,
|
693
|
-
/SOAP response .*oops.*String.*telephone_booths.*Array/
|
694
|
-
)
|
695
603
|
end
|
696
604
|
|
697
605
|
end
|