sonar 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,284 @@
1
+ module SonarTest__cookies
2
+
3
+ class App < Air
4
+
5
+ def index names
6
+ cookies.values_at(*names.split(',')).inspect
7
+ end
8
+
9
+ def post_index
10
+ post_params.each_pair do |n, v|
11
+ v.is_a?(Hash) &&
12
+ (expires = v['expires']) &&
13
+ (v['expires'] = ::Time.parse(expires))
14
+ response.set_cookie n, v
15
+ end
16
+ end
17
+
18
+ def delete_index names
19
+ names.split(',').each do |n|
20
+ response.delete_cookie n, params[n] || {}
21
+ end
22
+ end
23
+
24
+ def post_deeper__path
25
+ post_params.each_pair { |n, v| response.set_cookie n, v }
26
+ end
27
+
28
+ def deeper name
29
+ cookies[name]
30
+ end
31
+
32
+ end
33
+
34
+ Spec.new App do
35
+
36
+ Testing 'via HTTP' do
37
+
38
+ before do
39
+ @var, @val = 2.times.map { 5.times.map { (('a'..'z').to_a + ('A'..'Z').to_a + (1..50).to_a)[rand(100)] }.join }
40
+ @expected, @expected_nil = [@val].inspect, [nil].inspect
41
+ end
42
+
43
+ Should 'persist/dispose cause by default cookie`s path is set to current URI path' do
44
+ post @var => @val
45
+ o 'persisted?'
46
+ is(cookies[@var]) == @val
47
+ o 'disposed?'
48
+ r = get @var
49
+ expect(r.body) == @expected
50
+ end
51
+
52
+ Should 'persist/dispose cause given path matches default cookie`s path' do
53
+ post @var => {:value => @val, :path => '/'}
54
+ o 'persisted?'
55
+ is(cookies[@var]) == @val
56
+ o 'disposed?'
57
+ r = get @var
58
+ expect(r.body) == @expected
59
+ end
60
+
61
+ Should 'NOT persist/dispose cause wrong path provided - /blah is not a prefix of /' do
62
+ post @var => {:value => @val, :path => '/blah'}
63
+ o 'persisted?'
64
+ is(cookies[@var]).nil?
65
+ o 'disposed?'
66
+ r = get @var
67
+ expect(r.body) == @expected_nil
68
+ end
69
+
70
+ Should 'persist/dispose cause /deeper is a prefix of /deeper/path' do
71
+ post '/deeper/path', @var => @val
72
+ o 'persisted?'
73
+ is(cookies[@var]) == @val
74
+ o 'disposed?'
75
+ r = get '/deeper', @var
76
+ expect(r.body) == @val
77
+ end
78
+
79
+ Should 'NOT persist but not dispose cause path set automatically to /deeper, and it is not a prefix for /' do
80
+ post '/deeper/path', @var => @val
81
+ o 'persisted?'
82
+ is(cookies[@var]) == @val
83
+ o 'disposed?'
84
+ r = get @var
85
+ expect(r.body) == @expected_nil
86
+
87
+ Should 'dispose for /deeper path', :hooks => nil do
88
+
89
+ r = get '/deeper', @var
90
+ expect(r.body) == @val
91
+ end
92
+ end
93
+
94
+ Should 'persist/dispose cause path set to /' do
95
+ post '/deeper/path', @var => {:value => @val, :path => '/'}
96
+ o 'persisted?'
97
+ is(cookies[@var]) == @val
98
+ o 'disposed?'
99
+ r = get @var
100
+ expect(r.body) == @expected
101
+ end
102
+
103
+ Should 'NOT dispose - expires is in past' do
104
+ post @var => {:value => @val, :expires => ::Rack::Utils.rfc2822(::Time.now.gmtime - 1)}
105
+ o 'disposed?'
106
+ r = get @var
107
+ expect(r.body) == @expected_nil
108
+ end
109
+
110
+ Should 'NOT persist/dispose cause inner domain given' do
111
+ post @var => {:value => @val, :domain => 'x.org'}
112
+ o 'persisted?'
113
+ is(cookies[@var]).nil?
114
+ o 'disposed?'
115
+ r = get @var
116
+ expect(r.body) == @expected_nil
117
+ end
118
+
119
+ Should 'persist/dispose - domains matches' do
120
+ host = 'random.tld'
121
+
122
+ header['HTTP_HOST'] = host
123
+ post 'http://' + host, @var => @val
124
+ o 'disposed?'
125
+
126
+ header['HTTP_HOST'] = host
127
+ r = get 'http://' + host, @var
128
+ expect(r.body) == @expected
129
+ headers.delete 'HTTP_HOST'
130
+
131
+ Should 'NOT dispose cause requested from foreign domain' do
132
+ r = get @var
133
+ expect(r.body) == @expected_nil
134
+
135
+ header['HTTP_HOST'] = 'x.org'
136
+ r = get 'http://x.org', @var
137
+ expect(r.body) == @expected_nil
138
+ headers.delete 'HTTP_HOST'
139
+ end
140
+ end
141
+
142
+ Should 'use separate jar for each domain' do
143
+ header['HTTP_HOST'] = 'foo.bar'
144
+ domain = 'http://' + header['HTTP_HOST']
145
+ o domain
146
+ post domain, 'var' => domain
147
+ r = get domain, 'var'
148
+ expect(r.body) == [domain].inspect
149
+ headers.delete 'HTTP_HOST'
150
+
151
+ header['HTTP_HOST'] = 'bar.foo'
152
+ domain = 'http://' + header['HTTP_HOST']
153
+ o domain
154
+ post domain, 'var' => domain
155
+ r = get domain, 'var'
156
+ expect(r.body) == [domain].inspect
157
+ headers.delete 'HTTP_HOST'
158
+
159
+ header['HTTP_HOST'] = 'foo.bar'
160
+ domain = 'http://' + header['HTTP_HOST']
161
+ o domain
162
+ r = get domain, 'var'
163
+ expect(r.body) == [domain].inspect
164
+ headers.delete 'HTTP_HOST'
165
+
166
+ And 'use same jar for a domain and its subdomains' do
167
+ %w[a b c a.b a.b.c].each do |subdomain|
168
+ header['HTTP_HOST'] = '%s.foo.bar' % subdomain
169
+ domain = 'http://' + header['HTTP_HOST']
170
+ o domain
171
+ r = get domain, 'var'
172
+ expect(r.body) == ['http://foo.bar'].inspect
173
+ headers.delete 'HTTP_HOST'
174
+ end
175
+ end
176
+
177
+ And 'domains names are case insensitive' do
178
+ %w[BAR.foo bar.FOO BAR.FOO].each do |host|
179
+ header['HTTP_HOST'] = host
180
+ domain = 'http://' + header['HTTP_HOST']
181
+ o domain
182
+ r = get domain, 'var'
183
+ expect(r.body) == ['http://bar.foo'].inspect
184
+ headers.delete 'HTTP_HOST'
185
+ end
186
+ end
187
+
188
+ end
189
+
190
+ Should 'prefer more specific cookies' do
191
+ domain = 'http://foo.bar'
192
+ subdomain = 'http://a.foo.bar'
193
+
194
+ header['HTTP_HOST'] = 'a.foo.bar'
195
+ post subdomain, 'var' => subdomain
196
+
197
+ header['HTTP_HOST'] = 'foo.bar'
198
+ post domain, 'var' => domain
199
+
200
+ r = get domain, 'var'
201
+ expect(r.body) == [domain].inspect
202
+
203
+ header['HTTP_HOST'] = 'a.foo.bar'
204
+ r = get subdomain, 'var'
205
+ expect(r.body) == [subdomain].inspect
206
+ headers.delete 'HTTP_HOST'
207
+ end
208
+
209
+ Should 'NOT persist/dispose cause secure cookie are accessed via un-secure connection' do
210
+ post @var => {:value => @val, :secure => 'true'}
211
+ o 'persisted?'
212
+ is(cookies[@var]).nil?
213
+ o 'disposed?'
214
+ r = get @var
215
+ expect(r.body) == @expected_nil
216
+ end
217
+
218
+ Should 'persist/dispose cause secure cookie are accessed via secure connection' do
219
+ s_post @var => {:value => @val, :secure => 'true'}
220
+ o 'persisted?'
221
+ is(cookies[@var]) == @val
222
+ o 'disposed?'
223
+ r = s_get @var
224
+ expect(r.body) == @expected
225
+ end
226
+
227
+ Should 'delete a cookie' do
228
+ o 'setting'
229
+ post @var => @val
230
+ r = get @var
231
+ is(r.body) == @expected
232
+
233
+ o 'deleting'
234
+ delete @var
235
+ r = get @var
236
+ expect(r.body) == @expected_nil
237
+ end
238
+
239
+ Should 'set/get multiple cookies at once' do
240
+ vars, vals = 2.times.map { 5.times.map { 5.times.map { ('a'..'z').to_a[rand(26)] }.join } }
241
+ params = Hash[vars.zip vals]
242
+ post params
243
+ r = get vars.join(',')
244
+ expect(r.body) == params.values_at(*vars).inspect
245
+ end
246
+ end
247
+
248
+ Testing :directly do
249
+
250
+ n, size = 10, cookies.size
251
+ n.times do
252
+ var, val = 2.times.map { 5.times.map { ('a'..'z').to_a[rand(26)] }.join }
253
+ cookies[var] = val
254
+ expect(cookies[var]) == val
255
+ end
256
+ expect(cookies.size) == size + n
257
+
258
+ Should 'delete a cookie' do
259
+
260
+ cookies['foo'] = 'bar'
261
+ expect(cookies['foo']) == 'bar'
262
+
263
+ cookies.delete 'foo'
264
+ refute(cookies['foo']) == 'bar'
265
+ is(cookies['foo']).nil?
266
+ end
267
+
268
+ Should 'clear cookies' do
269
+ cookies.clear
270
+ expect(cookies.size) == 0
271
+ end
272
+
273
+ Should 'escape values' do
274
+ cookies['var'] = 'foo;bar'
275
+ expect(cookies['var']) == 'foo;bar'
276
+
277
+ cookies['var'] = ';bar;foo;'
278
+ expect(cookies['var']) == ';bar;foo;'
279
+ end
280
+
281
+ end
282
+
283
+ end
284
+ end
@@ -0,0 +1,40 @@
1
+ module SonarTest__redirect
2
+
3
+ class App < Air
4
+
5
+ def index
6
+ redirect :destination
7
+ end
8
+
9
+ def destination
10
+ __method__
11
+ end
12
+
13
+ end
14
+
15
+ Spec.new App do
16
+
17
+ get
18
+ is(last_response.status) == 302
19
+
20
+ follow_redirect!
21
+ is(last_response.status) == 200
22
+ is(last_response.body) == 'destination'
23
+
24
+ Should 'keep scheme' do
25
+ s_get
26
+ is(last_response.status) == 302
27
+
28
+ follow_redirect!
29
+ is(last_request.env['HTTPS']) == 'on'
30
+ is(last_response.status) == 200
31
+ is(last_response.body) == 'destination'
32
+ end
33
+
34
+ Should 'raise an error if last response is not an redirect' do
35
+ get :destination
36
+ does { follow_redirect! }.raise_error?
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,94 @@
1
+ module SonarTest__headers
2
+
3
+ class App < Air
4
+
5
+ def index headers
6
+ env.values_at(*headers.split(',')).inspect
7
+ end
8
+
9
+ def post_index
10
+ content_type
11
+ end
12
+
13
+ def dry
14
+ end
15
+
16
+ def post_dry
17
+ end
18
+
19
+ end
20
+
21
+ Spec.new App do
22
+
23
+ Testing 'User-Agent' do
24
+ reset_app!
25
+
26
+ ua = 'Chrome'
27
+ header['User-Agent'] = ua
28
+ r = get 'HTTP_USER_AGENT'
29
+ is(r.body) == [ua].inspect
30
+
31
+ ua = 'Safari'
32
+ header['User-Agent'] = ua
33
+ r = get 'HTTP_USER_AGENT'
34
+ is(r.body) == [ua].inspect
35
+ end
36
+
37
+ Testing 'Content-Type' do
38
+ reset_app!
39
+
40
+ ct = 'text/plain'
41
+ header['Content-Type'] = ct
42
+ r = get 'CONTENT_TYPE'
43
+ expect(r.body) == [ct].inspect
44
+
45
+ Should 'not override explicit CONTENT_TYPE on POST requests' do
46
+
47
+ ct = 'text/plain'
48
+ header['Content-Type'] = ct
49
+ r = post
50
+ expect(r.body) == ct
51
+ end
52
+ end
53
+
54
+ Should 'have 127.0.0.1 as default REMOTE_ADDR' do
55
+ reset_app!
56
+
57
+ get
58
+ expect(last_request.env['REMOTE_ADDR']) == '127.0.0.1'
59
+ end
60
+
61
+ Should 'have sonar.org as default SERVER_NAME' do
62
+ reset_app!
63
+
64
+ get
65
+ expect(last_request.env['SERVER_NAME']) == 'sonar.org'
66
+ end
67
+
68
+ Setting 'Rack-related headers' do
69
+ reset_app!
70
+
71
+ When 'setting rack.input explicitly' do
72
+
73
+ It 'should override default rack.input' do
74
+ header['rack.input'] = StringIO.new('someString')
75
+ get :dry
76
+ expect(last_request.env['rack.input']) == header['rack.input']
77
+ end
78
+
79
+ And 'not add multipart content type on post requests' do
80
+ post :dry
81
+ refute(last_request.env['CONTENT_TYPE']) =~ /x\-www\-form\-urlencoded/
82
+ end
83
+ end
84
+
85
+ Should 'keep explicitly set rack.errors' do
86
+ errors = StringIO.new
87
+ header['rack.errors'] = errors
88
+ get
89
+ expect { last_request.env['rack.errors'].__id__ } == errors.__id__
90
+ end
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,73 @@
1
+ module SonarTest__map
2
+
3
+ class App < Air
4
+
5
+ def news a1
6
+ a1
7
+ end
8
+
9
+ end
10
+
11
+ Spec.new App do
12
+
13
+ Testing 'without map' do
14
+ get '/news/1'
15
+ expect(last_response.status) == 200
16
+ expect(last_response.body) == '1'
17
+ end
18
+
19
+ When 'setting map' do
20
+ map '/news'
21
+
22
+ It 'should work only with arguments' do
23
+ get 1
24
+ expect(last_response.status) == 200
25
+ expect(last_response.body) == '1'
26
+ end
27
+
28
+ And 'if map including arguments as well' do
29
+ map '/news/foo'
30
+
31
+ It 'should work without arguments' do
32
+ get
33
+ expect(last_response.status) == 200
34
+ expect(last_response.body) == 'foo'
35
+ end
36
+ end
37
+ end
38
+
39
+ When 'map cleared' do
40
+ map nil
41
+
42
+ It 'should require full url' do
43
+ get
44
+ expect(last_response.status) == 404
45
+
46
+ get 'foo'
47
+ expect(last_response.status) == 404
48
+
49
+ get '/news/foo'
50
+ expect(last_response.status) == 200
51
+ end
52
+ end
53
+
54
+ When 'requests starting with a slash or protocol' do
55
+ map '/blah'
56
+
57
+ It 'should ignore base URL set by map' do
58
+ get 'news/foo'
59
+ expect(last_response.status) == 404
60
+
61
+ get '/news/foo'
62
+ expect(last_response.status) == 200
63
+
64
+ get 'http://blah.org/news/foo'
65
+ is(last_response).not_found?
66
+
67
+ header['HTTP_HOST'] = 'blah.org'
68
+ get 'http://blah.org/news/foo'
69
+ is(last_response).ok?
70
+ end
71
+ end
72
+ end
73
+ end