merb-core 0.9.5 → 0.9.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.
- data/CHANGELOG +925 -0
- data/CONTRIBUTORS +93 -0
- data/PUBLIC_CHANGELOG +85 -0
- data/Rakefile +18 -28
- data/bin/merb +34 -5
- data/lib/merb-core/autoload.rb +2 -3
- data/lib/merb-core/bootloader.rb +60 -66
- data/lib/merb-core/config.rb +7 -1
- data/lib/merb-core/controller/abstract_controller.rb +35 -21
- data/lib/merb-core/controller/merb_controller.rb +15 -42
- data/lib/merb-core/controller/mixins/authentication.rb +42 -6
- data/lib/merb-core/controller/mixins/conditional_get.rb +83 -0
- data/lib/merb-core/controller/mixins/render.rb +3 -3
- data/lib/merb-core/core_ext/kernel.rb +6 -19
- data/lib/merb-core/dispatch/cookies.rb +96 -80
- data/lib/merb-core/dispatch/default_exception/views/index.html.erb +2 -0
- data/lib/merb-core/dispatch/request.rb +18 -16
- data/lib/merb-core/dispatch/router/route.rb +6 -0
- data/lib/merb-core/dispatch/router.rb +4 -1
- data/lib/merb-core/dispatch/session/container.rb +64 -0
- data/lib/merb-core/dispatch/session/cookie.rb +91 -101
- data/lib/merb-core/dispatch/session/memcached.rb +38 -174
- data/lib/merb-core/dispatch/session/memory.rb +62 -208
- data/lib/merb-core/dispatch/session/store_container.rb +145 -0
- data/lib/merb-core/dispatch/session.rb +174 -48
- data/lib/merb-core/rack/middleware/conditional_get.rb +14 -8
- data/lib/merb-core/rack/middleware/csrf.rb +73 -0
- data/lib/merb-core/rack.rb +1 -0
- data/lib/merb-core/script.rb +112 -0
- data/lib/merb-core/server.rb +2 -0
- data/lib/merb-core/tasks/merb_rake_helper.rb +25 -0
- data/lib/merb-core/test/helpers/request_helper.rb +40 -3
- data/lib/merb-core/test/run_specs.rb +4 -3
- data/lib/merb-core/vendor/facets/inflect.rb +7 -10
- data/lib/merb-core/version.rb +1 -1
- data/lib/merb-core.rb +11 -40
- data/spec/private/core_ext/kernel_spec.rb +0 -11
- data/spec/private/dispatch/fixture/log/merb_test.log +893 -0
- data/spec/private/router/fixture/log/merb_test.log +12 -1728
- data/spec/private/router/route_spec.rb +4 -0
- data/spec/private/router/router_spec.rb +8 -0
- data/spec/private/vendor/facets/plural_spec.rb +1 -1
- data/spec/private/vendor/facets/singular_spec.rb +1 -1
- data/spec/public/abstract_controller/controllers/display.rb +8 -2
- data/spec/public/abstract_controller/controllers/filters.rb +18 -0
- data/spec/public/abstract_controller/display_spec.rb +6 -2
- data/spec/public/abstract_controller/filter_spec.rb +4 -0
- data/spec/public/controller/authentication_spec.rb +114 -43
- data/spec/public/controller/base_spec.rb +8 -0
- data/spec/public/controller/conditional_get_spec.rb +100 -0
- data/spec/public/controller/config/init.rb +1 -1
- data/spec/public/controller/controllers/authentication.rb +29 -0
- data/spec/public/controller/controllers/base.rb +13 -0
- data/spec/public/controller/controllers/conditional_get.rb +35 -0
- data/spec/public/controller/controllers/cookies.rb +10 -1
- data/spec/public/controller/cookies_spec.rb +38 -9
- data/spec/public/controller/spec_helper.rb +1 -0
- data/spec/public/controller/url_spec.rb +70 -1
- data/spec/public/directory_structure/directory/log/merb_test.log +461 -0
- data/spec/public/rack/conditinal_get_middleware_spec.rb +77 -89
- data/spec/public/rack/csrf_middleware_spec.rb +70 -0
- data/spec/public/reloading/directory/log/merb_test.log +52 -0
- data/spec/public/request/request_spec.rb +19 -1
- data/spec/public/router/fixation_spec.rb +26 -4
- data/spec/public/router/fixture/log/merb_test.log +234 -30332
- data/spec/public/session/controllers/sessions.rb +52 -0
- data/spec/public/session/cookie_session_spec.rb +73 -0
- data/spec/public/session/memcached_session_spec.rb +31 -0
- data/spec/public/session/memory_session_spec.rb +28 -0
- data/spec/public/session/multiple_sessions_spec.rb +74 -0
- data/spec/public/session/no_session_spec.rb +12 -0
- data/spec/public/session/session_spec.rb +91 -0
- data/spec/public/test/controllers/spec_helper_controller.rb +2 -1
- data/spec/public/test/request_helper_spec.rb +15 -0
- data/spec/spec_helper.rb +2 -2
- metadata +23 -5
- data/spec/private/dispatch/cookies_spec.rb +0 -219
- data/spec/private/dispatch/session_mixin_spec.rb +0 -47
@@ -307,6 +307,10 @@ describe Merb::Router::Route, "#generate" do
|
|
307
307
|
it "calls #to_param on segments that respond to it" do
|
308
308
|
@non_regexp_route.generate({ :name => stub('US', :to_param => 'USA') }).should == "/world/countries/USA"
|
309
309
|
end
|
310
|
+
|
311
|
+
it "adds fragment after ?" do
|
312
|
+
@non_regexp_route.generate({:name => 101, :area => 10101, :fragment => :a_fragment}).should == "/world/countries/101?area=10101#a_fragment"
|
313
|
+
end
|
310
314
|
end
|
311
315
|
|
312
316
|
|
@@ -136,6 +136,10 @@ describe Merb::Router, ".generate", "given a Hash" do
|
|
136
136
|
it "respects format parameter" do
|
137
137
|
Merb::Router.generate({ :controller => "elements", :action => "show", :id => "fire", :format => :json }).should == "/elements/show/fire.json"
|
138
138
|
end
|
139
|
+
|
140
|
+
it "respects fragment parameter" do
|
141
|
+
Merb::Router.generate({ :controller => "elements", :action => "search", :fragment => :a_fragment }, { :q => "water" }).should == "/elements/search?q=water#a_fragment"
|
142
|
+
end
|
139
143
|
end
|
140
144
|
|
141
145
|
|
@@ -154,6 +158,10 @@ describe Merb::Router, ".generate_for_default_route", "given a Hash" do
|
|
154
158
|
it "respects format parameter" do
|
155
159
|
Merb::Router.generate({ :controller => "elements", :action => "show", :id => "fire", :format => :json }).should == "/elements/show/fire.json"
|
156
160
|
end
|
161
|
+
|
162
|
+
it "respects fragment parameter" do
|
163
|
+
Merb::Router.generate({ :controller => "elements", :action => "show", :id => "fire", :format => :json, :fragment => :a_fragment }).should == "/elements/show/fire.json#a_fragment"
|
164
|
+
end
|
157
165
|
|
158
166
|
it "requires both parameters to be present" do
|
159
167
|
lambda {
|
@@ -30,7 +30,13 @@ module Merb::Test::Fixtures
|
|
30
30
|
display @obj, "test_display/foo.html"
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
|
+
class DisplayObjectWithPathViaOpts < Testing
|
35
|
+
def index
|
36
|
+
@obj = SomeModel.new
|
37
|
+
display @obj, :template => "test_display/foo.html"
|
38
|
+
end
|
39
|
+
end
|
34
40
|
|
35
41
|
class DisplayObjectWithMultipleRoots < DisplayObject
|
36
42
|
self._template_roots << [File.dirname(__FILE__) / "alt_views", :_template_location]
|
@@ -51,4 +57,4 @@ module Merb::Test::Fixtures
|
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
54
|
-
end
|
60
|
+
end
|
@@ -79,6 +79,24 @@ module Merb::Test::Fixtures
|
|
79
79
|
"#{@x} #{@y}"
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
class TestProcFilterViaMethod < Testing
|
84
|
+
def self.my_before(data)
|
85
|
+
before proc { add_string(data) }
|
86
|
+
end
|
87
|
+
|
88
|
+
my_before("one")
|
89
|
+
my_before("two")
|
90
|
+
|
91
|
+
def index
|
92
|
+
@text
|
93
|
+
end
|
94
|
+
protected
|
95
|
+
def add_string(str)
|
96
|
+
@text ||= ""
|
97
|
+
@text << str
|
98
|
+
end
|
99
|
+
end
|
82
100
|
|
83
101
|
class TestExcludeFilter < Testing
|
84
102
|
before :foo, :exclude => :index
|
@@ -17,7 +17,11 @@ describe Merb::AbstractController, " displaying objects with templates" do
|
|
17
17
|
it "should allow you to pass an object with a path specified for the template" do
|
18
18
|
dispatch_should_make_body("DisplayObjectWithPath", "fooness")
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
|
+
it "should allow you to pass an object with a path specified for the template via opts" do
|
22
|
+
dispatch_should_make_body("DisplayObjectWithPathViaOpts", "fooness")
|
23
|
+
end
|
24
|
+
|
21
25
|
it "should allow you to pass an object using multiple template root" do
|
22
26
|
dispatch_should_make_body("DisplayObjectWithMultipleRoots", "App: new index")
|
23
27
|
end
|
@@ -30,4 +34,4 @@ describe Merb::AbstractController, " displaying objects with templates" do
|
|
30
34
|
dispatch_should_make_body("DisplayObjectWithMultipleRoots", "fooness", "another")
|
31
35
|
end
|
32
36
|
|
33
|
-
end
|
37
|
+
end
|
@@ -37,6 +37,10 @@ describe Merb::AbstractController, " should support before and after filters" do
|
|
37
37
|
dispatch_should_make_body("TestProcFilter", "proc filter1 proc filter2")
|
38
38
|
end
|
39
39
|
|
40
|
+
it "should support proc arguments to filters when called inside a class method" do
|
41
|
+
dispatch_should_make_body("TestProcFilterViaMethod", "onetwo")
|
42
|
+
end
|
43
|
+
|
40
44
|
it "should support filters that skip specific actions via :exclude" do
|
41
45
|
dispatch_should_make_body("TestExcludeFilter", " ", :index)
|
42
46
|
dispatch_should_make_body("TestExcludeFilter", "foo filter bar filter", :show)
|
@@ -38,66 +38,137 @@ describe "basic_authentication in general", :shared => true do
|
|
38
38
|
|
39
39
|
end
|
40
40
|
|
41
|
-
describe Merb::Controller
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
describe Merb::Controller do
|
42
|
+
MTFC = Merb::Test::Fixtures::Controllers
|
43
|
+
|
44
|
+
describe "#basic_authentication with no realm" do
|
45
|
+
it_should_behave_like "basic_authentication in general"
|
46
|
+
|
47
|
+
it "should have a default WWW-Authenticate realm of 'Application' if no authentication is sent" do
|
48
|
+
response = dispatch_to(MTFC::BasicAuthentication, :index)
|
49
|
+
response.headers['WWW-Authenticate'] = 'Basic realm="Application"'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should have a default WWW-Authenticate realm of 'Application' if incorrect authentication is sent" do
|
53
|
+
u, p = "John", "password"
|
54
|
+
response = dispatch_with_basic_authentication_to(MTFC::BasicAuthentication, :index, u, p)
|
55
|
+
response.headers['WWW-Authenticate'] = 'Basic realm="Application"'
|
56
|
+
end
|
48
57
|
end
|
49
58
|
|
50
|
-
|
51
|
-
u, p = "John", "password"
|
52
|
-
response = dispatch_with_basic_authentication_to(Merb::Test::Fixtures::Controllers::BasicAuthentication, :index, u, p)
|
53
|
-
response.headers['WWW-Authenticate'] = 'Basic realm="Application"'
|
54
|
-
end
|
59
|
+
describe "#basic_authentication with realm" do
|
55
60
|
|
56
|
-
|
61
|
+
it_should_behave_like "basic_authentication in general"
|
57
62
|
|
58
|
-
|
63
|
+
it "should set the WWW-Authenticate realm if no authentication is sent" do
|
64
|
+
response = dispatch_to(MTFC::BasicAuthenticationWithRealm, :index)
|
65
|
+
response.headers['WWW-Authenticate'] = 'Basic realm="My SuperApp"'
|
66
|
+
end
|
59
67
|
|
60
|
-
|
68
|
+
it "should set the WWW-Authenticate realm if incorrect authentication is sent" do
|
69
|
+
u, p = "John", "password"
|
70
|
+
response = dispatch_with_basic_authentication_to(MTFC::BasicAuthenticationWithRealm, :index, u, p)
|
71
|
+
response.headers['WWW-Authenticate'] = 'Basic realm="My SuperApp"'
|
72
|
+
end
|
61
73
|
|
62
|
-
it "should set the WWW-Authenticate realm if no authentication is sent" do
|
63
|
-
response = dispatch_to(Merb::Test::Fixtures::Controllers::BasicAuthenticationWithRealm, :index)
|
64
|
-
response.headers['WWW-Authenticate'] = 'Basic realm="My SuperApp"'
|
65
74
|
end
|
66
75
|
|
67
|
-
|
68
|
-
u, p = "John", "password"
|
69
|
-
response = dispatch_with_basic_authentication_to(Merb::Test::Fixtures::Controllers::BasicAuthenticationWithRealm, :index, u, p)
|
70
|
-
response.headers['WWW-Authenticate'] = 'Basic realm="My SuperApp"'
|
71
|
-
end
|
76
|
+
describe "#basic_authentication.authenticate" do
|
72
77
|
|
73
|
-
|
78
|
+
it "should pass in the username and password and return the result of the block" do
|
79
|
+
u, p = "Fred", "secret"
|
80
|
+
response = dispatch_with_basic_authentication_to(MTFC::AuthenticateBasicAuthentication, :index, u, p)
|
81
|
+
response.body.should == "Fred:secret"
|
82
|
+
end
|
74
83
|
|
75
|
-
describe Merb::Controller, "#basic_authentication.authenticate" do
|
76
|
-
|
77
|
-
it "should pass in the username and password and return the result of the block" do
|
78
|
-
u, p = "Fred", "secret"
|
79
|
-
response = dispatch_with_basic_authentication_to(Merb::Test::Fixtures::Controllers::AuthenticateBasicAuthentication, :index, u, p)
|
80
|
-
response.body.should == "Fred:secret"
|
81
84
|
end
|
85
|
+
|
86
|
+
describe "#basic_authentication.request" do
|
82
87
|
|
83
|
-
|
88
|
+
it "should halt the filter chain and return a 401 status code" do
|
89
|
+
response = dispatch_to(MTFC::RequestBasicAuthentication, :index)
|
90
|
+
response.body.should == "HTTP Basic: Access denied.\n"
|
91
|
+
response.status.should == 401
|
92
|
+
end
|
84
93
|
|
85
|
-
|
94
|
+
it "should have a default WWW-Authenticate realm of 'Application'" do
|
95
|
+
response = dispatch_to(MTFC::RequestBasicAuthentication, :index)
|
96
|
+
response.headers['WWW-Authenticate'].should == 'Basic realm="Application"'
|
97
|
+
end
|
86
98
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
99
|
+
it "should set the WWW-Authenticate realm" do
|
100
|
+
response = dispatch_to(MTFC::RequestBasicAuthenticationWithRealm, :index)
|
101
|
+
response.headers['WWW-Authenticate'].should == 'Basic realm="My SuperApp"'
|
102
|
+
end
|
92
103
|
|
93
|
-
it "should have a default WWW-Authenticate realm of 'Application'" do
|
94
|
-
response = dispatch_to(Merb::Test::Fixtures::Controllers::RequestBasicAuthentication, :index)
|
95
|
-
response.headers['WWW-Authenticate'].should == 'Basic realm="Application"'
|
96
104
|
end
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
|
106
|
+
describe "#basic_authentication.request!" do
|
107
|
+
|
108
|
+
it "should not halt the filter chain and provide a 401 status code" do
|
109
|
+
response = dispatch_to(MTFC::PassiveBasicAuthentication, :index)
|
110
|
+
response.status = 401
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should have a default WWW=Authentication realm of 'Application'" do
|
114
|
+
response = dispatch_to(MTFC::PassiveBasicAuthentication, :index)
|
115
|
+
response.headers['WWW-Authenticate'].should == 'Basic realm="Application"'
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should set the WWW-Authenticate realm" do
|
119
|
+
response = dispatch_to(MTFC::PassiveBasicAuthenticationWithRealm, :index)
|
120
|
+
response.headers['WWW-Authenticate'].should == 'Basic realm="My Super App"'
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should allow the action to render it's output" do
|
124
|
+
response = dispatch_to(MTFC::PassiveBasicAuthentication, :index)
|
125
|
+
response.body.should == "My Output"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should be callable from within an action" do
|
129
|
+
response = dispatch_to(MTFC::PassiveBasicAuthenticationInAction, :index)
|
130
|
+
response.body.should == "In Action"
|
131
|
+
response.status.should == 401
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "basic_authentication.provided?" do
|
137
|
+
|
138
|
+
it "should return true when basic authentication credentials have been supplied" do
|
139
|
+
u, p = "Fred", "secret"
|
140
|
+
response = dispatch_with_basic_authentication_to(MTFC::PassiveBasicAuthentication, :index, u, p)
|
141
|
+
response.basic_authentication.provided?.should be_true
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return false when basic authentication credentials have not been supplied" do
|
145
|
+
response = dispatch_to(MTFC::PassiveBasicAuthentication, :index)
|
146
|
+
response.basic_authentication.provided?.should be_false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "basic_authentication.username and password" do
|
151
|
+
it "return username if set" do
|
152
|
+
u, p = "Fred", "secret"
|
153
|
+
response = dispatch_with_basic_authentication_to(MTFC::PassiveBasicAuthentication, :index, u, p)
|
154
|
+
response.basic_authentication.username.should == "Fred"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should return nil if the username is not set" do
|
158
|
+
response = dispatch_to(MTFC::PassiveBasicAuthentication, :index)
|
159
|
+
response.basic_authentication.username.should be_nil
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should return password if set" do
|
163
|
+
u, p = "Fred", "secret"
|
164
|
+
response = dispatch_with_basic_authentication_to(MTFC::PassiveBasicAuthentication, :index, u, p)
|
165
|
+
response.basic_authentication.password.should == "secret"
|
166
|
+
end
|
167
|
+
|
168
|
+
it "shoudl return nil for the password if not set" do
|
169
|
+
response = dispatch_to(MTFC::PassiveBasicAuthentication, :index)
|
170
|
+
response.basic_authentication.password.should be_nil
|
171
|
+
end
|
101
172
|
end
|
102
173
|
|
103
174
|
end
|
@@ -77,4 +77,12 @@ describe Merb::Controller, "handles invalid status codes" do
|
|
77
77
|
calling { dispatch_to(Controllers::SetStatus, :index) }.
|
78
78
|
should raise_error(ArgumentError, /was.*String/)
|
79
79
|
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe Merb::Controller, "before/after dispatch callbacks" do
|
83
|
+
it "are used for internal purposes" do
|
84
|
+
controller = dispatch_to(Controllers::DispatchCallbacks, :index)
|
85
|
+
controller.called_before.should be_true
|
86
|
+
controller.called_after.should be_true
|
87
|
+
end
|
80
88
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
Controllers = Merb::Test::Fixtures::Controllers
|
3
|
+
|
4
|
+
describe Merb::Controller, "#etag=" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
Merb.push_path(:layout, File.dirname(__FILE__) / "controllers" / "views" / "layouts")
|
8
|
+
Merb::Router.prepare do |r|
|
9
|
+
r.default_routes
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'sets ETag header' do
|
14
|
+
controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet, :sets_etag)
|
15
|
+
controller.headers['ETag'].should == '"39791e6fb09"'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
describe Merb::Controller, "#last_modified=" do
|
22
|
+
before do
|
23
|
+
Merb.push_path(:layout, File.dirname(__FILE__) / "controllers" / "views" / "layouts")
|
24
|
+
Merb::Router.prepare do |r|
|
25
|
+
r.default_routes
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets Last-Modified header' do
|
30
|
+
controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet, :sets_last_modified)
|
31
|
+
controller.headers['Last-Modified'].should == Time.at(7000).httpdate
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
describe Merb::Controller, "#etag_matches?" do
|
37
|
+
it 'returns true when response ETag header equals to request If-None-Match header' do
|
38
|
+
controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet, :sets_etag, {}, { Merb::Const::HTTP_IF_NONE_MATCH => '"39791e6fb09"' } )
|
39
|
+
controller.etag_matches?('"39791e6fb09"').should be(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns false when response ETag header DOES NOT equal to request If-None-Match header' do
|
43
|
+
controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet, :sets_etag, {}, { Merb::Const::HTTP_IF_NONE_MATCH => '"6fb91e09793"' } )
|
44
|
+
controller.etag_matches?('"55789a6fb09"').should be(false)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
describe Merb::Controller, "#modified_since?" do
|
51
|
+
before(:each) do
|
52
|
+
@controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet,
|
53
|
+
:sets_last_modified, {}, { Merb::Const::HTTP_IF_MODIFIED_SINCE => Time.at(7000).httpdate })
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'return true when response Last-Modified header value <= request If-Modified-Since header' do
|
57
|
+
@controller.not_modified?(Time.at(5000)).should be(true)
|
58
|
+
@controller.not_modified?(Time.at(6999)).should be(true)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'return false when response Last-Modified header value > request If-Modified-Since header' do
|
62
|
+
@controller.not_modified?(Time.at(7003)).should be(false)
|
63
|
+
@controller.not_modified?(Time.at(16999)).should be(false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
describe Merb::Controller, "#request_fresh?" do
|
69
|
+
it 'return true when ETag matches' do
|
70
|
+
env = { 'HTTP_IF_MODIFIED_SINCE' => Time.at(8000).httpdate, Merb::Const::HTTP_IF_NONE_MATCH => '"39791e6fb09"' }
|
71
|
+
@controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet,
|
72
|
+
:sets_etag, {}, env)
|
73
|
+
|
74
|
+
@controller.request_fresh?.should be(true)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'return true when entity is not modified since date given in request header' do
|
78
|
+
env = { Merb::Const::HTTP_IF_MODIFIED_SINCE => Time.at(7000).httpdate }
|
79
|
+
@controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet,
|
80
|
+
:sets_last_modified, {}, env)
|
81
|
+
|
82
|
+
@controller.request_fresh?.should be(true)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'return true when both etag and last modification date satisfy request freshness' do
|
86
|
+
env = { 'HTTP_IF_MODIFIED_SINCE' => Time.at(7000).httpdate, Merb::Const::HTTP_IF_NONE_MATCH => '"39791e6fb09"' }
|
87
|
+
@controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet,
|
88
|
+
:superfresh, {}, env)
|
89
|
+
|
90
|
+
@controller.request_fresh?.should be(true)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'return false when neither etag nor last modification date satisfy request freshness' do
|
94
|
+
env = { 'HTTP_IF_MODIFIED_SINCE' => Time.at(7000).httpdate, Merb::Const::HTTP_IF_NONE_MATCH => '"39791e6fb09"' }
|
95
|
+
@controller = dispatch_to(Merb::Test::Fixtures::Controllers::ConditionalGet,
|
96
|
+
:stale, {}, env)
|
97
|
+
|
98
|
+
@controller.request_fresh?.should be(false)
|
99
|
+
end
|
100
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
Merb::Config.use do |c|
|
2
|
-
c[:
|
2
|
+
c[:default_cookie_domain] = "specs.merbivore.com"
|
3
3
|
c[:session_id_key] = "some_meaningless_id_key"
|
4
4
|
c[:session_secret_key] = "some_super_hyper_secret_key"
|
5
5
|
c[:session_expiry] = Merb::Const::WEEK * 4
|
@@ -41,5 +41,34 @@ module Merb::Test::Fixtures::Controllers
|
|
41
41
|
basic_authentication("My SuperApp").request
|
42
42
|
end
|
43
43
|
end
|
44
|
+
|
45
|
+
class PassiveBasicAuthentication < BasicAuthentication
|
46
|
+
|
47
|
+
def index
|
48
|
+
"My Output"
|
49
|
+
end
|
50
|
+
|
51
|
+
def authenticate
|
52
|
+
basic_authentication.request!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class PassiveBasicAuthenticationWithRealm < BasicAuthentication
|
57
|
+
def authenticate
|
58
|
+
basic_authentication("My Super App").request!
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class PassiveBasicAuthenticationInAction < BasicAuthentication
|
63
|
+
|
64
|
+
def index
|
65
|
+
basic_authentication.request!
|
66
|
+
"In Action"
|
67
|
+
end
|
68
|
+
|
69
|
+
def authenticate
|
70
|
+
true
|
71
|
+
end
|
72
|
+
end
|
44
73
|
|
45
74
|
end
|
@@ -47,6 +47,19 @@ module Merb::Test::Fixtures
|
|
47
47
|
self.status = "awesome"
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
class DispatchCallbacks < Testing
|
52
|
+
|
53
|
+
attr_accessor :called_before, :called_after
|
54
|
+
|
55
|
+
self._before_dispatch_callbacks << lambda { |c| c.called_before = true }
|
56
|
+
self._after_dispatch_callbacks << lambda { |c| c.called_after = true }
|
57
|
+
|
58
|
+
def index
|
59
|
+
"index"
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
50
63
|
|
51
64
|
end
|
52
65
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
module Merb::Test::Fixtures
|
4
|
+
module Controllers
|
5
|
+
class Testing < Merb::Controller
|
6
|
+
self._template_root = File.dirname(__FILE__) / "views"
|
7
|
+
end
|
8
|
+
|
9
|
+
class ConditionalGet < Testing
|
10
|
+
def sets_etag
|
11
|
+
self.etag = "39791e6fb09"
|
12
|
+
"can has etag"
|
13
|
+
end
|
14
|
+
|
15
|
+
def sets_last_modified
|
16
|
+
self.last_modified = Time.at(7000)
|
17
|
+
"can has last-modified"
|
18
|
+
end
|
19
|
+
|
20
|
+
def superfresh
|
21
|
+
self.etag = "39791e6fb09"
|
22
|
+
self.last_modified = Time.at(7000)
|
23
|
+
|
24
|
+
"can has fresh request"
|
25
|
+
end
|
26
|
+
|
27
|
+
def stale
|
28
|
+
self.etag = "1234567678"
|
29
|
+
self.last_modified = Time.at(9000)
|
30
|
+
|
31
|
+
"can has stale request"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -5,10 +5,19 @@ module Merb::Test::Fixtures::Controllers
|
|
5
5
|
end
|
6
6
|
|
7
7
|
class CookiesController < Testing
|
8
|
+
|
9
|
+
def store_cookies
|
10
|
+
cookies[:foo] = 'bar'
|
11
|
+
cookies.set_cookie(:awesome, 'super-cookie', :domain => 'blog.merbivore.com')
|
12
|
+
end
|
13
|
+
|
14
|
+
def retrieve_cookies
|
15
|
+
end
|
16
|
+
|
8
17
|
end
|
9
18
|
|
10
19
|
class OverridingSessionCookieDomain < CookiesController
|
11
|
-
self.
|
20
|
+
self._default_cookie_domain = "overridden.merbivore.com"
|
12
21
|
end
|
13
22
|
|
14
23
|
class NotOverridingSessionCookieDomain < CookiesController
|
@@ -1,23 +1,52 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
2
|
|
3
|
-
describe Merb::Controller, ".
|
3
|
+
describe Merb::Controller, "._default_cookie_domain" do
|
4
|
+
|
4
5
|
before(:each) do
|
5
|
-
Merb::Config[:
|
6
|
+
Merb::Config[:default_cookie_domain].should_not be(nil)
|
6
7
|
end
|
7
8
|
|
8
|
-
it 'is set to Merb::Config[:
|
9
|
-
Merb::Controller.
|
10
|
-
Merb::Test::Fixtures::Controllers::CookiesController.
|
11
|
-
Merb::Config[:
|
9
|
+
it 'is set to Merb::Config[:default_cookie_domain] by default' do
|
10
|
+
Merb::Controller._default_cookie_domain.should == Merb::Config[:default_cookie_domain]
|
11
|
+
Merb::Test::Fixtures::Controllers::CookiesController._default_cookie_domain.should ==
|
12
|
+
Merb::Config[:default_cookie_domain]
|
12
13
|
end
|
13
14
|
|
14
15
|
it "can be overridden for particular controller" do
|
15
|
-
Merb::Test::Fixtures::Controllers::OverridingSessionCookieDomain.
|
16
|
+
Merb::Test::Fixtures::Controllers::OverridingSessionCookieDomain._default_cookie_domain.should ==
|
16
17
|
"overridden.merbivore.com"
|
17
18
|
end
|
18
19
|
|
19
20
|
it 'is inherited by subclasses unless overriden' do
|
20
|
-
Merb::Test::Fixtures::Controllers::NotOverridingSessionCookieDomain.
|
21
|
-
Merb::Config[:
|
21
|
+
Merb::Test::Fixtures::Controllers::NotOverridingSessionCookieDomain._default_cookie_domain.should ==
|
22
|
+
Merb::Config[:default_cookie_domain]
|
22
23
|
end
|
23
24
|
end
|
25
|
+
|
26
|
+
describe Merb::Controller, "#cookies" do
|
27
|
+
|
28
|
+
it "sets the Set-Cookie response header" do
|
29
|
+
controller_klass = Merb::Test::Fixtures::Controllers::CookiesController
|
30
|
+
with_cookies(controller_klass) do |cookie_jar|
|
31
|
+
controller = dispatch_to(controller_klass, :store_cookies)
|
32
|
+
cookies = controller.headers['Set-Cookie'].sort
|
33
|
+
cookies.length.should == 2
|
34
|
+
cookies[0].should match(/awesome=super-cookie;/)
|
35
|
+
cookies[0].should match(/domain=blog.merbivore.com;/)
|
36
|
+
cookies[1].should match(/foo=bar;/)
|
37
|
+
cookies[1].should match(/domain=specs.merbivore.com;/)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "it gives access to cookie values" do
|
42
|
+
controller_klass = Merb::Test::Fixtures::Controllers::CookiesController
|
43
|
+
with_cookies(controller_klass) do |cookie_jar|
|
44
|
+
controller = dispatch_to(controller_klass, :store_cookies)
|
45
|
+
controller = dispatch_to(controller_klass, :retrieve_cookies)
|
46
|
+
controller.cookies['awesome'].should == 'super-cookie'
|
47
|
+
controller.cookies['foo'].should == 'bar'
|
48
|
+
controller.cookies.should == cookie_jar
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -8,5 +8,6 @@ require File.join(__DIR__, "controllers", "display")
|
|
8
8
|
require File.join(__DIR__, "controllers", "authentication")
|
9
9
|
require File.join(__DIR__, "controllers", "redirect")
|
10
10
|
require File.join(__DIR__, "controllers", "cookies")
|
11
|
+
require File.join(__DIR__, "controllers", "conditional_get")
|
11
12
|
|
12
13
|
Merb.start :environment => 'test', :init_file => File.join(__DIR__, 'config', 'init')
|