deas 0.43.3 → 0.43.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,7 +28,7 @@ module Deas
28
28
 
29
29
  # ignore captures when setting params
30
30
  # remove duplicate forward slashes
31
- set_anchor(set_extra(set_named(set_splat(@path, s), h), h), a).gsub(/\/\/+/, '/')
31
+ set_anchor(set_extra(set_named(set_splat(@path, s), h).gsub(/\/\/+/, '/'), h), a)
32
32
  end
33
33
 
34
34
  private
@@ -1,3 +1,3 @@
1
1
  module Deas
2
- VERSION = "0.43.3"
2
+ VERSION = "0.43.4"
3
3
  end
@@ -73,6 +73,7 @@ module Deas
73
73
  def headers(*args); @deas_runner.headers(*args); end
74
74
  def body(*args); @deas_runner.body(*args); end
75
75
  def content_type(*args); @deas_runner.content_type(*args); end
76
+ def set_cookie(*args); @deas_runner.set_cookie(*args); end
76
77
  def halt(*args); @deas_runner.halt(*args); end
77
78
  def redirect(*args); @deas_runner.redirect(*args); end
78
79
  def send_file(*args); @deas_runner.send_file(*args); end
@@ -41,8 +41,8 @@ module Factory
41
41
  Deas::RequestData.new({
42
42
  :request => args[:request] || Factory.request,
43
43
  :response => args[:response] || Factory.response,
44
- :params => args[:params] || { Factory.string => Factory.string },
45
- :route_path => args[:route_path] || Factory.string
44
+ :route_path => args[:route_path] || Factory.string,
45
+ :params => args[:params] || { Factory.string => Factory.string }
46
46
  })
47
47
  end
48
48
 
@@ -22,9 +22,7 @@ class FakeSinatraCall
22
22
  @status = 200
23
23
  @headers = {}
24
24
 
25
- @settings = OpenStruct.new({
26
- :deas_server_data => Factory.server_data
27
- }.merge(settings || {}))
25
+ @settings = OpenStruct.new(settings || {})
28
26
  end
29
27
 
30
28
  def call(env)
@@ -69,6 +69,40 @@ class DeasDevServer
69
69
 
70
70
  end
71
71
 
72
+ class RemoveTrailingSlashesServer
73
+ include Deas::Server
74
+
75
+ root TEST_SUPPORT_ROOT
76
+ logger TEST_LOGGER
77
+ verbose_logging true
78
+ show_exceptions true
79
+
80
+ router do
81
+ remove_trailing_slashes
82
+
83
+ get '/show', 'ShowHandler'
84
+ end
85
+
86
+ end
87
+
88
+ class AllowTrailingSlashesServer
89
+ include Deas::Server
90
+
91
+ root TEST_SUPPORT_ROOT
92
+ logger TEST_LOGGER
93
+ verbose_logging true
94
+ show_exceptions true
95
+
96
+ router do
97
+ allow_trailing_slashes
98
+
99
+ get '/show', 'ShowHandler'
100
+ get '/show-text/', 'ShowTextHandler'
101
+
102
+ end
103
+
104
+ end
105
+
72
106
  class ShowHandler
73
107
  include Deas::ViewHandler
74
108
 
@@ -152,7 +152,7 @@ module Deas
152
152
 
153
153
  assert_equal 404, last_response.status
154
154
  assert_equal "text/plain", last_response.headers['Content-Type']
155
- assert_match "Deas::NotFound: /not_defined", last_response.body
155
+ assert_match "Deas::NotFound: GET /not_defined", last_response.body
156
156
  end
157
157
 
158
158
  should "return a text/plain body when an exception occurs" do
@@ -165,4 +165,45 @@ module Deas
165
165
 
166
166
  end
167
167
 
168
+ class RemoveTrailingSlashesTests < RackTestsContext
169
+ desc "a Deas server rack app with a router that requires no trailing slashes"
170
+ setup do
171
+ @app = RemoveTrailingSlashesServer.new
172
+ end
173
+
174
+ should "redirect any paths that end in a slash" do
175
+ get '/show/'
176
+
177
+ assert_equal 302, last_response.status
178
+ assert_equal '/show', last_response.headers['Location']
179
+ end
180
+
181
+ end
182
+
183
+ class AllowTrailingSlashesTests < RackTestsContext
184
+ desc "a Deas server rack app with a router that allows trailing slashes"
185
+ setup do
186
+ @app = AllowTrailingSlashesServer.new
187
+ end
188
+
189
+ should "serve any found paths regardless of whether they end with a slash" do
190
+ get '/show'
191
+ assert_equal 200, last_response.status
192
+ assert_equal 'text/html;charset=utf-8', last_response.headers['Content-Type']
193
+
194
+ get '/show/'
195
+ assert_equal 200, last_response.status
196
+ assert_equal 'text/html;charset=utf-8', last_response.headers['Content-Type']
197
+
198
+ get '/show-text'
199
+ assert_equal 200, last_response.status
200
+ assert_equal 'text/plain', last_response.headers['Content-Type']
201
+
202
+ get '/show-text/'
203
+ assert_equal 200, last_response.status
204
+ assert_equal 'text/plain', last_response.headers['Content-Type']
205
+ end
206
+
207
+ end
208
+
168
209
  end
@@ -12,21 +12,21 @@ class Deas::ErrorHandler
12
12
  @server_data = Factory.server_data(:error_procs => @error_proc_spies)
13
13
  @request = Factory.string
14
14
  @response = Factory.string
15
+ @route_path = Factory.string
15
16
  @handler_class = Factory.string
16
17
  @handler = Factory.string
17
18
  @params = Factory.string
18
19
  @splat = Factory.string
19
- @route_path = Factory.string
20
20
 
21
21
  @context_hash = {
22
22
  :server_data => @server_data,
23
23
  :request => @request,
24
24
  :response => @response,
25
+ :route_path => @route_path,
25
26
  :handler_class => @handler_class,
26
27
  :handler => @handler,
27
28
  :params => @params,
28
- :splat => @splat,
29
- :route_path => @route_path
29
+ :splat => @splat
30
30
  }
31
31
 
32
32
  @error_handler_class = Deas::ErrorHandler
@@ -117,18 +117,18 @@ class Deas::ErrorHandler
117
117
  subject{ @context }
118
118
 
119
119
  should have_readers :server_data
120
- should have_readers :request, :response, :handler_class, :handler
121
- should have_readers :params, :splat, :route_path
120
+ should have_readers :request, :response
121
+ should have_readers :route_path, :handler_class, :handler, :params, :splat
122
122
 
123
123
  should "know its attributes" do
124
124
  assert_equal @context_hash[:server_data], subject.server_data
125
125
  assert_equal @context_hash[:request], subject.request
126
126
  assert_equal @context_hash[:response], subject.response
127
+ assert_equal @context_hash[:route_path], subject.route_path
127
128
  assert_equal @context_hash[:handler_class], subject.handler_class
128
129
  assert_equal @context_hash[:handler], subject.handler
129
130
  assert_equal @context_hash[:params], subject.params
130
131
  assert_equal @context_hash[:splat], subject.splat
131
- assert_equal @context_hash[:route_path], subject.route_path
132
132
  end
133
133
 
134
134
  should "know if it equals another context" do
@@ -139,11 +139,11 @@ class Deas::ErrorHandler
139
139
  :server_data => Factory.server_data,
140
140
  :request => Factory.string,
141
141
  :response => Factory.string,
142
+ :route_path => Factory.string,
142
143
  :handler_class => Factory.string,
143
144
  :handler => Factory.string,
144
145
  :params => Factory.string,
145
146
  :splat => Factory.string,
146
- :route_path => Factory.string
147
147
  })
148
148
  assert_not_equal exp, subject
149
149
  end
@@ -62,8 +62,8 @@ class Deas::HandlerProxy
62
62
  :router => @server_data.router,
63
63
  :template_source => @server_data.template_source,
64
64
  :request => @request_data.request,
65
- :params => @request_data.params,
66
- :route_path => @request_data.route_path
65
+ :route_path => @request_data.route_path,
66
+ :params => @request_data.params
67
67
  }
68
68
  assert_equal exp_args, @runner_spy.args
69
69
 
@@ -71,6 +71,9 @@ class Deas::HandlerProxy
71
71
  end
72
72
 
73
73
  should "add data to the request env to make it available to Rack" do
74
+ exp = @runner_spy.route_path
75
+ assert_equal exp, @request_data.request.env['deas.route_path']
76
+
74
77
  exp = subject.handler_class
75
78
  assert_equal exp, @request_data.request.env['deas.handler_class']
76
79
 
@@ -82,17 +85,14 @@ class Deas::HandlerProxy
82
85
 
83
86
  exp = @runner_spy.splat
84
87
  assert_equal exp, @request_data.request.env['deas.splat']
85
-
86
- exp = @runner_spy.route_path
87
- assert_equal exp, @request_data.request.env['deas.route_path']
88
88
  end
89
89
 
90
90
  should "log the handler class name and the params" do
91
91
  exp_msgs = [
92
+ " Route: #{@runner_spy.route_path.inspect}",
92
93
  " Handler: #{subject.handler_class.name}",
93
94
  " Params: #{@runner_spy.params.inspect}",
94
- " Splat: #{@runner_spy.splat.inspect}",
95
- " Route: #{@runner_spy.route_path.inspect}"
95
+ " Splat: #{@runner_spy.splat.inspect}"
96
96
  ]
97
97
  assert_equal exp_msgs, @request_data.request.logging_msgs
98
98
  end
@@ -7,11 +7,11 @@ module Deas::Logging
7
7
  desc "Deas::Logging"
8
8
  subject{ Deas::Logging }
9
9
 
10
- should have_imeths :middleware_args
10
+ should have_imeths :middleware_type
11
11
 
12
12
  should "return middleware args given a verbose flag" do
13
- assert_equal [Deas::VerboseLogging], subject.middleware_args(true)
14
- assert_equal [Deas::SummaryLogging], subject.middleware_args(false)
13
+ assert_equal Deas::VerboseLogging, subject.middleware_type(true)
14
+ assert_equal Deas::SummaryLogging, subject.middleware_type(false)
15
15
  end
16
16
 
17
17
  end
@@ -19,9 +19,7 @@ module Deas::Logging
19
19
  class CallSetupTests < UnitTests
20
20
  setup do
21
21
  @logger = SpyLogger.new
22
- @app = Factory.sinatra_call({
23
- :deas_server_data => Factory.server_data(:logger => @logger)
24
- })
22
+ @app = Factory.sinatra_call
25
23
 
26
24
  @app_call_env = nil
27
25
  @resp_status = Factory.integer
@@ -60,7 +58,7 @@ module Deas::Logging
60
58
  @benchmark
61
59
  end
62
60
 
63
- @middleware = @middleware_class.new(@app)
61
+ @middleware = @middleware_class.new(@app, @logger)
64
62
  end
65
63
  subject{ @middleware }
66
64
 
@@ -131,7 +129,7 @@ module Deas::Logging
131
129
  @resp_status = @middleware_class::RESPONSE_STATUS_NAMES.keys.sample
132
130
  @app_response[0] = @resp_status
133
131
 
134
- @middleware = Deas::VerboseLogging.new(@app)
132
+ @middleware = Deas::VerboseLogging.new(@app, @logger)
135
133
  end
136
134
  subject{ @middleware }
137
135
 
@@ -213,7 +211,7 @@ module Deas::Logging
213
211
  'deas.handler_class' => @handler_class
214
212
  })
215
213
 
216
- @middleware = Deas::SummaryLogging.new(@app)
214
+ @middleware = Deas::SummaryLogging.new(@app, @logger)
217
215
  end
218
216
  subject{ @middleware }
219
217
 
@@ -8,25 +8,25 @@ class Deas::RequestData
8
8
  setup do
9
9
  @request = Factory.string
10
10
  @response = Factory.string
11
- @params = Factory.string
12
11
  @route_path = Factory.string
12
+ @params = Factory.string
13
13
 
14
14
  @request_data = Deas::RequestData.new({
15
15
  :request => @request,
16
16
  :response => @response,
17
- :params => @params,
18
- :route_path => @route_path
17
+ :route_path => @route_path,
18
+ :params => @params
19
19
  })
20
20
  end
21
21
  subject{ @request_data }
22
22
 
23
- should have_readers :request, :response, :params, :route_path
23
+ should have_readers :request, :response, :route_path, :params
24
24
 
25
25
  should "know its attributes" do
26
26
  assert_equal @request, subject.request
27
27
  assert_equal @response, subject.response
28
- assert_equal @params, subject.params
29
28
  assert_equal @route_path, subject.route_path
29
+ assert_equal @params, subject.params
30
30
  end
31
31
 
32
32
  should "default its attributes when they aren't provided" do
@@ -34,16 +34,16 @@ class Deas::RequestData
34
34
 
35
35
  assert_nil request_data.request
36
36
  assert_nil request_data.response
37
- assert_nil request_data.params
38
37
  assert_nil request_data.route_path
38
+ assert_nil request_data.params
39
39
  end
40
40
 
41
41
  should "know if it is equal to another request data" do
42
42
  request_data = Deas::RequestData.new({
43
43
  :request => @request,
44
44
  :response => @response,
45
- :params => @params,
46
- :route_path => @route_path
45
+ :route_path => @route_path,
46
+ :params => @params
47
47
  })
48
48
  assert_equal request_data, subject
49
49
 
@@ -19,6 +19,12 @@ class Deas::Router
19
19
  assert_equal 'default', subject::DEFAULT_REQUEST_TYPE_NAME
20
20
  end
21
21
 
22
+ should "know its trailing slashes constants" do
23
+ assert_equal 'remove', subject::REMOVE_TRAILING_SLASHES
24
+ assert_equal 'allow', subject::ALLOW_TRAILING_SLASHES
25
+ assert_equal '/', subject::SLASH
26
+ end
27
+
22
28
  end
23
29
 
24
30
  class InitTests < UnitTests
@@ -32,9 +38,13 @@ class Deas::Router
32
38
  subject{ @router }
33
39
 
34
40
  should have_readers :request_types, :urls, :routes, :definitions
35
- should have_readers :escape_query_value_proc
41
+ should have_readers :trailing_slashes, :escape_query_value_proc
36
42
 
37
- should have_imeths :view_handler_ns, :escape_query_value
43
+ should have_imeths :view_handler_ns
44
+ should have_imeths :allow_trailing_slashes, :allow_trailing_slashes_set?
45
+ should have_imeths :remove_trailing_slashes, :remove_trailing_slashes_set?
46
+ should have_imeths :trailing_slashes_set?
47
+ should have_imeths :escape_query_value
38
48
  should have_imeths :base_url, :set_base_url, :prepend_base_url
39
49
  should have_imeths :url, :url_for
40
50
  should have_imeths :default_request_type_name, :add_request_type
@@ -42,10 +52,12 @@ class Deas::Router
42
52
  should have_imeths :get, :post, :put, :patch, :delete
43
53
  should have_imeths :route, :redirect, :not_found
44
54
  should have_imeths :apply_definitions!, :validate!
55
+ should have_imeths :validate_trailing_slashes!
45
56
 
46
57
  should "default its attrs" do
47
58
  router = @router_class.new
48
59
  assert_nil router.view_handler_ns
60
+ assert_nil router.trailing_slashes
49
61
  assert_nil router.base_url
50
62
  assert_empty router.request_types
51
63
  assert_empty router.urls
@@ -74,6 +86,26 @@ class Deas::Router
74
86
  assert_equal exp, subject.view_handler_ns
75
87
  end
76
88
 
89
+ should "config trailing slash handling" do
90
+ assert_false subject.allow_trailing_slashes_set?
91
+ assert_false subject.remove_trailing_slashes_set?
92
+ assert_false subject.trailing_slashes_set?
93
+
94
+ subject.allow_trailing_slashes
95
+
96
+ assert_equal subject.class::ALLOW_TRAILING_SLASHES, subject.trailing_slashes
97
+ assert_true subject.allow_trailing_slashes_set?
98
+ assert_false subject.remove_trailing_slashes_set?
99
+ assert_true subject.trailing_slashes_set?
100
+
101
+ subject.remove_trailing_slashes
102
+
103
+ assert_equal subject.class::REMOVE_TRAILING_SLASHES, subject.trailing_slashes
104
+ assert_false subject.allow_trailing_slashes_set?
105
+ assert_true subject.remove_trailing_slashes_set?
106
+ assert_true subject.trailing_slashes_set?
107
+ end
108
+
77
109
  should "allow configuring a custom escape query value proc" do
78
110
  escape_proc = proc{ Factory.string }
79
111
  subject.escape_query_value(&escape_proc)
@@ -158,21 +190,91 @@ class Deas::Router
158
190
  assert_equal path1, nf.path
159
191
  end
160
192
 
193
+ should "validate trailing slashes" do
194
+ router = @router_class.new
195
+ router.get('/something', 'EmptyViewHandler')
196
+ router.get('/something/', 'EmptyViewHandler')
197
+ router.apply_definitions!
198
+
199
+ assert_nothing_raised do
200
+ router.validate_trailing_slashes!
201
+ end
202
+
203
+ router.allow_trailing_slashes
204
+ assert_nothing_raised do
205
+ router.validate_trailing_slashes!
206
+ end
207
+
208
+ router.remove_trailing_slashes
209
+ err = assert_raises(TrailingSlashesError) do
210
+ router.validate_trailing_slashes!
211
+ end
212
+ exp = "all route paths must *not* end with a \"/\", but these do:\n/something/"
213
+ assert_includes exp, err.message
214
+
215
+ router = @router_class.new
216
+ router.get('/something/', 'EmptyViewHandler')
217
+ router.get('/something-else/', 'EmptyViewHandler')
218
+ router.apply_definitions!
219
+
220
+ assert_nothing_raised do
221
+ router.validate_trailing_slashes!
222
+ end
223
+
224
+ router.allow_trailing_slashes
225
+ assert_nothing_raised do
226
+ router.validate_trailing_slashes!
227
+ end
228
+
229
+ router.remove_trailing_slashes
230
+ err = assert_raises(TrailingSlashesError) do
231
+ router.validate_trailing_slashes!
232
+ end
233
+ exp = "all route paths must *not* end with a \"/\", but these do:\n"\
234
+ "/something/\n/something-else/"
235
+ assert_includes exp, err.message
236
+
237
+ router = @router_class.new
238
+ router.get('/something', 'EmptyViewHandler')
239
+ router.get('/something-else', 'EmptyViewHandler')
240
+ router.apply_definitions!
241
+
242
+ assert_nothing_raised do
243
+ router.validate_trailing_slashes!
244
+ end
245
+
246
+ router.allow_trailing_slashes
247
+ assert_nothing_raised do
248
+ router.validate_trailing_slashes!
249
+ end
250
+
251
+ router.remove_trailing_slashes
252
+ assert_nothing_raised do
253
+ router.validate_trailing_slashes!
254
+ end
255
+ end
256
+
161
257
  should "apply definitions and validate each route when validating" do
162
258
  subject.get('/something', 'EmptyViewHandler')
163
259
  subject.apply_definitions!
260
+ subject.validate_trailing_slashes!
164
261
  route = subject.routes.last
165
262
  proxy = route.handler_proxies[subject.default_request_type_name]
166
263
 
167
264
  apply_def_called = false
168
265
  Assert.stub(subject, :apply_definitions!){ apply_def_called = true }
169
266
 
267
+ val_trailing_called = false
268
+ Assert.stub(subject, :validate_trailing_slashes!){ val_trailing_called = true }
269
+
170
270
  assert_false apply_def_called
271
+ assert_false val_trailing_called
171
272
  assert_nil proxy.handler_class
172
273
 
173
274
  subject.validate!
174
275
 
175
276
  assert_true apply_def_called
277
+ assert_true val_trailing_called
176
278
  assert_equal EmptyViewHandler, proxy.handler_class
177
279
  end
178
280