tennpipes-base 3.6.6
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.
- 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
|