require 'fileutils' require 'abstract_unit' require 'mailers/base_mailer' require 'mailers/caching_mailer' CACHE_DIR = 'test_cache' # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR) class FragmentCachingMailer < ActionMailer::Base abstract! def some_action; end end class BaseCachingTest < ActiveSupport::TestCase def setup super @store = ActiveSupport::Cache::MemoryStore.new @mailer = FragmentCachingMailer.new @mailer.perform_caching = true @mailer.cache_store = @store end def test_fragment_cache_key assert_equal 'views/what a key', @mailer.fragment_cache_key('what a key') end end class FragmentCachingTest < BaseCachingTest def test_read_fragment_with_caching_enabled @store.write('views/name', 'value') assert_equal 'value', @mailer.read_fragment('name') end def test_read_fragment_with_caching_disabled @mailer.perform_caching = false @store.write('views/name', 'value') assert_nil @mailer.read_fragment('name') end def test_fragment_exist_with_caching_enabled @store.write('views/name', 'value') assert @mailer.fragment_exist?('name') assert !@mailer.fragment_exist?('other_name') end def test_fragment_exist_with_caching_disabled @mailer.perform_caching = false @store.write('views/name', 'value') assert !@mailer.fragment_exist?('name') assert !@mailer.fragment_exist?('other_name') end def test_write_fragment_with_caching_enabled assert_nil @store.read('views/name') assert_equal 'value', @mailer.write_fragment('name', 'value') assert_equal 'value', @store.read('views/name') end def test_write_fragment_with_caching_disabled assert_nil @store.read('views/name') @mailer.perform_caching = false assert_equal 'value', @mailer.write_fragment('name', 'value') assert_nil @store.read('views/name') end def test_expire_fragment_with_simple_key @store.write('views/name', 'value') @mailer.expire_fragment 'name' assert_nil @store.read('views/name') end def test_expire_fragment_with_regexp @store.write('views/name', 'value') @store.write('views/another_name', 'another_value') @store.write('views/primalgrasp', 'will not expire ;-)') @mailer.expire_fragment(/name/) assert_nil @store.read('views/name') assert_nil @store.read('views/another_name') assert_equal 'will not expire ;-)', @store.read('views/primalgrasp') end def test_fragment_for @store.write('views/expensive', 'fragment content') fragment_computed = false view_context = @mailer.view_context buffer = 'generated till now -> '.html_safe buffer << view_context.send(:fragment_for, 'expensive') { fragment_computed = true } assert !fragment_computed assert_equal 'generated till now -> fragment content', buffer end def test_html_safety assert_nil @store.read('views/name') content = 'value'.html_safe assert_equal content, @mailer.write_fragment('name', content) cached = @store.read('views/name') assert_equal content, cached assert_equal String, cached.class html_safe = @mailer.read_fragment('name') assert_equal content, html_safe assert html_safe.html_safe? end end class FunctionalFragmentCachingTest < BaseCachingTest def setup super @store = ActiveSupport::Cache::MemoryStore.new @mailer = CachingMailer.new @mailer.perform_caching = true @mailer.cache_store = @store end def test_fragment_caching email = @mailer.fragment_cache expected_body = "\"Welcome\"" assert_match expected_body, email.body.encoded assert_match expected_body, @store.read("views/caching/#{template_digest("caching_mailer/fragment_cache")}") end def test_fragment_caching_in_partials email = @mailer.fragment_cache_in_partials expected_body = 'Old fragment caching in a partial' assert_match(expected_body, email.body.encoded) assert_match(expected_body, @store.read("views/caching/#{template_digest("caching_mailer/_partial")}")) end def test_skip_fragment_cache_digesting email = @mailer.skip_fragment_cache_digesting expected_body = "No Digest" assert_match expected_body, email.body.encoded assert_match expected_body, @store.read("views/no_digest") end def test_fragment_caching_options time = Time.now email = @mailer.fragment_caching_options expected_body = "No Digest" assert_match expected_body, email.body.encoded Time.stub(:now, time + 11) do assert_nil @store.read("views/no_digest") end end def test_multipart_fragment_caching email = @mailer.multipart_cache expected_text_body = "\"Welcome text\"" expected_html_body = "\"Welcome html\"" encoded_body = email.body.encoded assert_match expected_text_body, encoded_body assert_match expected_html_body, encoded_body assert_match expected_text_body, @store.read("views/text_caching") assert_match expected_html_body, @store.read("views/html_caching") end def test_fragment_cache_instrumentation payload = nil subscriber = proc do |*args| event = ActiveSupport::Notifications::Event.new(*args) payload = event.payload end ActiveSupport::Notifications.subscribed(subscriber, "read_fragment.action_mailer") do @mailer.fragment_cache end assert_equal "caching_mailer", payload[:mailer] assert_equal "views/caching/#{template_digest("caching_mailer/fragment_cache")}", payload[:key] end private def template_digest(name) ActionView::Digestor.digest(name: name, finder: @mailer.lookup_context) end end class CacheHelperOutputBufferTest < BaseCachingTest class MockController def read_fragment(name, options) return false end def write_fragment(name, fragment, options) fragment end end def setup super end def test_output_buffer output_buffer = ActionView::OutputBuffer.new controller = MockController.new cache_helper = Class.new do def self.controller; end; def self.output_buffer; end; def self.output_buffer=; end; end cache_helper.extend(ActionView::Helpers::CacheHelper) cache_helper.stub :controller, controller do cache_helper.stub :output_buffer, output_buffer do assert_called_with cache_helper, :output_buffer=, [output_buffer.class.new(output_buffer)] do assert_nothing_raised do cache_helper.send :fragment_for, 'Test fragment name', 'Test fragment', &Proc.new{ nil } end end end end end def test_safe_buffer output_buffer = ActiveSupport::SafeBuffer.new controller = MockController.new cache_helper = Class.new do def self.controller; end; def self.output_buffer; end; def self.output_buffer=; end; end cache_helper.extend(ActionView::Helpers::CacheHelper) cache_helper.stub :controller, controller do cache_helper.stub :output_buffer, output_buffer do assert_called_with cache_helper, :output_buffer=, [output_buffer.class.new(output_buffer)] do assert_nothing_raised do cache_helper.send :fragment_for, 'Test fragment name', 'Test fragment', &Proc.new{ nil } end end end end end end class ViewCacheDependencyTest < BaseCachingTest class NoDependenciesMailer < ActionMailer::Base end class HasDependenciesMailer < ActionMailer::Base view_cache_dependency { "trombone" } view_cache_dependency { "flute" } end def test_view_cache_dependencies_are_empty_by_default assert NoDependenciesMailer.new.view_cache_dependencies.empty? end def test_view_cache_dependencies_are_listed_in_declaration_order assert_equal %w(trombone flute), HasDependenciesMailer.new.view_cache_dependencies end end