tennpipes-base 3.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +294 -0
- data/Rakefile +1 -0
- data/bin/tennpipes +8 -0
- data/lib/tennpipes-base.rb +196 -0
- data/lib/tennpipes-base/application.rb +175 -0
- data/lib/tennpipes-base/application/application_setup.rb +202 -0
- data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
- data/lib/tennpipes-base/application/flash.rb +229 -0
- data/lib/tennpipes-base/application/params_protection.rb +129 -0
- data/lib/tennpipes-base/application/routing.rb +1002 -0
- data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
- data/lib/tennpipes-base/caller.rb +53 -0
- data/lib/tennpipes-base/cli/adapter.rb +33 -0
- data/lib/tennpipes-base/cli/base.rb +105 -0
- data/lib/tennpipes-base/cli/console.rb +20 -0
- data/lib/tennpipes-base/cli/launcher.rb +103 -0
- data/lib/tennpipes-base/cli/rake.rb +50 -0
- data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
- data/lib/tennpipes-base/command.rb +38 -0
- data/lib/tennpipes-base/ext/sinatra.rb +29 -0
- data/lib/tennpipes-base/filter.rb +52 -0
- data/lib/tennpipes-base/images/404.png +0 -0
- data/lib/tennpipes-base/images/500.png +0 -0
- data/lib/tennpipes-base/loader.rb +202 -0
- data/lib/tennpipes-base/logger.rb +492 -0
- data/lib/tennpipes-base/module.rb +58 -0
- data/lib/tennpipes-base/mounter.rb +308 -0
- data/lib/tennpipes-base/path_router.rb +119 -0
- data/lib/tennpipes-base/path_router/compiler.rb +110 -0
- data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
- data/lib/tennpipes-base/path_router/matcher.rb +123 -0
- data/lib/tennpipes-base/path_router/route.rb +169 -0
- data/lib/tennpipes-base/reloader.rb +309 -0
- data/lib/tennpipes-base/reloader/rack.rb +26 -0
- data/lib/tennpipes-base/reloader/storage.rb +55 -0
- data/lib/tennpipes-base/router.rb +98 -0
- data/lib/tennpipes-base/server.rb +119 -0
- data/lib/tennpipes-base/tasks.rb +21 -0
- data/lib/tennpipes-base/version.rb +20 -0
- data/lib/tennpipes-base/version.rb~ +20 -0
- data/test/fixtures/app_gem/Gemfile +4 -0
- data/test/fixtures/app_gem/app/app.rb +3 -0
- data/test/fixtures/app_gem/app_gem.gemspec +17 -0
- data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
- data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
- data/test/fixtures/apps/complex.rb +32 -0
- data/test/fixtures/apps/demo_app.rb +7 -0
- data/test/fixtures/apps/demo_demo.rb +7 -0
- data/test/fixtures/apps/demo_project/api/app.rb +7 -0
- data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
- data/test/fixtures/apps/demo_project/app.rb +7 -0
- data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
- data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/support.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
- data/test/fixtures/apps/kiq.rb +3 -0
- data/test/fixtures/apps/lib/myklass.rb +2 -0
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
- data/test/fixtures/apps/models/child.rb +2 -0
- data/test/fixtures/apps/models/parent.rb +5 -0
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
- data/test/fixtures/apps/mountable_apps/static.html +1 -0
- data/test/fixtures/apps/precompiled_app.rb +19 -0
- data/test/fixtures/apps/simple.rb +32 -0
- data/test/fixtures/apps/static.rb +10 -0
- data/test/fixtures/apps/system.rb +13 -0
- data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
- data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
- data/test/fixtures/dependencies/a.rb +9 -0
- data/test/fixtures/dependencies/b.rb +4 -0
- data/test/fixtures/dependencies/c.rb +1 -0
- data/test/fixtures/dependencies/circular/e.rb +13 -0
- data/test/fixtures/dependencies/circular/f.rb +2 -0
- data/test/fixtures/dependencies/circular/g.rb +2 -0
- data/test/fixtures/dependencies/d.rb +4 -0
- data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
- data/test/fixtures/reloadable_apps/main/app.rb +10 -0
- data/test/helper.rb +30 -0
- data/test/test_application.rb +185 -0
- data/test/test_core.rb +93 -0
- data/test/test_csrf_protection.rb +208 -0
- data/test/test_dependencies.rb +57 -0
- data/test/test_filters.rb +389 -0
- data/test/test_flash.rb +168 -0
- data/test/test_locale.rb +21 -0
- data/test/test_logger.rb +295 -0
- data/test/test_mounter.rb +302 -0
- data/test/test_params_protection.rb +195 -0
- data/test/test_reloader_complex.rb +74 -0
- data/test/test_reloader_external.rb +21 -0
- data/test/test_reloader_simple.rb +101 -0
- data/test/test_reloader_system.rb +113 -0
- data/test/test_restful_routing.rb +33 -0
- data/test/test_router.rb +281 -0
- data/test/test_routing.rb +2328 -0
- metadata +301 -0
data/test/test_core.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
+
|
3
|
+
describe "Core" do
|
4
|
+
def setup
|
5
|
+
Tennpipes.clear!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'for core functionality' do
|
9
|
+
it 'should check some global methods' do
|
10
|
+
assert_respond_to Tennpipes, :root
|
11
|
+
assert_respond_to Tennpipes, :env
|
12
|
+
assert_respond_to Tennpipes, :application
|
13
|
+
assert_respond_to Tennpipes, :set_encoding
|
14
|
+
assert_respond_to Tennpipes, :load!
|
15
|
+
assert_respond_to Tennpipes, :reload!
|
16
|
+
assert_respond_to Tennpipes, :version
|
17
|
+
assert_respond_to Tennpipes, :configure_apps
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should validate global helpers' do
|
21
|
+
assert_equal :test, Tennpipes.env
|
22
|
+
assert_match /\/test/, Tennpipes.root
|
23
|
+
refute_nil Tennpipes.version
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should set correct utf-8 encoding' do
|
27
|
+
Tennpipes.set_encoding
|
28
|
+
assert_equal Encoding.default_external, Encoding::UTF_8
|
29
|
+
assert_equal Encoding.default_internal, Encoding::UTF_8
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should raise application error if I instantiate a new tennpipes application without mounted apps' do
|
33
|
+
text = capture_io { Tennpipes.application }
|
34
|
+
assert_match /No apps are mounted/, text.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should check before/after tennpipes load hooks' do
|
38
|
+
Tennpipes.before_load { @_foo = 1 }
|
39
|
+
Tennpipes.after_load { @_foo += 1 }
|
40
|
+
Tennpipes.load!
|
41
|
+
assert_equal 1, Tennpipes.before_load.size
|
42
|
+
assert_equal 1, Tennpipes.after_load.size
|
43
|
+
assert_equal 2, @_foo
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should add middlewares in front if specified' do
|
47
|
+
test = Class.new {
|
48
|
+
def initialize(app)
|
49
|
+
@app = app
|
50
|
+
end
|
51
|
+
|
52
|
+
def call(env)
|
53
|
+
status, headers, body = @app.call(env)
|
54
|
+
headers["Middleware-Called"] = "yes"
|
55
|
+
return status, headers, body
|
56
|
+
end
|
57
|
+
}
|
58
|
+
|
59
|
+
class Foo < Tennpipes::Application; end
|
60
|
+
|
61
|
+
Tennpipes.use(test)
|
62
|
+
Tennpipes.mount(Foo).to("/")
|
63
|
+
|
64
|
+
res = Rack::MockRequest.new(Tennpipes.application).get("/")
|
65
|
+
assert_equal "yes", res["Middleware-Called"]
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should properly set default options' do
|
69
|
+
mock_app do
|
70
|
+
default :foo, :bar
|
71
|
+
default :zoo, :baz
|
72
|
+
set :foo, :bam
|
73
|
+
set :moo, :bam
|
74
|
+
default :moo, :ban
|
75
|
+
end
|
76
|
+
assert_equal @app.settings.foo, :bam
|
77
|
+
assert_equal @app.settings.zoo, :baz
|
78
|
+
assert_equal @app.settings.moo, :bam
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should return a friendly 500' do
|
82
|
+
mock_app do
|
83
|
+
enable :show_exceptions
|
84
|
+
get(:index){ raise StandardError }
|
85
|
+
end
|
86
|
+
|
87
|
+
get "/"
|
88
|
+
assert_equal 500, status
|
89
|
+
assert body.include?("StandardError")
|
90
|
+
assert body.include?("<code>show_exceptions</code> setting")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
+
|
3
|
+
describe "Application" do
|
4
|
+
before { Tennpipes.clear! }
|
5
|
+
|
6
|
+
describe 'CSRF protection' do
|
7
|
+
describe "with CSRF protection on" do
|
8
|
+
before do
|
9
|
+
mock_app do
|
10
|
+
enable :sessions
|
11
|
+
enable :protect_from_csrf
|
12
|
+
post('/'){ 'HI' }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should not allow requests without tokens' do
|
17
|
+
post "/"
|
18
|
+
assert_equal 403, status
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should allow requests with correct tokens' do
|
22
|
+
post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "a"}
|
23
|
+
assert_equal 200, status
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should not allow requests with incorrect tokens' do
|
27
|
+
post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "b"}
|
28
|
+
assert_equal 403, status
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should allow requests with correct X-CSRF-TOKEN' do
|
32
|
+
post "/", {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "a"
|
33
|
+
assert_equal 200, status
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not allow requests with incorrect X-CSRF-TOKEN' do
|
37
|
+
post "/", {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "b"
|
38
|
+
assert_equal 403, status
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "without CSRF protection on" do
|
44
|
+
before do
|
45
|
+
mock_app do
|
46
|
+
enable :sessions
|
47
|
+
disable :protect_from_csrf
|
48
|
+
post('/'){ 'HI' }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should allows requests without tokens' do
|
53
|
+
post "/"
|
54
|
+
assert_equal 200, status
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should allow requests with correct tokens' do
|
58
|
+
post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "a"}
|
59
|
+
assert_equal 200, status
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should allow requests with incorrect tokens' do
|
63
|
+
post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "b"}
|
64
|
+
assert_equal 200, status
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should allow requests with correct X-CSRF-TOKEN' do
|
68
|
+
post "/", {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "a"
|
69
|
+
assert_equal 200, status
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should allow requests with incorrect X-CSRF-TOKEN' do
|
73
|
+
post "/", {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "b"
|
74
|
+
assert_equal 200, status
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "with optional CSRF protection" do
|
79
|
+
before do
|
80
|
+
mock_app do
|
81
|
+
enable :sessions
|
82
|
+
enable :protect_from_csrf
|
83
|
+
enable :allow_disabled_csrf
|
84
|
+
post('/on') { 'HI' }
|
85
|
+
post('/off', :csrf_protection => false) { 'HI' }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should allow access to routes with csrf_protection off' do
|
90
|
+
post "/off"
|
91
|
+
assert_equal 200, status
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should not allow access to routes with csrf_protection on' do
|
95
|
+
post "/on"
|
96
|
+
assert_equal 403, status
|
97
|
+
assert_equal 'Forbidden', body
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "with :except option that is using Proc" do
|
102
|
+
before do
|
103
|
+
mock_app do
|
104
|
+
enable :sessions
|
105
|
+
set :protect_from_csrf, :except => proc{|env| ["/", "/foo"].any?{|path| path == env['PATH_INFO'] }}
|
106
|
+
post("/") { "Hello" }
|
107
|
+
post("/foo") { "Hello, foo" }
|
108
|
+
post("/bar") { "Hello, bar" }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should allow ignoring CSRF protection on specific routes' do
|
113
|
+
post "/"
|
114
|
+
assert_equal 200, status
|
115
|
+
post "/foo"
|
116
|
+
assert_equal 200, status
|
117
|
+
post "/bar"
|
118
|
+
assert_equal 403, status
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "with :except option that is using String and Regexp" do
|
123
|
+
before do
|
124
|
+
mock_app do
|
125
|
+
enable :sessions
|
126
|
+
set :protect_from_csrf, :except => ["/a", %r{^/a.c$}]
|
127
|
+
post("/a") { "a" }
|
128
|
+
post("/abc") { "abc" }
|
129
|
+
post("/foo") { "foo" }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should allow ignoring CSRF protection on specific routes' do
|
134
|
+
post "/a"
|
135
|
+
assert_equal 200, status
|
136
|
+
post "/abc"
|
137
|
+
assert_equal 200, status
|
138
|
+
post "/foo"
|
139
|
+
assert_equal 403, status
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "with custom protection options" do
|
144
|
+
before do
|
145
|
+
mock_app do
|
146
|
+
enable :sessions
|
147
|
+
set :protect_from_csrf, :authenticity_param => 'foobar', :message => 'sucker!'
|
148
|
+
post("/a") { "a" }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should allow configuring protection options' do
|
153
|
+
post "/a", {"foobar" => "a"}, 'rack.session' => {:csrf => "a"}
|
154
|
+
assert_equal 200, status
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should allow configuring message' do
|
158
|
+
post "/a"
|
159
|
+
assert_equal 403, status
|
160
|
+
assert_equal 'sucker!', body
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "with middleware" do
|
165
|
+
before do
|
166
|
+
class Middleware < Sinatra::Base
|
167
|
+
post("/middleware") { "Hello, middleware" }
|
168
|
+
post("/dummy") { "Hello, dummy" }
|
169
|
+
end
|
170
|
+
mock_app do
|
171
|
+
enable :sessions
|
172
|
+
set :protect_from_csrf, :except => proc{|env| ["/", "/middleware"].any?{|path| path == env['PATH_INFO'] }}
|
173
|
+
use Middleware
|
174
|
+
post("/") { "Hello" }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should allow ignoring CSRF protection on specific routes of middleware' do
|
179
|
+
post "/"
|
180
|
+
assert_equal 200, status
|
181
|
+
post "/middleware"
|
182
|
+
assert_equal 200, status
|
183
|
+
post "/dummy"
|
184
|
+
assert_equal 403, status
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "with standard report layout" do
|
189
|
+
before do
|
190
|
+
mock_app do
|
191
|
+
enable :sessions
|
192
|
+
set :protect_from_csrf, :message => 'sucker!'
|
193
|
+
enable :report_csrf_failure
|
194
|
+
post("/a") { "a" }
|
195
|
+
error 403 do
|
196
|
+
halt 406, 'please, do not hack'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'should allow configuring protection options' do
|
202
|
+
post "/a"
|
203
|
+
assert_equal 406, status
|
204
|
+
assert_equal 'please, do not hack', body
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
+
|
3
|
+
describe "Dependencies" do
|
4
|
+
describe 'when we require a dependency that have another dependency' do
|
5
|
+
before do
|
6
|
+
@log_level = Tennpipes::Logger::Config[:test]
|
7
|
+
@io = StringIO.new
|
8
|
+
Tennpipes::Logger::Config[:test] = { :log_level => :error, :stream => @io }
|
9
|
+
Tennpipes::Logger.setup!
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
Tennpipes::Logger::Config[:test] = @log_level
|
14
|
+
Tennpipes::Logger.setup!
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should raise an error without reloading it twice' do
|
18
|
+
capture_io do
|
19
|
+
assert_raises(RuntimeError) do
|
20
|
+
Tennpipes.require_dependencies(
|
21
|
+
Tennpipes.root("fixtures/dependencies/a.rb"),
|
22
|
+
Tennpipes.root("fixtures/dependencies/b.rb"),
|
23
|
+
Tennpipes.root("fixtures/dependencies/c.rb"),
|
24
|
+
Tennpipes.root("fixtures/dependencies/d.rb")
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
assert_equal 1, D
|
29
|
+
assert_match /RuntimeError - SomeThing/, @io.string
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should resolve dependency problems' do
|
33
|
+
capture_io do
|
34
|
+
Tennpipes.require_dependencies(
|
35
|
+
Tennpipes.root("fixtures/dependencies/a.rb"),
|
36
|
+
Tennpipes.root("fixtures/dependencies/b.rb"),
|
37
|
+
Tennpipes.root("fixtures/dependencies/c.rb")
|
38
|
+
)
|
39
|
+
end
|
40
|
+
assert_equal ["B", "C"], A_result
|
41
|
+
assert_equal "C", B_result
|
42
|
+
assert_equal "", @io.string
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should remove partially loaded constants' do
|
46
|
+
capture_io do
|
47
|
+
Tennpipes.require_dependencies(
|
48
|
+
Tennpipes.root("fixtures/dependencies/circular/e.rb"),
|
49
|
+
Tennpipes.root("fixtures/dependencies/circular/f.rb"),
|
50
|
+
Tennpipes.root("fixtures/dependencies/circular/g.rb")
|
51
|
+
)
|
52
|
+
end
|
53
|
+
assert_equal ["name"], F.fields
|
54
|
+
assert_equal "", @io.string
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,389 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
2
|
+
|
3
|
+
describe "Filters" do
|
4
|
+
it 'should filters by accept header' do
|
5
|
+
mock_app do
|
6
|
+
get '/foo', :provides => [:xml, :js] do
|
7
|
+
request.env['HTTP_ACCEPT']
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
12
|
+
assert ok?
|
13
|
+
assert_equal 'application/xml', body
|
14
|
+
assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
|
15
|
+
|
16
|
+
get '/foo.xml'
|
17
|
+
assert ok?
|
18
|
+
assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
|
19
|
+
|
20
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript' }
|
21
|
+
assert ok?
|
22
|
+
assert_equal 'application/javascript', body
|
23
|
+
assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type']
|
24
|
+
|
25
|
+
get '/foo.js'
|
26
|
+
assert ok?
|
27
|
+
assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type']
|
28
|
+
|
29
|
+
get '/foo', {}, { "HTTP_ACCEPT" => 'text/html' }
|
30
|
+
assert_equal 406, status
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should allow passing & halting in before filters' do
|
34
|
+
mock_app do
|
35
|
+
controller do
|
36
|
+
before { env['QUERY_STRING'] == 'secret' or pass }
|
37
|
+
get :index do
|
38
|
+
"secret index"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
controller do
|
43
|
+
before { env['QUERY_STRING'] == 'halt' and halt 401, 'go away!' }
|
44
|
+
get :index do
|
45
|
+
"index"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
get "/?secret"
|
51
|
+
assert_equal "secret index", body
|
52
|
+
|
53
|
+
get "/?halt"
|
54
|
+
assert_equal "go away!", body
|
55
|
+
assert_equal 401, status
|
56
|
+
|
57
|
+
get "/"
|
58
|
+
assert_equal "index", body
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should scope filters in the given controller' do
|
62
|
+
mock_app do
|
63
|
+
before { @global = 'global' }
|
64
|
+
after { @global = nil }
|
65
|
+
|
66
|
+
controller :foo do
|
67
|
+
before { @foo = :foo }
|
68
|
+
after { @foo = nil }
|
69
|
+
get("/") { [@foo, @bar, @global].compact.join(" ") }
|
70
|
+
end
|
71
|
+
|
72
|
+
get("/") { [@foo, @bar, @global].compact.join(" ") }
|
73
|
+
|
74
|
+
controller :bar do
|
75
|
+
before { @bar = :bar }
|
76
|
+
after { @bar = nil }
|
77
|
+
get("/") { [@foo, @bar, @global].compact.join(" ") }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
get "/bar"
|
82
|
+
assert_equal "bar global", body
|
83
|
+
|
84
|
+
get "/foo"
|
85
|
+
assert_equal "foo global", body
|
86
|
+
|
87
|
+
get "/"
|
88
|
+
assert_equal "global", body
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should be able to access params in a before filter' do
|
92
|
+
username_from_before_filter = nil
|
93
|
+
|
94
|
+
mock_app do
|
95
|
+
before do
|
96
|
+
username_from_before_filter = params[:username]
|
97
|
+
end
|
98
|
+
|
99
|
+
get :users, :with => :username do
|
100
|
+
end
|
101
|
+
end
|
102
|
+
get '/users/josh'
|
103
|
+
assert_equal 'josh', username_from_before_filter
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should be able to access params normally when a before filter is specified' do
|
107
|
+
mock_app do
|
108
|
+
before { }
|
109
|
+
get :index do
|
110
|
+
params.inspect
|
111
|
+
end
|
112
|
+
end
|
113
|
+
get '/?test=what'
|
114
|
+
assert_equal '{"test"=>"what"}', body
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should be able to filter based on a path' do
|
118
|
+
mock_app do
|
119
|
+
before('/') { @test = "#{@test}before"}
|
120
|
+
get :index do
|
121
|
+
@test
|
122
|
+
end
|
123
|
+
get :main do
|
124
|
+
@test
|
125
|
+
end
|
126
|
+
end
|
127
|
+
get '/'
|
128
|
+
assert_equal 'before', body
|
129
|
+
get '/main'
|
130
|
+
assert_equal '', body
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should be able to filter based on a symbol' do
|
134
|
+
mock_app do
|
135
|
+
before(:index) { @test = 'before'}
|
136
|
+
get :index do
|
137
|
+
@test
|
138
|
+
end
|
139
|
+
get :main do
|
140
|
+
@test
|
141
|
+
end
|
142
|
+
end
|
143
|
+
get '/'
|
144
|
+
assert_equal 'before', body
|
145
|
+
get '/main'
|
146
|
+
assert_equal '', body
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should be able to filter based on a symbol for a controller' do
|
150
|
+
mock_app do
|
151
|
+
controller :foo do
|
152
|
+
before(:test) { @test = 'foo'}
|
153
|
+
get :test do
|
154
|
+
@test.to_s + " response"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
controller :bar do
|
158
|
+
before(:test) { @test = 'bar'}
|
159
|
+
get :test do
|
160
|
+
@test.to_s + " response"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
get '/foo/test'
|
165
|
+
assert_equal 'foo response', body
|
166
|
+
get '/bar/test'
|
167
|
+
assert_equal 'bar response', body
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should be able to filter based on a symbol or path' do
|
171
|
+
mock_app do
|
172
|
+
before(:index, '/main') { @test = 'before'}
|
173
|
+
get :index do
|
174
|
+
@test
|
175
|
+
end
|
176
|
+
get :main do
|
177
|
+
@test
|
178
|
+
end
|
179
|
+
end
|
180
|
+
get '/'
|
181
|
+
assert_equal 'before', body
|
182
|
+
get '/main'
|
183
|
+
assert_equal 'before', body
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should be able to filter based on a symbol or regexp' do
|
187
|
+
mock_app do
|
188
|
+
before(:index, /main/) { @test = 'before'}
|
189
|
+
get :index do
|
190
|
+
@test
|
191
|
+
end
|
192
|
+
get :main do
|
193
|
+
@test
|
194
|
+
end
|
195
|
+
get :profile do
|
196
|
+
@test
|
197
|
+
end
|
198
|
+
end
|
199
|
+
get '/'
|
200
|
+
assert_equal 'before', body
|
201
|
+
get '/main'
|
202
|
+
assert_equal 'before', body
|
203
|
+
get '/profile'
|
204
|
+
assert_equal '', body
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should be able to filter excluding based on a symbol' do
|
208
|
+
mock_app do
|
209
|
+
before(:except => :index) { @test = 'before'}
|
210
|
+
get :index do
|
211
|
+
@test
|
212
|
+
end
|
213
|
+
get :main do
|
214
|
+
@test
|
215
|
+
end
|
216
|
+
end
|
217
|
+
get '/'
|
218
|
+
assert_equal '', body
|
219
|
+
get '/main'
|
220
|
+
assert_equal 'before', body
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should be able to filter excluding based on a symbol when specify the multiple routes and use nested controller' do
|
224
|
+
mock_app do
|
225
|
+
controller :test, :nested do
|
226
|
+
before(:except => [:test1, :test2]) { @long = 'long'}
|
227
|
+
before(:except => [:test1]) { @short = 'short'}
|
228
|
+
get :test1 do
|
229
|
+
"#{@long} #{@short} normal"
|
230
|
+
end
|
231
|
+
get :test2 do
|
232
|
+
"#{@long} #{@short} normal"
|
233
|
+
end
|
234
|
+
get :test3 do
|
235
|
+
"#{@long} #{@short} normal"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
get '/test/nested/test1'
|
240
|
+
assert_equal ' normal', body
|
241
|
+
get '/test/nested/test2'
|
242
|
+
assert_equal ' short normal', body
|
243
|
+
get '/test/nested/test3'
|
244
|
+
assert_equal 'long short normal', body
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should be able to filter based on a request param' do
|
248
|
+
mock_app do
|
249
|
+
before(:agent => /IE/) { @test = 'before'}
|
250
|
+
get :index do
|
251
|
+
@test
|
252
|
+
end
|
253
|
+
end
|
254
|
+
get '/'
|
255
|
+
assert_equal '', body
|
256
|
+
get "/", {}, {'HTTP_USER_AGENT' => 'This is IE'}
|
257
|
+
assert_equal 'before', body
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'should be able to filter based on a symbol or path in multiple controller' do
|
261
|
+
mock_app do
|
262
|
+
controllers :foo do
|
263
|
+
before(:index, '/foo/main') { @test = 'before' }
|
264
|
+
get :index do
|
265
|
+
@test
|
266
|
+
end
|
267
|
+
get :main do
|
268
|
+
@test
|
269
|
+
end
|
270
|
+
end
|
271
|
+
controllers :bar do
|
272
|
+
before(:index, '/bar/main') { @test = 'also before' }
|
273
|
+
get :index do
|
274
|
+
@test
|
275
|
+
end
|
276
|
+
get :main do
|
277
|
+
@test
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
get '/foo'
|
282
|
+
assert_equal 'before', body
|
283
|
+
get '/bar'
|
284
|
+
assert_equal 'also before', body
|
285
|
+
get '/foo/main'
|
286
|
+
assert_equal 'before', body
|
287
|
+
get '/bar/main'
|
288
|
+
assert_equal 'also before', body
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should call before filters even if there was no match' do
|
292
|
+
test = nil
|
293
|
+
mock_app do
|
294
|
+
before(:index, '/foo') { test = 'before' }
|
295
|
+
get :index do
|
296
|
+
''
|
297
|
+
end
|
298
|
+
end
|
299
|
+
get '/foo'
|
300
|
+
assert_equal 'before', test
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'should ensure the call of before_filter at the first time' do
|
304
|
+
once = ''
|
305
|
+
mock_app do
|
306
|
+
before do
|
307
|
+
once += 'before'
|
308
|
+
end
|
309
|
+
get :index do
|
310
|
+
raise Exception, 'Oops'
|
311
|
+
end
|
312
|
+
post :index do
|
313
|
+
raise Exception, 'Oops'
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
post '/'
|
318
|
+
assert_equal 'before', once
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'should call before filters only once' do
|
322
|
+
once = ''
|
323
|
+
mock_app do
|
324
|
+
error 500 do
|
325
|
+
'error 500'
|
326
|
+
end
|
327
|
+
before do
|
328
|
+
once += 'before'
|
329
|
+
end
|
330
|
+
get :index do
|
331
|
+
raise Exception, 'Oops'
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
get '/'
|
336
|
+
assert_equal 'before', once
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'should catch exceptions in before filters' do
|
340
|
+
doodle = nil
|
341
|
+
mock_app do
|
342
|
+
after do
|
343
|
+
doodle = 'Been after'
|
344
|
+
end
|
345
|
+
before do
|
346
|
+
raise StandardError, "before"
|
347
|
+
end
|
348
|
+
get :index do
|
349
|
+
doodle = 'Been now'
|
350
|
+
end
|
351
|
+
error 500 do
|
352
|
+
"We broke #{env['sinatra.error'].message}"
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
get '/'
|
357
|
+
assert_equal 'We broke before', body
|
358
|
+
assert_equal nil, doodle
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'should catch exceptions in after filters if no exceptions caught before' do
|
362
|
+
doodle = ''
|
363
|
+
mock_app do
|
364
|
+
after do
|
365
|
+
doodle += ' and after'
|
366
|
+
raise StandardError, "after"
|
367
|
+
end
|
368
|
+
get :foo do
|
369
|
+
doodle = 'Been now'
|
370
|
+
raise StandardError, "now"
|
371
|
+
end
|
372
|
+
get :index do
|
373
|
+
doodle = 'Been now'
|
374
|
+
end
|
375
|
+
error 500 do
|
376
|
+
"We broke #{env['sinatra.error'].message}"
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
get '/foo'
|
381
|
+
assert_equal 'We broke now', body
|
382
|
+
assert_equal 'Been now', doodle
|
383
|
+
|
384
|
+
doodle = ''
|
385
|
+
get '/'
|
386
|
+
assert_equal 'We broke after', body
|
387
|
+
assert_equal 'Been now and after', doodle
|
388
|
+
end
|
389
|
+
end
|