2 require 'abstract_unit'
4 CACHE_DIR
= 'test_cache'
5 # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
6 FILE_STORE_PATH
= File
.join(File
.dirname(__FILE__
), '/../temp/', CACHE_DIR
)
7 ActionController
::Base.page_cache_directory
= FILE_STORE_PATH
8 ActionController
::Base.cache_store
= :file_store, FILE_STORE_PATH
10 class PageCachingTestController
< ActionController
::Base
11 caches_page
:ok, :no_content, :if => Proc
.new
{ |c
| !c
.request
.format
.json
? }
12 caches_page
:found, :not_found
23 redirect_to
:action => 'ok'
31 render
:text => "Super soaker"
32 cache_page("Super soaker", "/index.html")
35 def expire_custom_path
36 expire_page("/index.html")
41 render
:text => "Sneak attack"
45 class PageCachingTest
< Test
::Unit::TestCase
47 ActionController
::Base.perform_caching
= true
49 ActionController
::Routing::Routes.draw
do |map
|
50 map
.main
'', :controller => 'posts'
52 map
.connect
':controller/:action/:id'
55 @request = ActionController
::TestRequest.new
56 @request.host
= 'hostname.com'
58 @response = ActionController
::TestResponse.new
59 @controller = PageCachingTestController
.new
61 @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true}
62 @rewriter = ActionController
::UrlRewriter.new(@request, @params)
64 FileUtils
.rm_rf(File
.dirname(FILE_STORE_PATH
))
65 FileUtils
.mkdir_p(FILE_STORE_PATH
)
69 FileUtils
.rm_rf(File
.dirname(FILE_STORE_PATH
))
71 ActionController
::Base.perform_caching
= false
74 def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
75 @params[:format] = 'rss'
76 assert_equal
'/posts.rss', @rewriter.rewrite(@params)
77 @params[:format] = nil
78 assert_equal
'/', @rewriter.rewrite(@params)
81 def test_should_cache_get_with_ok_status
84 assert_page_cached
:ok, "get with ok status should have been cached"
87 def test_should_cache_with_custom_path
89 assert File
.exist
?("#{FILE_STORE_PATH}/index.html")
92 def test_should_expire_cache_with_custom_path
94 assert File
.exist
?("#{FILE_STORE_PATH}/index.html")
96 get
:expire_custom_path
97 assert
!File
.exist
?("#{FILE_STORE_PATH}/index.html")
100 def test_should_cache_without_trailing_slash_on_url
101 @controller.class.cache_page
'cached content', '/page_caching_test/trailing_slash'
102 assert File
.exist
?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
105 def test_should_cache_with_trailing_slash_on_url
106 @controller.class.cache_page
'cached content', '/page_caching_test/trailing_slash/'
107 assert File
.exist
?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
110 uses_mocha("should_cache_ok_at_custom_path") do
111 def test_should_cache_ok_at_custom_path
112 @request.stubs(:path).returns("/index.html")
115 assert File
.exist
?("#{FILE_STORE_PATH}/index.html")
119 [:ok, :no_content, :found, :not_found].each
do |status
|
120 [:get, :post, :put, :delete].each
do |method
|
121 unless method
== :get and status
== :ok
122 define_method
"test_shouldnt_cache_#{method}_with_#{status}_status" do
123 @request.env['REQUEST_METHOD'] = method
.to_s
.upcase
125 assert_response status
126 assert_page_not_cached status
, "#{method} with #{status} status shouldn't have been cached"
132 def test_page_caching_conditional_options
133 get
:ok, :format=>'json'
134 assert_page_not_cached
:ok
138 def assert_page_cached(action
, message
= "#{action} should have been cached")
139 assert page_cached
?(action
), message
142 def assert_page_not_cached(action
, message
= "#{action} shouldn't have been cached")
143 assert
!page_cached
?(action
), message
146 def page_cached
?(action
)
147 File
.exist
? "#{FILE_STORE_PATH}/page_caching_test/#{action}.html"
151 class ActionCachingTestController
< ActionController
::Base
152 caches_action
:index, :redirected, :forbidden, :if => Proc
.new
{ |c
| !c
.request
.format
.json
? }, :expires_in => 1.hour
153 caches_action
:show, :cache_path => 'http://test.host/custom/show'
154 caches_action
:edit, :cache_path => Proc
.new
{ |c
| c
.params
[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
155 caches_action
:with_layout
156 caches_action
:layout_false, :layout => false
158 layout
'talk_from_action.erb'
161 @cache_this = MockTime
.now
.to_f
.to_s
162 render
:text => @cache_this
166 redirect_to
:action => 'index'
170 render
:text => "Forbidden"
171 headers
["Status"] = "403 Forbidden"
175 @cache_this = MockTime
.now
.to_f
.to_s
176 render
:text => @cache_this, :layout => true
179 alias_method
:show, :index
180 alias_method
:edit, :index
181 alias_method
:destroy, :index
182 alias_method
:layout_false, :with_layout
185 expire_action
:controller => 'action_caching_test', :action => 'index'
186 render
:nothing => true
190 expire_action
:controller => 'action_caching_test', :action => 'index', :format => 'xml'
191 render
:nothing => true
195 class MockTime
< Time
196 # Let Time spicy to assure that Time.now != Time.now
202 class ActionCachingMockController
203 attr_accessor
:mock_url_for
204 attr_accessor
:mock_path
207 yield self if block_given
?
215 mocked_path
= @mock_path
216 Object
.new
.instance_eval(<<-EVAL)
217 def path; '#{@mock_path}' end
218 def format; 'all' end
219 def cache_format; nil end
225 class ActionCacheTest
< Test
::Unit::TestCase
228 FileUtils
.mkdir_p(FILE_STORE_PATH
)
229 @path_class = ActionController
::Caching::Actions::ActionCachePath
230 @mock_controller = ActionCachingMockController
.new
234 FileUtils
.rm_rf(File
.dirname(FILE_STORE_PATH
))
237 def test_simple_action_cache
239 cached_time
= content_to_cache
240 assert_equal cached_time
, @response.body
241 assert fragment_exist
?('hostname.com/action_caching_test')
245 assert_equal cached_time
, @response.body
248 def test_simple_action_not_cached
250 cached_time
= content_to_cache
251 assert_equal cached_time
, @response.body
252 assert
!fragment_exist
?('hostname.com/action_caching_test/destroy')
256 assert_not_equal cached_time
, @response.body
259 def test_action_cache_with_layout
261 cached_time
= content_to_cache
262 assert_not_equal cached_time
, @response.body
263 assert fragment_exist
?('hostname.com/action_caching_test/with_layout')
267 assert_not_equal cached_time
, @response.body
269 assert_equal
@response.body
, read_fragment('hostname.com/action_caching_test/with_layout')
272 def test_action_cache_with_layout_and_layout_cache_false
274 cached_time
= content_to_cache
275 assert_not_equal cached_time
, @response.body
276 assert fragment_exist
?('hostname.com/action_caching_test/layout_false')
280 assert_not_equal cached_time
, @response.body
282 assert_equal cached_time
, read_fragment('hostname.com/action_caching_test/layout_false')
285 def test_action_cache_conditional_options
286 old_use_accept_header
= ActionController
::Base.use_accept_header
287 ActionController
::Base.use_accept_header
= true
288 @request.env['HTTP_ACCEPT'] = 'application/json'
290 assert
!fragment_exist
?('hostname.com/action_caching_test')
291 ActionController
::Base.use_accept_header
= old_use_accept_header
294 uses_mocha
'test action cache' do
295 def test_action_cache_with_store_options
296 MockTime
.expects(:now).returns(12345).once
297 @controller.expects(:read_fragment).with('hostname.com/action_caching_test', :expires_in => 1.hour
).once
298 @controller.expects(:write_fragment).with('hostname.com/action_caching_test', '12345.0', :expires_in => 1.hour
).once
303 def test_action_cache_with_custom_cache_path
305 cached_time
= content_to_cache
306 assert_equal cached_time
, @response.body
307 assert fragment_exist
?('test.host/custom/show')
311 assert_equal cached_time
, @response.body
314 def test_action_cache_with_custom_cache_path_in_block
316 assert fragment_exist
?('test.host/edit')
320 assert fragment_exist
?('test.host/1;edit')
323 def test_cache_expiration
325 cached_time
= content_to_cache
329 assert_equal cached_time
, @response.body
336 new_cached_time
= content_to_cache
337 assert_not_equal cached_time
, @response.body
341 assert_response
:success
342 assert_equal new_cached_time
, @response.body
345 def test_cache_expiration_isnt_affected_by_request_format
347 cached_time
= content_to_cache
350 @request.set_REQUEST_URI
"/action_caching_test/expire.xml"
351 get
:expire, :format => :xml
355 new_cached_time
= content_to_cache
356 assert_not_equal cached_time
, @response.body
359 def test_cache_is_scoped_by_subdomain
360 @request.host
= 'jamis.hostname.com'
362 jamis_cache
= content_to_cache
366 @request.host
= 'david.hostname.com'
368 david_cache
= content_to_cache
369 assert_not_equal jamis_cache
, @response.body
373 @request.host
= 'jamis.hostname.com'
375 assert_equal jamis_cache
, @response.body
379 @request.host
= 'david.hostname.com'
381 assert_equal david_cache
, @response.body
384 def test_redirect_is_not_cached
386 assert_response
:redirect
390 assert_response
:redirect
393 def test_forbidden_is_not_cached
395 assert_response
:forbidden
399 assert_response
:forbidden
402 def test_xml_version_of_resource_is_treated_as_different_cache
403 with_routing
do |set
|
404 ActionController
::Routing::Routes.draw
do |map
|
405 map
.connect
':controller/:action.:format'
406 map
.connect
':controller/:action'
409 get
:index, :format => 'xml'
410 cached_time
= content_to_cache
411 assert_equal cached_time
, @response.body
412 assert fragment_exist
?('hostname.com/action_caching_test/index.xml')
415 get
:index, :format => 'xml'
416 assert_equal cached_time
, @response.body
417 assert_equal
'application/xml', @response.content_type
423 get
:index, :format => 'xml'
424 assert_not_equal cached_time
, @response.body
428 def test_correct_content_type_is_returned_for_cache_hit
429 # run it twice to cache it the first time
430 get
:index, :id => 'content-type.xml'
431 get
:index, :id => 'content-type.xml'
432 assert_equal
'application/xml', @response.content_type
435 def test_empty_path_is_normalized
436 @mock_controller.mock_url_for
= 'http://example.org/'
437 @mock_controller.mock_path
= '/'
439 assert_equal
'example.org/index', @path_class.path_for(@mock_controller, {})
442 def test_file_extensions
443 get
:index, :id => 'kitten.jpg'
444 get
:index, :id => 'kitten.jpg'
446 assert_response
:success
455 @request = ActionController
::TestRequest.new
456 @response = ActionController
::TestResponse.new
457 @controller = ActionCachingTestController
.new
458 @request.host
= 'hostname.com'
461 def fragment_exist
?(path
)
462 @controller.fragment_exist
?(path
)
465 def read_fragment(path
)
466 @controller.read_fragment(path
)
470 class FragmentCachingTestController
< ActionController
::Base
471 def some_action
; end;
474 class FragmentCachingTest
< Test
::Unit::TestCase
476 ActionController
::Base.perform_caching
= true
477 @store = ActiveSupport
::Cache::MemoryStore.new
478 ActionController
::Base.cache_store
= @store
479 @controller = FragmentCachingTestController
.new
480 @params = {:controller => 'posts', :action => 'index'}
481 @request = ActionController
::TestRequest.new
482 @response = ActionController
::TestResponse.new
483 @controller.params
= @params
484 @controller.request
= @request
485 @controller.response
= @response
486 @controller.send(:initialize_current_url)
487 @controller.send(:initialize_template_class, @response)
488 @controller.send(:assign_shortcuts, @request, @response)
491 def test_fragment_cache_key
492 assert_equal
'views/what a key', @controller.fragment_cache_key('what a key')
493 assert_equal
"views/test.host/fragment_caching_test/some_action",
494 @controller.fragment_cache_key(:controller => 'fragment_caching_test',:action => 'some_action')
497 def test_read_fragment_with_caching_enabled
498 @store.write('views/name', 'value')
499 assert_equal
'value', @controller.read_fragment('name')
502 def test_read_fragment_with_caching_disabled
503 ActionController
::Base.perform_caching
= false
504 @store.write('views/name', 'value')
505 assert_nil
@controller.read_fragment('name')
508 def test_fragment_exist_with_caching_enabled
509 @store.write('views/name', 'value')
510 assert
@controller.fragment_exist
?('name')
511 assert
!@controller.fragment_exist
?('other_name')
514 def test_fragment_exist_with_caching_disabled
515 ActionController
::Base.perform_caching
= false
516 @store.write('views/name', 'value')
517 assert
!@controller.fragment_exist
?('name')
518 assert
!@controller.fragment_exist
?('other_name')
521 def test_write_fragment_with_caching_enabled
522 assert_nil
@store.read('views/name')
523 assert_equal
'value', @controller.write_fragment('name', 'value')
524 assert_equal
'value', @store.read('views/name')
527 def test_write_fragment_with_caching_disabled
528 assert_nil
@store.read('views/name')
529 ActionController
::Base.perform_caching
= false
530 assert_equal
nil, @controller.write_fragment('name', 'value')
531 assert_nil
@store.read('views/name')
534 def test_expire_fragment_with_simple_key
535 @store.write('views/name', 'value')
536 @controller.expire_fragment
'name'
537 assert_nil
@store.read('views/name')
540 def test_expire_fragment_with_regexp
541 @store.write('views/name', 'value')
542 @store.write('views/another_name', 'another_value')
543 @store.write('views/primalgrasp', 'will not expire ;-)')
545 @controller.expire_fragment
/name/
547 assert_nil
@store.read('views/name')
548 assert_nil
@store.read('views/another_name')
549 assert_equal
'will not expire ;-)', @store.read('views/primalgrasp')
552 def test_fragment_for_with_disabled_caching
553 ActionController
::Base.perform_caching
= false
555 @store.write('views/expensive', 'fragment content')
556 fragment_computed
= false
558 buffer
= 'generated till now -> '
559 @controller.fragment_for(buffer
, 'expensive') { fragment_computed
= true }
561 assert fragment_computed
562 assert_equal
'generated till now -> ', buffer
565 def test_fragment_for
566 @store.write('views/expensive', 'fragment content')
567 fragment_computed
= false
569 buffer
= 'generated till now -> '
570 @controller.fragment_for(buffer
, 'expensive') { fragment_computed
= true }
572 assert
!fragment_computed
573 assert_equal
'generated till now -> fragment content', buffer
577 class FunctionalCachingController
< ActionController
::Base
581 def html_fragment_cached_with_partial
582 respond_to
do |format
|
587 def js_fragment_cached_with_partial
588 respond_to
do |format
|
593 def formatted_fragment_cached
594 respond_to
do |format
|
606 class FunctionalFragmentCachingTest
< Test
::Unit::TestCase
608 ActionController
::Base.perform_caching
= true
609 @store = ActiveSupport
::Cache::MemoryStore.new
610 ActionController
::Base.cache_store
= @store
611 @controller = FunctionalCachingController
.new
612 @request = ActionController
::TestRequest.new
613 @response = ActionController
::TestResponse.new
616 def test_fragment_caching
618 assert_response
:success
619 expected_body
= <<-CACHED
621 This bit's fragment cached
623 assert_equal expected_body
, @response.body
625 assert_equal
"This bit's fragment cached", @store.read('views/test.host/functional_caching/fragment_cached')
628 def test_fragment_caching_in_partials
629 get
:html_fragment_cached_with_partial
630 assert_response
:success
631 assert_match
/Fragment caching in a partial/, @response.body
632 assert_match
"Fragment caching in a partial", @store.read('views/test.host/functional_caching/html_fragment_cached_with_partial')
635 def test_render_inline_before_fragment_caching
636 get
:inline_fragment_cached
637 assert_response
:success
638 assert_match
/Some inline content/, @response.body
639 assert_match
/Some cached content/, @response.body
640 assert_match
"Some cached content", @store.read('views/test.host/functional_caching/inline_fragment_cached')
643 def test_fragment_caching_in_rjs_partials
644 xhr
:get, :js_fragment_cached_with_partial
645 assert_response
:success
646 assert_match
/Fragment caching in a partial/, @response.body
647 assert_match
"Fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial')
650 def test_html_formatted_fragment_caching
651 get
:formatted_fragment_cached, :format => "html"
652 assert_response
:success
653 expected_body
= "<body>\n<p>ERB</p>\n</body>"
655 assert_equal expected_body
, @response.body
657 assert_equal
"<p>ERB</p>", @store.read('views/test.host/functional_caching/formatted_fragment_cached')
660 def test_xml_formatted_fragment_caching
661 get
:formatted_fragment_cached, :format => "xml"
662 assert_response
:success
663 expected_body
= "<body>\n <p>Builder</p>\n</body>\n"
665 assert_equal expected_body
, @response.body
667 assert_equal
" <p>Builder</p>\n", @store.read('views/test.host/functional_caching/formatted_fragment_cached')
670 def test_js_formatted_fragment_caching
671 get
:formatted_fragment_cached, :format => "js"
672 assert_response
:success
673 expected_body
= %(title = "Hey";\n$("element_1").visualEffect("highlight");\n) +
674 %($("element_2").visualEffect("highlight");\nfooter = "Bye";)
675 assert_equal expected_body, @response.body
677 assert_equal ['$("element_1").visualEffect("highlight");', '$("element_2").visualEffect("highlight");'],
678 @store.read('views/test.host/functional_caching/formatted_fragment_cached')