weasel_diesel 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ class HelloWorldController < SinatraServiceController
2
+ def list
3
+ "Hello #{params[:name]}"
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ describe_service "hello_world.xml" do |service|
2
+ service.formats :xml
3
+ service.http_verb :get
4
+ service.disable_auth # on by default
5
+
6
+ service.param.string :name, :default => 'World'
7
+
8
+ service.response do |response|
9
+ response.element(:name => "greeting") do |e|
10
+ e.attribute "message" => :string, :doc => "The greeting message sent back."
11
+ end
12
+ end
13
+
14
+ service.documentation do |doc|
15
+ doc.overall "This service provides a simple hello world implementation example."
16
+ doc.params :name, "The name of the person to greet."
17
+ doc.example "<code>http://ps3.yourgame.com/hello_world.xml?name=Matt</code>"
18
+ end
19
+
20
+ end
@@ -0,0 +1,124 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe "WeaselDiesel JSON response description" do
4
+
5
+ # JSON response example
6
+ =begin
7
+ { vouchers: [
8
+ {
9
+ id : 1,
10
+ redeemed : false,
11
+ created_at : 123123123123,
12
+ option: {
13
+ id : 1231,
14
+ price: 123.32
15
+ }
16
+ },
17
+ {
18
+ id : 2,
19
+ redeemed : true,
20
+ created_at : 123123123123,
21
+ option: {
22
+ id : 1233,
23
+ price: 1.32
24
+ }
25
+ },
26
+ ] }
27
+ =end
28
+
29
+ before :all do
30
+ @timestamp = Time.now.to_i
31
+ @service = describe_service "json_list" do |service|
32
+ service.formats :json
33
+ service.response do |response|
34
+ response.array :vouchers do |node|
35
+ node.key :id
36
+ node.type :Voucher
37
+ node.string :name, :mock => "test"
38
+ node.integer :id, :doc => "Identifier"
39
+ node.boolean :redeemed
40
+ node.datetime :created_at, :mock => @timestamp
41
+ node.object :option do |option|
42
+ option.integer :id
43
+ option.integer :deal_id, :mock => 1
44
+ option.float :price
45
+ end
46
+ end
47
+ end
48
+ end
49
+ @response = @service.response
50
+ @root_node = @response.nodes.find{|n| n.name == :vouchers}
51
+
52
+ end
53
+
54
+ it "should handle the json root node" do
55
+ @root_node.should_not be_nil
56
+ end
57
+
58
+ it "should handle a node property list" do
59
+ props = @root_node.properties
60
+ props.should_not be_empty
61
+ {:id => :integer, :redeemed => :boolean, :created_at => :datetime}.each do |key, type|
62
+ prop = props.find{|prop| prop.name == key}
63
+ prop.should_not be_nil
64
+ prop.type.should == type
65
+ end
66
+ end
67
+
68
+ it "should handle a nested object with properties" do
69
+ @root_node.objects.should_not be_nil
70
+ option = @root_node.objects.find{|o| o.name == :option}
71
+ option.should_not be_nil
72
+ {:id => :integer, :deal_id => :integer, :price => :float}.each do |key, type|
73
+ prop = option.properties.find{|prop| prop.name == key}
74
+ if prop.nil?
75
+ puts option.properties.inspect
76
+ puts [key, type].inspect
77
+ end
78
+ prop.should_not be_nil
79
+ prop.type.should == type
80
+ end
81
+ end
82
+
83
+ it "should allow some meta attributes" do
84
+ atts = @root_node.meta_attributes
85
+ atts.should_not be_nil
86
+ {:key => :id, :type => :Voucher}.each do |type, value|
87
+ meta = atts.find{|att| att.type == type}
88
+ puts [type, atts].inspect if meta.nil?
89
+ meta.should_not be_nil
90
+ meta.value.should == value
91
+ end
92
+ @root_node.key.should == :id
93
+ @root_node.type.should == :Voucher
94
+ end
95
+
96
+ it "should handle mocked values properly" do
97
+ created_at = @root_node.properties.find{|prop| prop.name == :created_at}
98
+ created_at.opts[:mock].should == @timestamp
99
+ option = @root_node.objects.find{|prop| prop.name == :option}
100
+ deal_id = option.properties.find{|prop| prop.name == :deal_id}
101
+ deal_id.opts[:mock].should == 1
102
+ name = @root_node.properties.find{|prop| prop.name == :name}
103
+ name.opts[:mock].should == "test"
104
+ end
105
+
106
+ it "should allow an anonymous object at the root of the response" do
107
+ service = describe_service "json_anonymous_obj" do |service|
108
+ service.formats :json
109
+ service.response do |response|
110
+ response.object do |obj|
111
+ obj.integer :id
112
+ obj.string :foo
113
+ end
114
+ end
115
+ end
116
+ response = service.response
117
+ response.nodes.should_not be_empty
118
+ obj = response.nodes.first
119
+ obj.should_not be_nil
120
+ obj.properties.find{|prop| prop.name == :id}.should_not be_nil
121
+ obj.properties.find{|prop| prop.name == :foo}.should_not be_nil
122
+ end
123
+
124
+ end
@@ -0,0 +1,225 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+ require File.expand_path("../lib/json_response_verification", File.dirname(__FILE__))
3
+
4
+ WeaselDiesel.send(:include, JSONResponseVerification)
5
+
6
+ describe "JSON response verification" do
7
+
8
+ before :all do
9
+ @service = describe_service "json_response_verification" do |service|
10
+ service.response do |response|
11
+ response.element(:name => :user) do |user|
12
+ user.integer :id
13
+ user.string :name
14
+ user.datetime :created_at
15
+ user.object :creds do |creds|
16
+ creds.integer :id
17
+ creds.float :price
18
+ creds.boolean :enabled
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ @second_service = describe_service "anonym_obj_json_response_verification" do |service|
25
+ service.response do |response|
26
+ response.object do |user|
27
+ user.integer :id
28
+ user.string :name, :null => true
29
+ user.datetime :created_at
30
+ user.object :creds do |creds|
31
+ creds.integer :id
32
+ creds.float :price
33
+ creds.boolean :enabled
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ @third_service = describe_service "with_array" do |service|
40
+ service.response do |response|
41
+ response.array :users do |node|
42
+ node.integer :id
43
+ node.string :name
44
+ node.boolean :admin, :doc => "true if the user is an admin"
45
+ node.string :state, :doc => "test", :null => true
46
+ node.datetime :last_login_at
47
+ end
48
+ end
49
+ end
50
+
51
+ @forth_service = describe_service "with_nested_array" do |service|
52
+ service.response do |response|
53
+ response.array :users do |node|
54
+ node.integer :id
55
+ node.string :name
56
+ node.boolean :admin, :doc => "true if the user is an admin"
57
+ node.string :state, :doc => "test"
58
+ node.array :pets do |pet|
59
+ pet.integer :id
60
+ pet.string :name
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ @optional_prop_service = describe_service "opt_prop_service" do |service|
67
+ service.response do |response|
68
+ response.object do |obj|
69
+ obj.string :email, :null => true
70
+ obj.integer :city_id, :null => true
71
+ obj.string :full_name, :null => true
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+
79
+ def valid_response(namespaced=true)
80
+ response = {
81
+ "id" => 1,
82
+ "name" => "matt",
83
+ "created_at" => "2011-09-22T16:32:46-07:00",
84
+ "creds" => { "id" => 42, "price" => 2010.07, "enabled" => false }
85
+ }
86
+ namespaced ? {"user" => response} : response
87
+ end
88
+
89
+ def valid_array_response
90
+ {"users" => [
91
+ {"id" => 1,
92
+ "admin" => true,
93
+ "name" => "Heidi",
94
+ "state" => "retired",
95
+ "last_login_at" => "2011-09-22T22:46:35-07:00"
96
+ },
97
+ {"id" => 2,
98
+ "admin" => false,
99
+ "name" => "Giana",
100
+ "state" => "playing",
101
+ "last_login_at" => "2011-09-22T22:46:35-07:00"
102
+ }]
103
+ }
104
+ end
105
+
106
+ def valid_nested_array_response
107
+ {"users" => [
108
+ {"id" => 1,
109
+ "admin" => true,
110
+ "name" => "Heidi",
111
+ "state" => "retired",
112
+ "pets" => []
113
+ },
114
+ {"id" => 2,
115
+ "admin" => false,
116
+ "name" => "Giana",
117
+ "state" => "playing",
118
+ "pets" => [{"id" => 23, "name" => "medor"}, {"id" => 34, "name" => "rex"}]
119
+ }]
120
+ }
121
+ end
122
+
123
+
124
+ it "should validate the response" do
125
+ valid, errors = @service.validate_hash_response(valid_response)
126
+ errors.should == []
127
+ valid.should be_true
128
+ errors.should be_empty
129
+ end
130
+
131
+ it "should detect that the response is missing the top level object" do
132
+ response = valid_response
133
+ response.delete("user")
134
+ valid, errors = @service.validate_hash_response(response)
135
+ valid.should be_false
136
+ errors.should_not be_empty
137
+ end
138
+
139
+ it "should detect that a property integer type is wrong" do
140
+ response = valid_response
141
+ response["user"]["id"] = 'test'
142
+ valid, errors = @service.validate_hash_response(response)
143
+ valid.should be_false
144
+ errors.should_not be_empty
145
+ errors.first.should match(/id/)
146
+ errors.first.should match(/wrong type/)
147
+ end
148
+
149
+ it "should detect that an integer attribute value is nil" do
150
+ response = valid_response
151
+ response["user"]["id"] = nil
152
+ valid, errors = @service.validate_hash_response(response)
153
+ valid.should be_false
154
+ errors.should_not be_empty
155
+ errors.first.should match(/id/)
156
+ errors.first.should match(/wrong type/)
157
+ end
158
+
159
+ it "should detect that a string attribute value is nil [bug]" do
160
+ response = valid_response
161
+ response["user"]["name"] = nil
162
+ valid, errors = @service.validate_hash_response(response)
163
+ valid.should be_false
164
+ errors.should_not be_empty
165
+ errors.first.should match(/name/)
166
+ errors.first.should match(/wrong type/)
167
+ end
168
+
169
+
170
+ it "should detect that a nested object is missing" do
171
+ response = valid_response
172
+ response["user"].delete("creds")
173
+ valid, errors = @service.validate_hash_response(response)
174
+ valid.should be_false
175
+ errors.first.should match(/creds/)
176
+ errors.first.should match(/missing/)
177
+ end
178
+
179
+ it "should validate non namespaced responses" do
180
+ valid, errors = @second_service.validate_hash_response(valid_response(false))
181
+ valid.should be_true
182
+ end
183
+
184
+ it "should validate nil attributes if marked as nullable" do
185
+ response = valid_response(false)
186
+ response["name"] = nil
187
+ valid, errors = @second_service.validate_hash_response(response)
188
+ valid.should be_true
189
+ end
190
+
191
+
192
+ it "should validate array items" do
193
+ valid, errors = @third_service.validate_hash_response(valid_array_response)
194
+ valid.should be_true
195
+ errors.should be_empty
196
+ end
197
+
198
+ it "should validate an empty array" do
199
+ response = valid_array_response
200
+ response["users"] = []
201
+ valid, errors = @third_service.validate_hash_response(response)
202
+ valid.should be_true
203
+ end
204
+
205
+ it "should catch error in an array item" do
206
+ response = valid_array_response
207
+ response["users"][1]["id"] = 'test'
208
+ valid, errors = @third_service.validate_hash_response(response)
209
+ valid.should be_false
210
+ errors.should_not be_empty
211
+ end
212
+
213
+ it "should validate nested arrays" do
214
+ valid, errors = @forth_service.validate_hash_response(valid_nested_array_response)
215
+ valid.should be_true
216
+ end
217
+
218
+
219
+ it "should respect optional properties" do
220
+ valid, errors = @optional_prop_service.validate_hash_response({})
221
+ valid.should be_true
222
+ end
223
+
224
+
225
+ end
@@ -0,0 +1,102 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe ParamsVerification do
4
+
5
+ before :all do
6
+ @service = WSList.all.find{|s| s.url == 'services/test.xml'}
7
+ @service.should_not be_nil
8
+ @valid_params = {'framework' => 'RSpec', 'version' => '1.02', 'user' => {'id' => '123'}}
9
+ end
10
+
11
+ it "should validate valid params" do
12
+ params = @valid_params.dup
13
+ lambda{ ParamsVerification.validate!(params, @service.defined_params) }.should_not raise_exception
14
+ end
15
+
16
+ it "should return the params" do
17
+ params = @valid_params.dup
18
+ returned_params = ParamsVerification.validate!(params, @service.defined_params)
19
+ returned_params.should be_an_instance_of(Hash)
20
+ returned_params.keys.size.should >= 3
21
+ end
22
+
23
+ it "should set the default value for an optional param" do
24
+ params = @valid_params.dup
25
+ params['timestamp'].should be_nil
26
+ returned_params = ParamsVerification.validate!(params, @service.defined_params)
27
+ returned_params['timestamp'].should_not be_nil
28
+ end
29
+
30
+ it "should set the default value for a namespace optional param" do
31
+ params = {'framework' => 'RSpec', 'version' => '1.02', 'user' => {'id' => '123'}}
32
+ params['user']['mailing_list'].should be_nil
33
+ returned_params = ParamsVerification.validate!(params, @service.defined_params)
34
+ returned_params['user']['mailing_list'].should be_true
35
+ end
36
+
37
+ it "should raise an exception when a required param is missing" do
38
+ params = @valid_params.dup
39
+ params.delete('framework')
40
+ lambda{ ParamsVerification.validate!(params, @service.defined_params) }.should raise_exception(ParamsVerification::MissingParam)
41
+ end
42
+
43
+ it "should cast a comma delimited string into an array when param marked as an array" do
44
+ service = WSList.all.find{|s| s.url == "services/array_param.xml"}
45
+ service.should_not be_nil
46
+ params = {'seq' => "a,b,c,d,e,g"}
47
+ validated = ParamsVerification.validate!(params, service.defined_params)
48
+ validated['seq'].should == %W{a b c d e g}
49
+ end
50
+
51
+ it "should not raise an exception if a req array param doesn't contain a comma" do
52
+ service = WSList.all.find{|s| s.url == "services/array_param.xml"}
53
+ params = {'seq' => "a b c d e g"}
54
+ lambda{ ParamsVerification.validate!(params, service.defined_params) }.should_not raise_exception(ParamsVerification::InvalidParamType)
55
+ end
56
+
57
+ it "should raise an exception when a param is of the wrong type" do
58
+ params = @valid_params.dup
59
+ params['user']['id'] = 'abc'
60
+ lambda{ ParamsVerification.validate!(params, @service.defined_params) }.should raise_exception(ParamsVerification::InvalidParamType)
61
+ end
62
+
63
+ it "should raise an exception when a param is under the minvalue" do
64
+ params = @valid_params.dup
65
+ params['num'] = 1
66
+ lambda{ ParamsVerification.validate!(params, @service.defined_params) }.should raise_exception(ParamsVerification::InvalidParamType)
67
+ end
68
+
69
+ it "should raise an exception when a param isn't in the param option list" do
70
+ params = @valid_params.dup
71
+ params['alpha'] = 'z'
72
+ lambda{ ParamsVerification.validate!(params, @service.defined_params) }.should raise_exception(ParamsVerification::InvalidParamValue)
73
+ end
74
+
75
+ it "should raise an exception when a nested optional param isn't in the param option list" do
76
+ params = @valid_params.dup
77
+ params['user']['sex'] = 'large'
78
+ lambda{ ParamsVerification.validate!(params, @service.defined_params) }.should raise_exception(ParamsVerification::InvalidParamType)
79
+ # other service
80
+ params = {'preference' => {'region_code' => 'us', 'language_code' => 'de'}}
81
+ service = WSList.all.find{|s| s.url == 'preferences.xml'}
82
+ service.should_not be_nil
83
+ lambda{ ParamsVerification.validate!(params, service.defined_params) }.should raise_exception(ParamsVerification::InvalidParamValue)
84
+ end
85
+
86
+ it "should raise an exception when a required param is present but doesn't match the limited set of options" do
87
+ service = describe_service "search" do |service|
88
+ service.params { |p| p.string :by, :options => ['name', 'code', 'last_four'], :required => true }
89
+ end
90
+ params = {'by' => 'foo'}
91
+ lambda{ ParamsVerification.validate!(params, service.defined_params) }.should raise_exception(ParamsVerification::InvalidParamValue)
92
+ end
93
+
94
+
95
+ it "should validate that no params are passed when accept_no_params! is set on a service" do
96
+ service = WSList.all.find{|s| s.url == "services/test_no_params.xml"}
97
+ service.should_not be_nil
98
+ params = @valid_params.dup
99
+ lambda{ ParamsVerification.validate!(params, service.defined_params) }.should raise_exception
100
+ end
101
+
102
+ end