merb 0.4.0 → 0.4.1

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 (143) hide show
  1. data/README +23 -160
  2. data/Rakefile +15 -14
  3. data/app_generators/merb/merb_generator.rb +4 -3
  4. data/app_generators/merb/templates/Rakefile +1 -6
  5. data/app_generators/merb/templates/app/mailers/views/layout/{application.erb → application.html.erb} +0 -0
  6. data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +1 -0
  7. data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +1 -0
  8. data/app_generators/merb/templates/app/views/layout/application.html.erb +2 -2
  9. data/app_generators/merb/templates/config/dependencies.rb +1 -1
  10. data/app_generators/merb/templates/config/router.rb +4 -1
  11. data/app_generators/merb/templates/spec/spec_helper.rb +2 -3
  12. data/lib/autotest/merb_rspec.rb +1 -0
  13. data/lib/merb/abstract_controller.rb +31 -2
  14. data/lib/merb/controller.rb +5 -5
  15. data/lib/merb/core_ext/get_args.rb +5 -1
  16. data/lib/merb/exceptions.rb +17 -0
  17. data/lib/merb/generators/merb_app/merb_app.rb +4 -1
  18. data/lib/merb/generators/merb_plugin.rb +4 -1
  19. data/lib/merb/logger.rb +5 -1
  20. data/lib/merb/mail_controller.rb +1 -1
  21. data/lib/merb/mailer.rb +2 -2
  22. data/lib/merb/mixins/controller.rb +5 -1
  23. data/lib/merb/mixins/render.rb +57 -27
  24. data/lib/merb/part_controller.rb +1 -1
  25. data/lib/merb/request.rb +2 -2
  26. data/lib/merb/server.rb +33 -5
  27. data/lib/merb/template/erubis.rb +1 -1
  28. data/lib/merb.rb +15 -5
  29. data/merb_generators/resource/resource_generator.rb +9 -2
  30. data/spec/fixtures/config/merb.yml +18 -0
  31. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +227 -0
  32. data/spec/fixtures/controllers/render_spec_controllers.rb +115 -0
  33. data/spec/fixtures/foo.rb +3 -0
  34. data/spec/fixtures/mailers/views/layout/application.html.erb +3 -0
  35. data/spec/fixtures/mailers/views/layout/application.text.erb +3 -0
  36. data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +1 -0
  37. data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +1 -0
  38. data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +1 -0
  39. data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +1 -0
  40. data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +1 -0
  41. data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +1 -0
  42. data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +1 -0
  43. data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +1 -0
  44. data/spec/fixtures/models/router_spec_models.rb +20 -0
  45. data/spec/fixtures/parts/views/layout/todo_part.html.erb +3 -0
  46. data/spec/fixtures/parts/views/layout/todo_part.xml.erb +3 -0
  47. data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +1 -0
  48. data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +1 -0
  49. data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +1 -0
  50. data/spec/fixtures/parts/views/todo_part/list.html.erb +3 -0
  51. data/spec/fixtures/sample.txt +1 -0
  52. data/spec/fixtures/views/erubis.html.erb +1 -0
  53. data/spec/fixtures/views/examples/_erubis.html.erb +1 -0
  54. data/spec/fixtures/views/examples/_haml.html.haml +1 -0
  55. data/spec/fixtures/views/examples/_markaby.html.mab +1 -0
  56. data/spec/fixtures/views/examples/_throw_content.html.erb +6 -0
  57. data/spec/fixtures/views/examples/hello.xml.builder +1 -0
  58. data/spec/fixtures/views/examples/js.js.erb +1 -0
  59. data/spec/fixtures/views/examples/template_catch_content.html.erb +15 -0
  60. data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +6 -0
  61. data/spec/fixtures/views/examples/template_throw_content.html.erb +10 -0
  62. data/spec/fixtures/views/exceptions/admin_access_required.html.erb +1 -0
  63. data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +1 -0
  64. data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +1 -0
  65. data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +1 -0
  66. data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +1 -0
  67. data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +1 -0
  68. data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +1 -0
  69. data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +1 -0
  70. data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
  71. data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +1 -0
  72. data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +1 -0
  73. data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +1 -0
  74. data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
  75. data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
  76. data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +1 -0
  77. data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +1 -0
  78. data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +1 -0
  79. data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +4 -0
  80. data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +1 -0
  81. data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +1 -0
  82. data/spec/fixtures/views/haml.html.haml +1 -0
  83. data/spec/fixtures/views/haml.xml.haml +2 -0
  84. data/spec/fixtures/views/layout/application.html.erb +1 -0
  85. data/spec/fixtures/views/layout/application.xml.erb +1 -0
  86. data/spec/fixtures/views/layout/nested/example.html.erb +1 -0
  87. data/spec/fixtures/views/markaby.html.mab +1 -0
  88. data/spec/fixtures/views/nested/example/test.html.erb +1 -0
  89. data/spec/fixtures/views/partials/_erubis.html.erb +1 -0
  90. data/spec/fixtures/views/partials/_erubis_collection.html.erb +1 -0
  91. data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +1 -0
  92. data/spec/fixtures/views/partials/_erubis_new.html.erb +1 -0
  93. data/spec/fixtures/views/partials/_haml.html.haml +1 -0
  94. data/spec/fixtures/views/partials/_haml_collection.html.haml +1 -0
  95. data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +1 -0
  96. data/spec/fixtures/views/partials/_haml_new.html.haml +1 -0
  97. data/spec/fixtures/views/partials/_markaby.html.mab +1 -0
  98. data/spec/fixtures/views/partials/_markaby_collection.html.mab +1 -0
  99. data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +1 -0
  100. data/spec/fixtures/views/partials/_markaby_new.html.mab +1 -0
  101. data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +1 -0
  102. data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +1 -0
  103. data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +1 -0
  104. data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +4 -0
  105. data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +7 -0
  106. data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +7 -0
  107. data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +15 -0
  108. data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +15 -0
  109. data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +4 -0
  110. data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +12 -0
  111. data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +11 -0
  112. data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +14 -0
  113. data/spec/fixtures/views/test.dir/the_template.html.erb +1 -0
  114. data/spec/merb/abstract_controller_spec.rb +37 -0
  115. data/spec/merb/caching_spec.rb +102 -0
  116. data/spec/merb/config_spec.rb +29 -0
  117. data/spec/merb/controller_filters_spec.rb +188 -0
  118. data/spec/merb/controller_spec.rb +144 -0
  119. data/spec/merb/cookie_store_spec.rb +85 -0
  120. data/spec/merb/core_ext_spec.rb +430 -0
  121. data/spec/merb/dispatch_spec.rb +514 -0
  122. data/spec/merb/fake_request_spec.rb +72 -0
  123. data/spec/merb/form_control_mixin_spec.rb +431 -0
  124. data/spec/merb/generator_spec.rb +121 -0
  125. data/spec/merb/handler_spec.rb +169 -0
  126. data/spec/merb/mail_controller_spec.rb +144 -0
  127. data/spec/merb/mailer_spec.rb +87 -0
  128. data/spec/merb/multipart_spec.rb +49 -0
  129. data/spec/merb/part_controller_spec.rb +92 -0
  130. data/spec/merb/plugins_spec.rb +80 -0
  131. data/spec/merb/render_spec.rb +378 -0
  132. data/spec/merb/request_spec.rb +243 -0
  133. data/spec/merb/responder_spec.rb +561 -0
  134. data/spec/merb/router_spec.rb +726 -0
  135. data/spec/merb/template_spec.rb +41 -0
  136. data/spec/merb/upload_handler_spec.rb +101 -0
  137. data/spec/merb/view_context_spec.rb +148 -0
  138. data/spec/spec_generator_helper.rb +19 -0
  139. data/spec/spec_helper.rb +88 -0
  140. metadata +203 -65
  141. data/lib/merb/caching/store/memcache.rb +0 -20
  142. data/script/destroy +0 -14
  143. data/script/generate +0 -14
@@ -0,0 +1,188 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class TestFiltersController < Merb::Controller
4
+
5
+ before :filter1
6
+ before :will_halt, :only => :four
7
+ before Proc.new {|c| c.one }, :exclude => [:one, :three, :uses_params]
8
+ after Proc.new {|c| c.five }, :exclude => [:one, :three, :uses_params]
9
+ after :filter2
10
+ before :modifies_param, :only => :uses_params
11
+ after :restores_param, :only => :uses_params
12
+
13
+
14
+ def will_halt
15
+ throw :halt
16
+ end
17
+
18
+ def filters_halted
19
+ "Filters Halted"
20
+ end
21
+
22
+ def modifies_param
23
+ params[:the_param] ||= ''
24
+ params[:the_param_original] = params[:the_param]
25
+ params[:the_param] += ' is modified'
26
+ end
27
+
28
+ def restores_param
29
+ params[:the_param] = params[:the_param_original] + ' is restored'
30
+ @used_params = params[:the_param]
31
+ end
32
+
33
+ def filter1
34
+ @filter1='called'
35
+ end
36
+
37
+ def filter2
38
+ @filter2='called'
39
+ end
40
+
41
+ def one
42
+ session.data.should == {}
43
+ @one = 'one'
44
+ end
45
+
46
+ def two
47
+ @two = 'two'
48
+ end
49
+
50
+ def three
51
+ @three = 'three'
52
+ end
53
+
54
+ def four
55
+ @four = 'four'
56
+ end
57
+
58
+ def five
59
+ @five = 'five'
60
+ end
61
+
62
+ def uses_params
63
+ @uses_params = params[:the_param]
64
+ end
65
+
66
+ end
67
+
68
+ class TestDefaultFiltersHalted < Merb::Controller
69
+ before :will_halt
70
+
71
+ def will_halt
72
+ throw :halt
73
+ end
74
+
75
+ def one
76
+ end
77
+
78
+ end
79
+
80
+ class TestPrivateActions < Merb::Controller
81
+
82
+ protected
83
+ def notcallable1
84
+ "notcallable"
85
+ end
86
+
87
+ private
88
+ def notcallable2
89
+ "notcallable"
90
+ end
91
+
92
+ end
93
+ describe "Dispatch and before/after filters" do
94
+
95
+ def call_filter_action(action, extra_params = {})
96
+ @c = new_controller( action, TestFiltersController, extra_params )
97
+ @c.dispatch(action)
98
+ end
99
+
100
+ before :each do
101
+ request = Merb::Test::FakeRequest.new
102
+ @status, @response, @headers = 200, request.body, {'Content-Type' =>'text/html'}
103
+ @request, @cookies = request, {}
104
+ end
105
+
106
+ it "should not allow calling protected actions" do
107
+ c = new_controller( 'notcallable1', TestPrivateActions )
108
+ lambda {c.dispatch(:notcallable1)}.should raise_error( Merb::ControllerExceptions::ActionNotFound)
109
+ end
110
+
111
+ it "should not allow calling private actions" do
112
+ c = new_controller( 'notcallable2', TestPrivateActions )
113
+ lambda {c.dispatch(:notcallable2)}.should raise_error( Merb::ControllerExceptions::ActionNotFound)
114
+ end
115
+
116
+ it "should call a :symbol before and after filter" do
117
+ c = new_controller( 'one', TestFiltersController )
118
+ c.dispatch(:one)
119
+ c.body.should == 'one'
120
+ c.instance_variable_get('@one').should == 'one'
121
+ c.instance_variable_get('@two').should == nil
122
+ c.instance_variable_get('@three').should == nil
123
+ c.instance_variable_get('@filter1').should == 'called'
124
+ end
125
+
126
+ it "should be able to see instance variables" do
127
+ call_filter_action "one"
128
+ @c.cookies.should be_is_a(Hash)
129
+ @c.session.data.should == {}
130
+ @c.response.read.should == ""
131
+ @c.instance_variable_get("@filter1").should eql( 'called')
132
+ @c.instance_variable_get("@one").should eql( 'one')
133
+ end
134
+
135
+ it "should ignore actions specified by :exclude" do
136
+ call_filter_action "three"
137
+ @c.instance_variable_get("@one").should be_nil
138
+ @c.instance_variable_get("@five").should be_nil
139
+ end
140
+
141
+ it "should be able to see params in the before filter" do
142
+ call_filter_action "uses_params", :the_param => 'the param'
143
+ @c.instance_variable_get("@uses_params").should eql( 'the param is modified')
144
+ end
145
+
146
+ it "should be able to see params in the after filter" do
147
+ call_filter_action "uses_params", :the_param => 'the param'
148
+ @c.instance_variable_get("@used_params").should eql( 'the param is restored')
149
+ end
150
+
151
+ it "should call a Proc before and after filter" do
152
+ c = new_controller( 'two', TestFiltersController )
153
+ c.dispatch(:two)
154
+ c.body.should == 'two'
155
+ c.instance_variable_get('@one').should == 'one'
156
+ c.instance_variable_get('@two').should == 'two'
157
+ c.instance_variable_get('@three').should == nil
158
+ c.instance_variable_get('@five').should == 'five'
159
+ end
160
+
161
+ it "should call filters_halted when throw :halt" do
162
+ c = new_controller( 'four', TestFiltersController )
163
+ c.dispatch(:four)
164
+ c.body.should == "Filters Halted"
165
+ c.instance_variable_get('@one').should == nil
166
+ c.instance_variable_get('@two').should == nil
167
+ c.instance_variable_get('@three').should == nil
168
+ c.instance_variable_get('@filter1').should == 'called'
169
+ end
170
+
171
+ it "should have a default filter halted page" do
172
+ c = new_controller( 'one', TestFiltersController )
173
+ c.dispatch(:one)
174
+ end
175
+
176
+ it "should not allow both :only and :exclude" do
177
+ ["before", "after"].each do |filter_type|
178
+ lambda { TestFiltersController.send(filter_type, :x, :only => :foo, :exclude => :bar) }.should raise_error(ArgumentError)
179
+ end
180
+ end
181
+
182
+ it "should not allow a filter that is not a symbol, string, or proc" do
183
+ ["before", "after"].each do |filter_type|
184
+ lambda { TestFiltersController.send(filter_type, []) }.should raise_error(ArgumentError)
185
+ end
186
+ end
187
+
188
+ end
@@ -0,0 +1,144 @@
1
+ require 'ostruct'
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe "Merb::Controller" do
5
+
6
+ # not sure what this tests
7
+ # it "should instantiate" do
8
+ # c = new_controller
9
+ # @request.env.should == c.request.env
10
+ # end
11
+
12
+ it "should have a default layout of application.rhtml" do
13
+ c = new_controller
14
+ c._layout.should == :application
15
+ end
16
+ end
17
+
18
+ describe Merb::Controller, "url generator tests" do
19
+ def new_url_controller(route, params = {:action => 'show', :controller => 'Test'})
20
+ request = OpenStruct.new
21
+ request.route = route
22
+ request.params = params
23
+ response = OpenStruct.new
24
+ response.read = ""
25
+
26
+ Merb::Controller.build(request, response)
27
+ end
28
+
29
+ before(:all) do
30
+ Merb::Router.prepare do |r|
31
+ @resource_routes = r.resources(:blogs)
32
+ r.resources(:gardens) do |gardens|
33
+ @nested_resource = gardens.resources :flowers
34
+ end
35
+ @test_route = r.match("/the/:place/:goes/here").to(:controller => "Test", :action => "show").name(:test)
36
+ @default_route = r.default_routes
37
+ end
38
+ end
39
+
40
+ it "should generate a url from a route using a hash" do
41
+ c = new_url_controller(@test_route, :place => "1")
42
+ c.url_from_route(@test_route, :goes => "g").should == "/the/1/g/here"
43
+ end
44
+
45
+ it "should generate a url from a route using an object" do
46
+ c = new_url_controller(@test_route, :place => "2")
47
+ obj = OpenStruct.new(:goes => "elsewhere")
48
+ c.url_from_route(@test_route, obj).should == "/the/2/elsewhere/here"
49
+ end
50
+
51
+ it "should generate a url and tack extra params on as a query string" do
52
+ c = new_url_controller(@test_route, :place => "1")
53
+ c.url_from_route(@test_route, :goes => "g", :page => 2).should == "/the/1/g/here?page=2"
54
+ end
55
+
56
+ it "should generate a url directly from a hash using the current route as a default" do
57
+ c = new_url_controller(@test_route, :goes => "swimmingly")
58
+ c.url(:place => "provo").should == "/the/provo/swimmingly/here"
59
+ end
60
+
61
+ it "should generate a default route url with just :controller" do
62
+ c = new_url_controller(@default_route)
63
+ c.url(:controller => "welcome").should == "/welcome"
64
+ end
65
+
66
+ it "should generate a default route url with just :action" do
67
+ c = new_url_controller(@default_route, :controller => "foo")
68
+ c.url(:action => "baz").should == "/foo/baz"
69
+ end
70
+
71
+ it "should generate a default route url with just :id" do
72
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
73
+ c.url(:id => "23").should == "/foo/bar/23"
74
+ end
75
+
76
+ it 'should generate urls from nested resources' do
77
+ c = new_url_controller(@nested_resource, :garden => 5)
78
+ c.url(:flower, :garden_id => 1, :id => 3).should == "/gardens/1/flowers/3"
79
+ end
80
+
81
+ it "should generate a default route url with an extra param" do
82
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
83
+ c.url(:controller => :current, :monkey => "quux").should == "/foo/bar?monkey=quux"
84
+ end
85
+
86
+ it "should generate a default route url with extra params" do
87
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
88
+ url = c.url(:controller => :current, :monkey => "quux", :cow => "moo")
89
+ url.should match(%r{/foo/bar?.*monkey=quux})
90
+ url.should match(%r{/foo/bar?.*cow=moo})
91
+ end
92
+
93
+ it "should generate a default route url with extra params and an array" do
94
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
95
+ c.url(:controller => :current, :monkey => [1,2]).should == "/foo/bar?monkey[]=1&monkey[]=2"
96
+ end
97
+
98
+ it "should generate a default route url with extra params and a hash" do
99
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
100
+ c.url(:controller => :current, :animals => {:cow => "moo"}).should == "/foo/bar?animals[cow]=moo"
101
+ end
102
+
103
+ it "should generate a default route url with :action and :format" do
104
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
105
+ c.url(:action => :recent, :format => :txt).should == "/foo/recent.txt"
106
+ end
107
+
108
+ it "should generate a default route url with all options" do
109
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
110
+ c.url(:controller => "foo", :action => "bar", :id => "baz", :format => :js, :monkey => "quux").should == "/foo/bar/baz.js?monkey=quux"
111
+ end
112
+
113
+ it "should handle nested nested and more nested hashes and arrays" do
114
+ c = new_url_controller(@default_route, :controller => "foo", :action => "bar")
115
+ url = c.url(:controller => :current, :user => {:filter => {:name => "quux*"}, :order => ["name"]})
116
+ url.should match(%r{/foo/bar?.*user\[filter\]\[name\]=quux%2A})
117
+ url.should match(%r{/foo/bar?.*user\[order\]\[\]=name})
118
+ end
119
+
120
+ it "should handle an object as the second arg" do
121
+ c = new_url_controller(@resource_routes, :controller => "blogs", :action => "show")
122
+ blog = mock("blog")
123
+ blog.should_receive(:id).once.and_return(7)
124
+ url = c.url(:blog, blog)
125
+ url.should == "/blogs/7"
126
+ end
127
+
128
+ it "should point to /blogs/:blog_id if @blog is not new_record" do
129
+ c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index")
130
+ blog = mock("blog")
131
+ blog.should_receive(:id).once.and_return(7)
132
+ blog.should_receive(:new_record?).once.and_return(false)
133
+ url = c.url(:blog, blog)
134
+ url.should == "/blogs/7"
135
+ end
136
+
137
+ it "should point to /blogs/ if @blog is new_record" do
138
+ c = new_url_controller(@resource_routes, :controller => "blogs", :action => "index")
139
+ blog = mock("blog")
140
+ blog.should_receive(:new_record?).once.and_return(true)
141
+ url = c.url(:blog, blog)
142
+ url.should == "/blogs/"
143
+ end
144
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ require "merb/session/cookie_store"
4
+
5
+ class Merb::Controller
6
+ include ::Merb::SessionMixin
7
+ end
8
+
9
+ class TestCookieSessionController < Merb::Controller
10
+
11
+ def change
12
+ session[:hello] = 'world'
13
+ end
14
+
15
+ def no_change
16
+ "test"
17
+ end
18
+
19
+ end
20
+
21
+ Merb::Server.config[:session_secret_key] = 'Secret!'
22
+
23
+ describe Merb::SessionMixin do
24
+ it "should set the cookie if the cookie is changed" do
25
+ c = new_controller( 'change', TestCookieSessionController)
26
+ c.dispatch(:change)
27
+ c.headers['Set-Cookie'].should =~ %r{_session_id=} # this could be better
28
+ end
29
+ end
30
+
31
+ describe Merb::CookieStore do
32
+
33
+ def cookies(*which)
34
+ @cookies.values_at(*which)
35
+ end
36
+
37
+ def cookie_value(which)
38
+ @cookies[which].first
39
+ end
40
+
41
+ before(:each) do
42
+ @secret = 'Keep it secret; keep it safe.'
43
+ @cookies = {
44
+ :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
45
+ :a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
46
+ :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
47
+ :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }]
48
+ }
49
+ end
50
+
51
+
52
+
53
+ it "should raise argument error if missing secret key" do
54
+ lambda { Merb::CookieStore.new(nil, nil) }.should raise_error(ArgumentError)
55
+ end
56
+
57
+ it "should restore and unmarshal good cookies" do
58
+ cookies(:empty, :a_one, :typical).each do |value, expected|
59
+ session = Merb::CookieStore.new(value, @secret)
60
+ session['lazy loads the data hash'].should be_nil
61
+ session.data.should == expected
62
+ end
63
+ end
64
+
65
+ it "should raise error on tampered cookie" do
66
+ lambda { Merb::CookieStore.new('a--b', @secret) }.should
67
+ raise_error(Merb::CookieStore::TamperedWithCookie)
68
+ end
69
+
70
+ it "should raise when data overflows" do
71
+ session = Merb::CookieStore.new(cookie_value(:empty), @secret)
72
+ session['overflow'] = 'bye!' * 1024
73
+ lambda { session.read_cookie }.should
74
+ raise_error(Merb::CookieStore::CookieOverflow)
75
+ end
76
+
77
+ it "should close and marshal cookie data" do
78
+ session = Merb::CookieStore.new(cookie_value(:typical), @secret)
79
+ session.modified?.should == false
80
+ session['flash'] = {}
81
+ session.modified?.should == true
82
+ session.read_cookie.should == cookie_value(:flashed)
83
+ end
84
+
85
+ end