merb-core 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,139 +1,127 @@
1
1
  require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
2
- require File.join(File.dirname(__FILE__), "shared_example_groups")
3
2
 
4
3
  require "sha1"
5
4
 
6
- NOW = Time.now
7
-
8
- class EtagController < Merb::Controller
9
- def non_matching_etag
10
- response = "Ruby world needs a Paste port. Or... CherryPy?"
5
+ class ConditionalGetTestController < Merb::Controller
6
+ def with_etag
7
+ response = "original message-body"
11
8
  headers['ETag'] = Digest::SHA1.hexdigest(response)
12
9
 
13
10
  response
14
11
  end
15
12
 
16
- def matching_etag
17
- response = "Everybody loves Rack"
18
- headers['ETag'] = Digest::SHA1.hexdigest(response)
19
-
20
- response
21
- end
22
-
23
- def no_etag
24
- # sanity check
25
- headers.delete('ETag')
26
-
27
- "Everyone loves Rack"
13
+ def with_last_modified
14
+ headers[Merb::Const::LAST_MODIFIED] = :documents_last_modified_time
15
+ "original message-body"
28
16
  end
29
- end
30
17
 
31
- class LastModifiedController < Merb::Controller
32
- def non_matching_last_modified
33
- response = "Who cares about efficiency? Just throw more hardware at the problem."
34
- headers[Merb::Const::LAST_MODIFIED] = :non_matching
35
-
36
- response
37
- end
38
-
39
- def matching_last_modified
40
- response = "Who cares about efficiency? Just throw more hardware at the problem."
41
- headers[Merb::Const::LAST_MODIFIED] = :matching
42
-
43
- response
44
- end
45
-
46
- def no_last_modified
18
+ def without
47
19
  # sanity check
48
- headers.delete('Last-Modified')
20
+ headers.delete('ETag')
21
+ headers.delete(Merb::Const::LAST_MODIFIED)
49
22
 
50
- "Everyone loves Rack"
23
+ "original message-body"
51
24
  end
52
25
  end
53
26
 
54
27
 
55
28
  Merb::Router.prepare do |r|
56
- r.match("/etag/match").to(:controller => "etag_controller", :action => "matching_etag")
57
- r.match("/etag/nomatch").to(:controller => "etag_controller", :action => "non_matching_etag")
58
- r.match("/etag/stomach").to(:controller => "etag_controller", :action => "no_etag")
59
-
60
- r.match("/last_modified/match").to(:controller => "last_modified_controller", :action => "matching_last_modified")
61
- r.match("/last_modified/nomatch").to(:controller => "last_modified_controller", :action => "non_matching_last_modified")
62
- r.match("/last_modified/stomach").to(:controller => "last_modified_controller", :action => "no_last_modified")
29
+ r.match("/with_etag").to(
30
+ :controller => "conditional_get_test_controller", :action => "with_etag"
31
+ )
32
+ r.match("/with_last_modified").to(
33
+ :controller => "conditional_get_test_controller", :action => "with_last_modified"
34
+ )
35
+ r.match("/without").to(
36
+ :controller => "conditional_get_test_controller", :action => "without"
37
+ )
63
38
  end
64
39
 
40
+ describe Merb::Rack::ConditionalGet do
65
41
 
42
+ describe(
43
+ "when the client already has an up-to-date document",
44
+ :shared => true
45
+ ) do
46
+ it 'sets status to "304"' do
47
+ @status.should == 304
48
+ end
66
49
 
67
- describe Merb::Rack::ConditionalGet do
50
+ it 'returns no message-body' do
51
+ @body.should == ""
52
+ end
53
+ end
54
+
55
+ describe(
56
+ "when the client does NOT have an up-to-date document",
57
+ :shared => true
58
+ ) do
59
+ it 'does not modify status' do
60
+ @status.should == 200
61
+ end
68
62
 
63
+ it 'does not modify message-body' do
64
+ @body.should == "original message-body"
65
+ end
66
+ end
67
+
69
68
  before(:each) do
70
69
  @app = Merb::Rack::Application.new
71
70
  @middleware = Merb::Rack::ConditionalGet.new(@app)
72
71
  end
73
72
 
74
- describe "when response has no ETag header" do
75
- it 'does not modify status' do
76
- env = Rack::MockRequest.env_for('/etag/stomach')
77
- status, headers, body = @middleware.call(env)
78
-
79
- status.should == 200
73
+ describe "when response has no ETag header and no Last-Modified header" do
74
+ before(:each) do
75
+ env = Rack::MockRequest.env_for('/without')
76
+ @status, @headers, @body = @middleware.call(env)
80
77
  end
78
+
79
+ it_should_behave_like "when the client does NOT have an up-to-date document"
81
80
  end
82
81
 
83
82
  describe "when response has ETag header" do
84
83
  describe "and it == to HTTP_IF_NONE_MATCH of the request" do
85
- it 'sets status to "304"' do
86
- env = Rack::MockRequest.env_for('/etag/match')
84
+ before(:each) do
85
+ env = Rack::MockRequest.env_for('/with_etag')
87
86
  env['HTTP_IF_NONE_MATCH'] =
88
- Digest::SHA1.hexdigest("Everybody loves Rack")
89
-
90
- status, headers, body = @middleware.call(env)
91
- status.should == 304
87
+ Digest::SHA1.hexdigest("original message-body")
88
+ @status, @headers, @body = @middleware.call(env)
92
89
  end
90
+
91
+ it_should_behave_like "when the client already has an up-to-date document"
93
92
  end
94
93
 
95
94
  describe "and it IS NOT == to HTTP_IF_NONE_MATCH of the request" do
96
- it 'does not modify status' do
97
- env = Rack::MockRequest.env_for('/etag/nomatch')
95
+ before(:each) do
96
+ env = Rack::MockRequest.env_for('/with_etag')
98
97
  env['HTTP_IF_NONE_MATCH'] =
99
- Digest::SHA1.hexdigest("Everybody loves Rack")
100
-
101
- status, headers, body = @middleware.call(env)
102
- status.should == 200
98
+ Digest::SHA1.hexdigest("a different message-body")
99
+ @status, @headers, @body = @middleware.call(env)
103
100
  end
104
- end
105
- end
106
-
107
- describe "when response has no Last-Modified header" do
108
- it 'does not modify status' do
109
- env = Rack::MockRequest.env_for('/last_modified/stomach')
110
- status, headers, body = @middleware.call(env)
111
-
112
- status.should == 200
101
+
102
+ it_should_behave_like "when the client does NOT have an up-to-date document"
113
103
  end
114
104
  end
115
105
 
116
106
  describe "when response has Last-Modified header" do
117
- describe "when response has Last-Modified header" do
118
- describe "and it == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
119
- it 'sets status to "304"' do
120
- env = Rack::MockRequest.env_for('/last_modified/match')
121
- env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :matching
122
-
123
- status, headers, body = @middleware.call(env)
124
- status.should == 304
125
- end
107
+ describe "and it == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
108
+ before(:each) do
109
+ env = Rack::MockRequest.env_for('/with_last_modified')
110
+ env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :documents_last_modified_time
111
+ @status, @headers, @body = @middleware.call(env)
126
112
  end
113
+
114
+ it_should_behave_like "when the client already has an up-to-date document"
115
+ end
127
116
 
128
- describe "and it IS NOT == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
129
- it 'does not modify status' do
130
- env = Rack::MockRequest.env_for('/last_modified/nomatch')
131
- env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :matching
132
-
133
- status, headers, body = @middleware.call(env)
134
- status.should == 200
135
- end
117
+ describe "and it IS NOT == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
118
+ before(:each) do
119
+ env = Rack::MockRequest.env_for('/with_last_modified')
120
+ env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :some_other_time
121
+ @status, @headers, @body = @middleware.call(env)
136
122
  end
123
+
124
+ it_should_behave_like "when the client does NOT have an up-to-date document"
137
125
  end
138
126
  end
139
127
  end
@@ -0,0 +1,70 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
2
+ require File.join(File.dirname(__FILE__), "shared_example_groups")
3
+
4
+
5
+ Merb::Router.prepare do |r|
6
+ r.resources :users
7
+ end
8
+
9
+ class Users < Merb::Controller
10
+ def new
11
+ body = "<div><form action='/users' method='POST'></form></div>"
12
+ body
13
+ end
14
+
15
+ def index
16
+ body = "<div>This is my index action</div>"
17
+ body
18
+ end
19
+
20
+ def edit
21
+ body = "<div><form action='/users' method='POST'></form><form action='/sessions' method='POST'></form></div>"
22
+ end
23
+
24
+ def create
25
+
26
+ end
27
+ end
28
+
29
+
30
+ describe Merb::Rack::Csrf do
31
+ before(:each) do
32
+ @app = Merb::Rack::Application.new
33
+ @middleware = Merb::Rack::Csrf.new(@app)
34
+ @env = Rack::MockRequest.env_for('/users/new')
35
+
36
+ Merb::Config[:session_secret_key] = "ABC"
37
+ end
38
+
39
+ it "should be successful" do
40
+ env = Rack::MockRequest.env_for('/users', :method => 'POST', 'csrf_authentication_token' => "b072aa15485e028dc8973d48089efe0e")
41
+ status, header, body = @middleware.call(env)
42
+ status.should == 200
43
+ end
44
+
45
+ it "should return a Merb::ExceptionsController::Forbidden (403)" do
46
+ env = Rack::MockRequest.env_for('/users', :method => 'POST', 'csrf_authentication_token' => "INCORRECT_AUTH_TOKEN")
47
+ status, header, body = @middleware.call(env)
48
+ status.should == 403
49
+ end
50
+
51
+ it "should insert a hidden field in to any form with a POST method" do
52
+ env = Rack::MockRequest.env_for('/users/new')
53
+ status, header, body = @middleware.call(env)
54
+ body.should have_tag(:form, :action => '/users')
55
+ body.should have_tag(:input, :type => 'hidden', :id => 'csrf_authentication_token')
56
+ end
57
+
58
+ it "should not do anything if there is no form found in the response" do
59
+ env = Rack::MockRequest.env_for('/users')
60
+ status, header, body = @middleware.call(env)
61
+ body.should not_match_tag('form')
62
+ end
63
+
64
+ it "should insert hidden fields in to both forms" do
65
+ env = Rack::MockRequest.env_for('/users/1/edit')
66
+ status, header, body = @middleware.call(env)
67
+ body.should have_tag(:form, :action => '/users')
68
+ body.should have_tag(:form, :action => '/sessions')
69
+ end
70
+ end
@@ -288161,3 +288161,55 @@ Restarting Worker Thread
288161
288161
  ~ Not Using Sessions
288162
288162
  ~ Not Using Sessions
288163
288163
  ~ Not Using Sessions
288164
+ ~ Not Using Sessions
288165
+ ~ Not Using Sessions
288166
+ ~ Not Using Sessions
288167
+ ~ Not Using Sessions
288168
+ ~ Not Using Sessions
288169
+ ~ Not Using Sessions
288170
+ ~ Not Using Sessions
288171
+ ~ Not Using Sessions
288172
+ ~ Not Using Sessions
288173
+ ~ Not Using Sessions
288174
+ ~ Not Using Sessions
288175
+ ~ Not Using Sessions
288176
+ ~ Not Using Sessions
288177
+ ~ Not Using Sessions
288178
+ ~ Not Using Sessions
288179
+ ~ Not Using Sessions
288180
+ ~ Not Using Sessions
288181
+ ~ Not Using Sessions
288182
+ ~ Not Using Sessions
288183
+ ~ Not Using Sessions
288184
+ ~ Not Using Sessions
288185
+ ~ Not Using Sessions
288186
+ ~ Not Using Sessions
288187
+ ~ Not Using Sessions
288188
+ ~ Not Using Sessions
288189
+ ~ Not Using Sessions
288190
+ ~ Not Using Sessions
288191
+ ~ Not Using Sessions
288192
+ ~ Not Using Sessions
288193
+ ~ Starting Merb server listening at 0.0.0.0:4000
288194
+ ~ Not Using Sessions
288195
+ ~ Starting Merb server listening at 0.0.0.0:4000
288196
+ ~ Not Using Sessions
288197
+ ~ Starting Merb server listening at 0.0.0.0:4000
288198
+ ~ Not Using Sessions
288199
+ ~ Starting Merb server listening at 0.0.0.0:4000
288200
+ ~ Not Using Sessions
288201
+ ~ Starting Merb server listening at 0.0.0.0:4000
288202
+ ~ Not Using Sessions
288203
+ ~ Starting Merb server listening at 0.0.0.0:4000
288204
+ ~ Not Using Sessions
288205
+ ~ Starting Merb server listening at 0.0.0.0:4000
288206
+ ~ Not Using Sessions
288207
+ ~ Starting Merb server listening at 0.0.0.0:4000
288208
+ ~ Not Using Sessions
288209
+ ~ Starting Merb server listening at 0.0.0.0:4000
288210
+ ~ Starting Merb server listening at 0.0.0.0:4000
288211
+ ~ Starting Merb server listening at 0.0.0.0:4000
288212
+ ~ Starting Merb server listening at 0.0.0.0:4000
288213
+ ~ Starting Merb server listening at 0.0.0.0:4000
288214
+ ~ Starting Merb server listening at 0.0.0.0:4000
288215
+ ~ Starting Merb server listening at 0.0.0.0:4000
@@ -56,6 +56,7 @@ describe Merb::Request, " query and body params" do
56
56
  before(:all) { Merb::BootLoader::Dependencies.enable_json_gem }
57
57
 
58
58
  {"foo=bar&baz=bat" => {"foo" => "bar", "baz" => "bat"},
59
+ "foo=bar&foo=baz" => {"foo" => "baz"},
59
60
  "foo[]=bar&foo[]=baz" => {"foo" => ["bar", "baz"]},
60
61
  "foo[][bar]=1&foo[][bar]=2" => {"foo" => [{"bar" => "1"},{"bar" => "2"}]},
61
62
  "foo[bar][][baz]=1&foo[bar][][baz]=2" => {"foo" => {"bar" => [{"baz" => "1"},{"baz" => "2"}]}},
@@ -220,4 +221,21 @@ describe Merb::Request, " misc" do
220
221
 
221
222
  end
222
223
 
223
- end
224
+ end
225
+
226
+
227
+
228
+ describe Merb::Request, "#if_none_match" do
229
+ it 'returns value of If-None-Match request header' do
230
+ fake_request(Merb::Const::HTTP_IF_NONE_MATCH => "dc1562a133").if_none_match.should == "dc1562a133"
231
+ end
232
+ end
233
+
234
+
235
+
236
+ describe Merb::Request, "#if_modified_since" do
237
+ it 'returns value of If-Modified-Since request header' do
238
+ t = '05 Sep 2008 22:00:27 GMT'
239
+ fake_request(Merb::Const::HTTP_IF_MODIFIED_SINCE => t).if_modified_since.should == Time.rfc2822(t)
240
+ end
241
+ end
@@ -1,19 +1,41 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper")
2
2
 
3
+ module Merb::Test::Fixtures
4
+ module Controllers
5
+ class FixatableRoutes < Merb::Controller
6
+
7
+ def fixoid
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+
3
14
  describe "A route marked as fixatable" do
4
15
  predicate_matchers[:allow_fixation] = :allow_fixation?
5
16
 
6
- it "allows fixation" do
17
+ before do
7
18
  Merb::Router.prepare do |r|
8
- r.match("/hello/:action/:id").to(:controller => "foo", :action => "fixoid").fixatable
19
+ r.match("/hello/:action/:id").to(
20
+ :controller => "merb/test/fixtures/controllers/fixatable_routes",
21
+ :action => "fixoid").fixatable
9
22
  end
23
+ end
10
24
 
25
+ it "allows fixation" do
11
26
  matched_route_for("/hello/goodbye/tagging").should allow_fixation
12
27
  end
28
+
29
+ it "should store a cookie with the session_id" do
30
+ session_id = Merb::SessionMixin.rand_uuid
31
+ request = fake_request(:request_uri => "/hello/goodbye/tagging",
32
+ :query_string => "_session_id=#{session_id}")
33
+ controller = ::Merb::Dispatcher.handle(request)
34
+ controller.params["_session_id"].should == session_id
35
+ controller.request.session_cookie_value.should == session_id
36
+ end
13
37
  end
14
38
 
15
-
16
-
17
39
  describe "A route NOT marked as fixatable" do
18
40
  predicate_matchers[:allow_fixation] = :allow_fixation?
19
41