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.
Files changed (78) hide show
  1. data/CHANGELOG +925 -0
  2. data/CONTRIBUTORS +93 -0
  3. data/PUBLIC_CHANGELOG +85 -0
  4. data/Rakefile +18 -28
  5. data/bin/merb +34 -5
  6. data/lib/merb-core/autoload.rb +2 -3
  7. data/lib/merb-core/bootloader.rb +60 -66
  8. data/lib/merb-core/config.rb +7 -1
  9. data/lib/merb-core/controller/abstract_controller.rb +35 -21
  10. data/lib/merb-core/controller/merb_controller.rb +15 -42
  11. data/lib/merb-core/controller/mixins/authentication.rb +42 -6
  12. data/lib/merb-core/controller/mixins/conditional_get.rb +83 -0
  13. data/lib/merb-core/controller/mixins/render.rb +3 -3
  14. data/lib/merb-core/core_ext/kernel.rb +6 -19
  15. data/lib/merb-core/dispatch/cookies.rb +96 -80
  16. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +2 -0
  17. data/lib/merb-core/dispatch/request.rb +18 -16
  18. data/lib/merb-core/dispatch/router/route.rb +6 -0
  19. data/lib/merb-core/dispatch/router.rb +4 -1
  20. data/lib/merb-core/dispatch/session/container.rb +64 -0
  21. data/lib/merb-core/dispatch/session/cookie.rb +91 -101
  22. data/lib/merb-core/dispatch/session/memcached.rb +38 -174
  23. data/lib/merb-core/dispatch/session/memory.rb +62 -208
  24. data/lib/merb-core/dispatch/session/store_container.rb +145 -0
  25. data/lib/merb-core/dispatch/session.rb +174 -48
  26. data/lib/merb-core/rack/middleware/conditional_get.rb +14 -8
  27. data/lib/merb-core/rack/middleware/csrf.rb +73 -0
  28. data/lib/merb-core/rack.rb +1 -0
  29. data/lib/merb-core/script.rb +112 -0
  30. data/lib/merb-core/server.rb +2 -0
  31. data/lib/merb-core/tasks/merb_rake_helper.rb +25 -0
  32. data/lib/merb-core/test/helpers/request_helper.rb +40 -3
  33. data/lib/merb-core/test/run_specs.rb +4 -3
  34. data/lib/merb-core/vendor/facets/inflect.rb +7 -10
  35. data/lib/merb-core/version.rb +1 -1
  36. data/lib/merb-core.rb +11 -40
  37. data/spec/private/core_ext/kernel_spec.rb +0 -11
  38. data/spec/private/dispatch/fixture/log/merb_test.log +893 -0
  39. data/spec/private/router/fixture/log/merb_test.log +12 -1728
  40. data/spec/private/router/route_spec.rb +4 -0
  41. data/spec/private/router/router_spec.rb +8 -0
  42. data/spec/private/vendor/facets/plural_spec.rb +1 -1
  43. data/spec/private/vendor/facets/singular_spec.rb +1 -1
  44. data/spec/public/abstract_controller/controllers/display.rb +8 -2
  45. data/spec/public/abstract_controller/controllers/filters.rb +18 -0
  46. data/spec/public/abstract_controller/display_spec.rb +6 -2
  47. data/spec/public/abstract_controller/filter_spec.rb +4 -0
  48. data/spec/public/controller/authentication_spec.rb +114 -43
  49. data/spec/public/controller/base_spec.rb +8 -0
  50. data/spec/public/controller/conditional_get_spec.rb +100 -0
  51. data/spec/public/controller/config/init.rb +1 -1
  52. data/spec/public/controller/controllers/authentication.rb +29 -0
  53. data/spec/public/controller/controllers/base.rb +13 -0
  54. data/spec/public/controller/controllers/conditional_get.rb +35 -0
  55. data/spec/public/controller/controllers/cookies.rb +10 -1
  56. data/spec/public/controller/cookies_spec.rb +38 -9
  57. data/spec/public/controller/spec_helper.rb +1 -0
  58. data/spec/public/controller/url_spec.rb +70 -1
  59. data/spec/public/directory_structure/directory/log/merb_test.log +461 -0
  60. data/spec/public/rack/conditinal_get_middleware_spec.rb +77 -89
  61. data/spec/public/rack/csrf_middleware_spec.rb +70 -0
  62. data/spec/public/reloading/directory/log/merb_test.log +52 -0
  63. data/spec/public/request/request_spec.rb +19 -1
  64. data/spec/public/router/fixation_spec.rb +26 -4
  65. data/spec/public/router/fixture/log/merb_test.log +234 -30332
  66. data/spec/public/session/controllers/sessions.rb +52 -0
  67. data/spec/public/session/cookie_session_spec.rb +73 -0
  68. data/spec/public/session/memcached_session_spec.rb +31 -0
  69. data/spec/public/session/memory_session_spec.rb +28 -0
  70. data/spec/public/session/multiple_sessions_spec.rb +74 -0
  71. data/spec/public/session/no_session_spec.rb +12 -0
  72. data/spec/public/session/session_spec.rb +91 -0
  73. data/spec/public/test/controllers/spec_helper_controller.rb +2 -1
  74. data/spec/public/test/request_helper_spec.rb +15 -0
  75. data/spec/spec_helper.rb +2 -2
  76. metadata +23 -5
  77. data/spec/private/dispatch/cookies_spec.rb +0 -219
  78. 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 {
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../../../spec_helper'
2
2
 
3
- describe Language::English::Inflect, "#singular" do
3
+ describe English::Inflect, "#singular" do
4
4
  it "pluralizes equipment => equipment" do
5
5
  "equipment".plural.should == "equipment"
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../../../spec_helper'
2
2
 
3
- describe Language::English::Inflect, "#singular" do
3
+ describe English::Inflect, "#singular" do
4
4
  # ==== exceptional cases
5
5
 
6
6
  it "singularizes equipment => equipment" do
@@ -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, "#basic_authentication with no realm" do
42
-
43
- it_should_behave_like "basic_authentication in general"
44
-
45
- it "should have a default WWW-Authenticate realm of 'Application' if no authentication is sent" do
46
- response = dispatch_to(Merb::Test::Fixtures::Controllers::BasicAuthentication, :index)
47
- response.headers['WWW-Authenticate'] = 'Basic realm="Application"'
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
- it "should have a default WWW-Authenticate realm of 'Application' if incorrect authentication is sent" do
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
- end
61
+ it_should_behave_like "basic_authentication in general"
57
62
 
58
- describe Merb::Controller, "#basic_authentication with realm" do
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
- it_should_behave_like "basic_authentication in general"
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
- it "should set the WWW-Authenticate realm if incorrect authentication is sent" do
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
- end
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
- end
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
- describe Merb::Controller, "#basic_authentication.request" do
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
- it "should halt the filter chain and return a 401 status code" do
88
- response = dispatch_to(Merb::Test::Fixtures::Controllers::RequestBasicAuthentication, :index)
89
- response.body.should == "HTTP Basic: Access denied.\n"
90
- response.status.should == 401
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
- it "should set the WWW-Authenticate realm" do
99
- response = dispatch_to(Merb::Test::Fixtures::Controllers::RequestBasicAuthenticationWithRealm, :index)
100
- response.headers['WWW-Authenticate'].should == 'Basic realm="My SuperApp"'
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[:session_cookie_domain] = "specs.merbivore.com"
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._session_cookie_domain = "overridden.merbivore.com"
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, "._session_cookie_domain" do
3
+ describe Merb::Controller, "._default_cookie_domain" do
4
+
4
5
  before(:each) do
5
- Merb::Config[:session_cookie_domain].should_not be(nil)
6
+ Merb::Config[:default_cookie_domain].should_not be(nil)
6
7
  end
7
8
 
8
- it 'is set to Merb::Config[:session_cookie_domain] by default' do
9
- Merb::Controller._session_cookie_domain.should == Merb::Config[:session_cookie_domain]
10
- Merb::Test::Fixtures::Controllers::CookiesController._session_cookie_domain.should ==
11
- Merb::Config[:session_cookie_domain]
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._session_cookie_domain.should ==
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._session_cookie_domain.should ==
21
- Merb::Config[:session_cookie_domain]
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')