actionpack-page_caching 1.0.2 → 1.1.0

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.

Potentially problematic release.


This version of actionpack-page_caching might be problematic. Click here for more details.

@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "4-1-stable"
6
+ gem "mime-types", "< 3"
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "4-2-stable"
6
+ gem "mime-types", "< 3"
7
+
8
+ if RUBY_VERSION < "2.1"
9
+ gem "nokogiri", "< 1.7"
10
+ end
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "5-0-stable"
@@ -1,5 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- gemspec path: '..'
3
+ gemspec path: ".."
4
4
 
5
- gem 'rails', github: 'rails/rails', branch: 'master'
5
+ gem "rails", github: "rails/rails", branch: "master"
6
+ gem "arel", github: "rails/arel", branch: "master"
@@ -1,5 +1,7 @@
1
- require 'fileutils'
2
- require 'active_support/core_ext/class/attribute_accessors'
1
+ require "fileutils"
2
+ require "uri"
3
+ require "active_support/core_ext/class/attribute_accessors"
4
+ require "active_support/core_ext/string/strip"
3
5
 
4
6
  module ActionController
5
7
  module Caching
@@ -32,8 +34,8 @@ module ActionController
32
34
  # class WeblogController < ActionController::Base
33
35
  # def update
34
36
  # List.update(params[:list][:id], params[:list])
35
- # expire_page action: 'show', id: params[:list][:id]
36
- # redirect_to action: 'show', id: params[:list][:id]
37
+ # expire_page action: "show", id: params[:list][:id]
38
+ # redirect_to action: "show", id: params[:list][:id]
37
39
  # end
38
40
  # end
39
41
  #
@@ -51,7 +53,7 @@ module ActionController
51
53
  # likely require configuring your web server to look in the new location for
52
54
  # cached files.
53
55
  class_attribute :page_cache_directory
54
- self.page_cache_directory ||= ''
56
+ self.page_cache_directory ||= ""
55
57
 
56
58
  # The compression used for gzip. If +false+ (default), the page is not compressed.
57
59
  # If can be a symbol showing the ZLib compression method, for example, <tt>:best_compression</tt>
@@ -60,33 +62,137 @@ module ActionController
60
62
  self.page_cache_compression ||= false
61
63
  end
62
64
 
65
+ class PageCache #:nodoc:
66
+ def initialize(cache_directory, default_extension, controller = nil)
67
+ @cache_directory = cache_directory
68
+ @default_extension = default_extension
69
+ @controller = controller
70
+ end
71
+
72
+ def expire(path)
73
+ instrument :expire_page, path do
74
+ delete(cache_path(path))
75
+ end
76
+ end
77
+
78
+ def cache(content, path, extension = nil, gzip = Zlib::BEST_COMPRESSION)
79
+ instrument :write_page, path do
80
+ write(content, cache_path(path, extension), gzip)
81
+ end
82
+ end
83
+
84
+ private
85
+ def cache_directory
86
+ case @cache_directory
87
+ when Proc
88
+ handle_proc_cache_directory
89
+ when Symbol
90
+ handle_symbol_cache_directory
91
+ else
92
+ handle_default_cache_directory
93
+ end
94
+ end
95
+
96
+ def handle_proc_cache_directory
97
+ if @controller
98
+ @controller.instance_exec(&@cache_directory)
99
+ else
100
+ raise_runtime_error
101
+ end
102
+ end
103
+
104
+ def handle_symbol_cache_directory
105
+ if @controller
106
+ @controller.send(@cache_directory)
107
+ else
108
+ raise_runtime_error
109
+ end
110
+ end
111
+
112
+ def handle_callable_cache_directory
113
+ if @controller
114
+ @cache_directory.call(@controller.request)
115
+ else
116
+ raise_runtime_error
117
+ end
118
+ end
119
+
120
+ def handle_default_cache_directory
121
+ if @cache_directory.respond_to?(:call)
122
+ handle_callable_cache_directory
123
+ else
124
+ @cache_directory.to_s
125
+ end
126
+ end
127
+
128
+ def raise_runtime_error
129
+ raise RuntimeError, <<-MSG.strip_heredoc
130
+ Dynamic page_cache_directory used with class-level cache_page method
131
+
132
+ You have specified either a Proc, Symbol or callable object for page_cache_directory
133
+ which needs to be executed within the context of a request. If you need to call the
134
+ cache_page method from a class-level context then set the page_cache_directory to a
135
+ static value and override the setting at the instance-level using before_action.
136
+ MSG
137
+ end
138
+
139
+ def default_extension
140
+ @default_extension
141
+ end
142
+
143
+ def cache_file(path, extension)
144
+ if path.empty? || path == "/"
145
+ name = "/index"
146
+ else
147
+ name = URI.parser.unescape(path.chomp("/"))
148
+ end
149
+
150
+ if File.extname(name).empty?
151
+ name + (extension || default_extension)
152
+ else
153
+ name
154
+ end
155
+ end
156
+
157
+ def cache_path(path, extension = nil)
158
+ File.join(cache_directory, cache_file(path, extension))
159
+ end
160
+
161
+ def delete(path)
162
+ File.delete(path) if File.exist?(path)
163
+ File.delete(path + ".gz") if File.exist?(path + ".gz")
164
+ end
165
+
166
+ def write(content, path, gzip)
167
+ FileUtils.makedirs(File.dirname(path))
168
+ File.open(path, "wb+") { |f| f.write(content) }
169
+
170
+ if gzip
171
+ Zlib::GzipWriter.open(path + ".gz", gzip) { |f| f.write(content) }
172
+ end
173
+ end
174
+
175
+ def instrument(name, path)
176
+ ActiveSupport::Notifications.instrument("#{name}.action_controller", path: path) { yield }
177
+ end
178
+ end
179
+
63
180
  module ClassMethods
64
181
  # Expires the page that was cached with the +path+ as a key.
65
182
  #
66
- # expire_page '/lists/show'
183
+ # expire_page "/lists/show"
67
184
  def expire_page(path)
68
- return unless perform_caching
69
- path = page_cache_path(path)
70
-
71
- instrument_page_cache :expire_page, path do
72
- File.delete(path) if File.exist?(path)
73
- File.delete(path + '.gz') if File.exist?(path + '.gz')
185
+ if perform_caching
186
+ page_cache.expire(path)
74
187
  end
75
188
  end
76
189
 
77
190
  # Manually cache the +content+ in the key determined by +path+.
78
191
  #
79
- # cache_page "I'm the cached content", '/lists/show'
192
+ # cache_page "I'm the cached content", "/lists/show"
80
193
  def cache_page(content, path, extension = nil, gzip = Zlib::BEST_COMPRESSION)
81
- return unless perform_caching
82
- path = page_cache_path(path, extension)
83
-
84
- instrument_page_cache :write_page, path do
85
- FileUtils.makedirs(File.dirname(path))
86
- File.open(path, 'wb+') { |f| f.write(content) }
87
- if gzip
88
- Zlib::GzipWriter.open(path + '.gz', gzip) { |f| f.write(content) }
89
- end
194
+ if perform_caching
195
+ page_cache.cache(content, path, extension, gzip)
90
196
  end
91
197
  end
92
198
 
@@ -105,60 +211,50 @@ module ActionController
105
211
  # # don't gzip images
106
212
  # caches_page :image, gzip: false
107
213
  def caches_page(*actions)
108
- return unless perform_caching
109
- options = actions.extract_options!
110
-
111
- gzip_level = options.fetch(:gzip, page_cache_compression)
112
- gzip_level = case gzip_level
113
- when Symbol
114
- Zlib.const_get(gzip_level.upcase)
115
- when Fixnum
116
- gzip_level
117
- when false
118
- nil
119
- else
120
- Zlib::BEST_COMPRESSION
121
- end
214
+ if perform_caching
215
+ options = actions.extract_options!
122
216
 
123
- after_filter({only: actions}.merge(options)) do |c|
124
- c.cache_page(nil, nil, gzip_level)
125
- end
126
- end
217
+ gzip_level = options.fetch(:gzip, page_cache_compression)
218
+ gzip_level = \
219
+ case gzip_level
220
+ when Symbol
221
+ Zlib.const_get(gzip_level.upcase)
222
+ when Integer
223
+ gzip_level
224
+ when false
225
+ nil
226
+ else
227
+ Zlib::BEST_COMPRESSION
228
+ end
127
229
 
128
- private
129
- def page_cache_file(path, extension)
130
- name = (path.empty? || path == '/') ? '/index' : URI.parser.unescape(path.chomp('/'))
131
- unless (name.split('/').last || name).include? '.'
132
- name << (extension || self.default_static_extension)
230
+ after_action({ only: actions }.merge(options)) do |c|
231
+ c.cache_page(nil, nil, gzip_level)
133
232
  end
134
- return name
135
- end
136
-
137
- def page_cache_path(path, extension = nil)
138
- page_cache_directory.to_s + page_cache_file(path, extension)
139
233
  end
234
+ end
140
235
 
141
- def instrument_page_cache(name, path)
142
- ActiveSupport::Notifications.instrument("#{name}.action_controller", path: path){ yield }
236
+ private
237
+ def page_cache
238
+ PageCache.new(page_cache_directory, default_static_extension)
143
239
  end
144
240
  end
145
241
 
146
242
  # Expires the page that was cached with the +options+ as a key.
147
243
  #
148
- # expire_page controller: 'lists', action: 'show'
244
+ # expire_page controller: "lists", action: "show"
149
245
  def expire_page(options = {})
150
- return unless self.class.perform_caching
151
-
152
- if options.is_a?(Hash)
153
- if options[:action].is_a?(Array)
154
- options[:action].each do |action|
155
- self.class.expire_page(url_for(options.merge(only_path: true, action: action)))
246
+ if perform_caching?
247
+ case options
248
+ when Hash
249
+ case options[:action]
250
+ when Array
251
+ options[:action].each { |action| expire_page(options.merge(action: action)) }
252
+ else
253
+ page_cache.expire(url_for(options.merge(only_path: true)))
156
254
  end
157
255
  else
158
- self.class.expire_page(url_for(options.merge(only_path: true)))
256
+ page_cache.expire(options)
159
257
  end
160
- else
161
- self.class.expire_page(options)
162
258
  end
163
259
  end
164
260
 
@@ -166,29 +262,39 @@ module ActionController
166
262
  # the contents of response.body is used. If no options are provided, the url of the current
167
263
  # request being handled is used.
168
264
  #
169
- # cache_page "I'm the cached content", controller: 'lists', action: 'show'
265
+ # cache_page "I'm the cached content", controller: "lists", action: "show"
170
266
  def cache_page(content = nil, options = nil, gzip = Zlib::BEST_COMPRESSION)
171
- return unless self.class.perform_caching && caching_allowed?
267
+ if perform_caching? && caching_allowed?
268
+ path = \
269
+ case options
270
+ when Hash
271
+ url_for(options.merge(only_path: true, format: params[:format]))
272
+ when String
273
+ options
274
+ else
275
+ request.path
276
+ end
172
277
 
173
- path = case options
174
- when Hash
175
- url_for(options.merge(only_path: true, format: params[:format]))
176
- when String
177
- options
178
- else
179
- request.path
180
- end
278
+ if (type = Mime::LOOKUP[self.content_type]) && (type_symbol = type.symbol).present?
279
+ extension = ".#{type_symbol}"
280
+ end
181
281
 
182
- if (type = Mime::LOOKUP[self.content_type]) && (type_symbol = type.symbol).present?
183
- extension = ".#{type_symbol}"
282
+ page_cache.cache(content || response.body, path, extension, gzip)
184
283
  end
185
-
186
- self.class.cache_page(content || response.body, path, extension, gzip)
187
284
  end
188
285
 
189
286
  def caching_allowed?
190
287
  (request.get? || request.head?) && response.status == 200
191
288
  end
289
+
290
+ def perform_caching?
291
+ self.class.perform_caching
292
+ end
293
+
294
+ private
295
+ def page_cache
296
+ PageCache.new(page_cache_directory, default_static_extension, self)
297
+ end
192
298
  end
193
299
  end
194
300
  end
@@ -1,4 +1,4 @@
1
- require 'action_controller/caching/pages'
1
+ require "action_controller/caching/pages"
2
2
 
3
3
  module ActionController
4
4
  module Caching
@@ -1 +1 @@
1
- require 'actionpack/page_caching/railtie'
1
+ require "actionpack/page_caching/railtie"
@@ -1,16 +1,16 @@
1
- require 'rails/railtie'
1
+ require "rails/railtie"
2
2
 
3
3
  module ActionPack
4
4
  module PageCaching
5
5
  class Railtie < Rails::Railtie
6
- initializer 'action_pack.page_caching' do
6
+ initializer "action_pack.page_caching" do
7
7
  ActiveSupport.on_load(:action_controller) do
8
- require 'action_controller/page_caching'
8
+ require "action_controller/page_caching"
9
9
  end
10
10
  end
11
11
 
12
- initializer 'action_pack.page_caching.set_config', before: 'action_controller.set_configs' do |app|
13
- app.config.action_controller.page_cache_directory ||= app.config.paths['public'].first
12
+ initializer "action_pack.page_caching.set_config", before: "action_controller.set_configs" do |app|
13
+ app.config.action_controller.page_cache_directory ||= app.config.paths["public"].first
14
14
  end
15
15
  end
16
16
  end
@@ -1,22 +1,12 @@
1
- require 'bundler/setup'
2
- require 'minitest/autorun'
3
- require 'action_controller'
4
- require 'action_controller/page_caching'
1
+ require "bundler/setup"
2
+ require "minitest/autorun"
3
+ require "action_controller"
4
+ require "action_controller/page_caching"
5
5
 
6
- SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
7
-
8
- module ActionController
9
- class Base
10
- include SharedTestRoutes.url_helpers
11
- end
12
-
13
- class TestCase
14
- def setup
15
- @routes = SharedTestRoutes
6
+ if ActiveSupport.respond_to?(:test_order)
7
+ ActiveSupport.test_order = :random
8
+ end
16
9
 
17
- @routes.draw do
18
- get ':controller(/:action)'
19
- end
20
- end
21
- end
10
+ if ActionController::Base.respond_to?(:enable_fragment_cache_logging=)
11
+ ActionController::Base.enable_fragment_cache_logging = true
22
12
  end
@@ -1,12 +1,69 @@
1
- require 'abstract_unit'
1
+ require "abstract_unit"
2
+ require "mocha/setup"
2
3
 
3
- CACHE_DIR = 'test_cache'
4
- # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
5
- FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
4
+ CACHE_DIR = "test_cache"
5
+ # Don't change "../tmp" cavalierly or you might hose something you don't want hosed
6
+ TEST_TMP_DIR = File.expand_path("../tmp", __FILE__)
7
+ FILE_STORE_PATH = File.join(TEST_TMP_DIR, CACHE_DIR)
8
+
9
+ module PageCachingTestHelpers
10
+ def setup
11
+ super
12
+
13
+ @routes = ActionDispatch::Routing::RouteSet.new
14
+
15
+ FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
16
+ FileUtils.mkdir_p(FILE_STORE_PATH)
17
+ end
18
+
19
+ def teardown
20
+ super
21
+
22
+ FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
23
+ @controller.perform_caching = false
24
+ end
25
+
26
+ private
27
+
28
+ def assert_page_cached(action, options = {})
29
+ expected = options[:content] || action.to_s
30
+ path = cache_file(action, options)
31
+
32
+ assert File.exist?(path), "The cache file #{path} doesn't exist"
33
+
34
+ if File.extname(path) == ".gz"
35
+ actual = Zlib::GzipReader.open(path) { |f| f.read }
36
+ else
37
+ actual = File.read(path)
38
+ end
39
+
40
+ assert_equal expected, actual, "The cached content doesn't match the expected value"
41
+ end
42
+
43
+ def assert_page_not_cached(action, options = {})
44
+ path = cache_file(action, options)
45
+ assert !File.exist?(path), "The cache file #{path} still exists"
46
+ end
47
+
48
+ def cache_file(action, options = {})
49
+ path = options[:path] || FILE_STORE_PATH
50
+ controller = options[:controller] || self.class.name.underscore
51
+ format = options[:format] || "html"
52
+
53
+ "#{path}/#{controller}/#{action}.#{format}"
54
+ end
55
+
56
+ def draw(&block)
57
+ @routes = ActionDispatch::Routing::RouteSet.new
58
+ @routes.draw(&block)
59
+ @controller.extend(@routes.url_helpers)
60
+ end
61
+ end
6
62
 
7
63
  class CachingMetalController < ActionController::Metal
8
64
  abstract!
9
65
 
66
+ include AbstractController::Callbacks
10
67
  include ActionController::Caching
11
68
 
12
69
  self.page_cache_directory = FILE_STORE_PATH
@@ -17,28 +74,22 @@ class PageCachingMetalTestController < CachingMetalController
17
74
  caches_page :ok
18
75
 
19
76
  def ok
20
- self.response_body = 'ok'
77
+ self.response_body = "ok"
21
78
  end
22
79
  end
23
80
 
24
81
  class PageCachingMetalTest < ActionController::TestCase
82
+ include PageCachingTestHelpers
25
83
  tests PageCachingMetalTestController
26
84
 
27
- def setup
28
- super
29
-
30
- FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
31
- FileUtils.mkdir_p(FILE_STORE_PATH)
32
- end
33
-
34
- def teardown
35
- FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
36
- end
37
-
38
85
  def test_should_cache_get_with_ok_status
86
+ draw do
87
+ get "/page_caching_metal_test/ok", to: "page_caching_metal_test#ok"
88
+ end
89
+
39
90
  get :ok
40
91
  assert_response :ok
41
- assert File.exist?("#{FILE_STORE_PATH}/page_caching_metal_test/ok.html"), 'get with ok status should have been cached'
92
+ assert_page_cached :ok
42
93
  end
43
94
  end
44
95
 
@@ -48,6 +99,17 @@ class CachingController < ActionController::Base
48
99
  abstract!
49
100
 
50
101
  self.cache_store = :file_store, FILE_STORE_PATH
102
+
103
+ protected
104
+ if ActionPack::VERSION::STRING < "4.1"
105
+ def render(options)
106
+ if options.key?(:html)
107
+ super({ text: options.delete(:html) }.merge(options))
108
+ else
109
+ super
110
+ end
111
+ end
112
+ end
51
113
  end
52
114
 
53
115
  class PageCachingTestController < CachingController
@@ -61,7 +123,7 @@ class PageCachingTestController < CachingController
61
123
  caches_page :gzip_level, gzip: :best_speed
62
124
 
63
125
  def ok
64
- head :ok
126
+ render html: "ok"
65
127
  end
66
128
 
67
129
  def no_content
@@ -69,7 +131,7 @@ class PageCachingTestController < CachingController
69
131
  end
70
132
 
71
133
  def found
72
- redirect_to action: 'ok'
134
+ redirect_to action: "ok"
73
135
  end
74
136
 
75
137
  def not_found
@@ -77,170 +139,204 @@ class PageCachingTestController < CachingController
77
139
  end
78
140
 
79
141
  def custom_path
80
- render text: 'Super soaker'
81
- cache_page('Super soaker', '/index.html')
142
+ render html: "custom_path"
143
+ cache_page(nil, "/index.html")
82
144
  end
83
145
 
84
146
  def default_gzip
85
- render text: 'Text'
147
+ render html: "default_gzip"
86
148
  end
87
149
 
88
150
  def no_gzip
89
- render text: 'PNG'
151
+ render html: "no_gzip"
90
152
  end
91
153
 
92
154
  def gzip_level
93
- render text: 'Big text'
155
+ render html: "gzip_level"
94
156
  end
95
157
 
96
158
  def expire_custom_path
97
- expire_page('/index.html')
159
+ expire_page("/index.html")
98
160
  head :ok
99
161
  end
100
162
 
101
163
  def trailing_slash
102
- render text: 'Sneak attack'
164
+ render html: "trailing_slash"
103
165
  end
104
166
 
105
167
  def about_me
106
168
  respond_to do |format|
107
- format.html { render text: 'I am html' }
108
- format.xml { render text: 'I am xml' }
169
+ format.html { render html: "I am html" }
170
+ format.xml { render xml: "I am xml" }
109
171
  end
110
172
  end
111
173
  end
112
174
 
113
175
  class PageCachingTest < ActionController::TestCase
114
- def setup
115
- super
116
-
117
- @request = ActionController::TestRequest.new
118
- @request.host = 'hostname.com'
119
- @request.env.delete('PATH_INFO')
176
+ include PageCachingTestHelpers
177
+ tests PageCachingTestController
120
178
 
121
- @controller = PageCachingTestController.new
122
- @controller.perform_caching = true
123
- @controller.cache_store = :file_store, FILE_STORE_PATH
124
-
125
- @response = ActionController::TestResponse.new
179
+ def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
180
+ draw do
181
+ get "posts.:format", to: "posts#index", as: :formatted_posts
182
+ get "/", to: "posts#index", as: :main
183
+ end
126
184
 
127
- @params = { controller: 'posts', action: 'index', only_path: true }
185
+ defaults = { controller: "posts", action: "index", only_path: true }
128
186
 
129
- FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
130
- FileUtils.mkdir_p(FILE_STORE_PATH)
187
+ assert_equal "/posts.rss", @routes.url_for(defaults.merge(format: "rss"))
188
+ assert_equal "/", @routes.url_for(defaults.merge(format: nil))
131
189
  end
132
190
 
133
- def teardown
134
- FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
135
- @controller.perform_caching = false
136
- end
137
-
138
- def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
139
- with_routing do |set|
140
- set.draw do
141
- get 'posts.:format', to: 'posts#index', as: :formatted_posts
142
- get '/', to: 'posts#index', as: :main
143
- end
144
- @params[:format] = 'rss'
145
- assert_equal '/posts.rss', @routes.url_for(@params)
146
- @params[:format] = nil
147
- assert_equal '/', @routes.url_for(@params)
191
+ def test_should_cache_head_with_ok_status
192
+ draw do
193
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
148
194
  end
149
- end
150
195
 
151
- def test_should_cache_head_with_ok_status
152
196
  head :ok
153
197
  assert_response :ok
154
- assert_page_cached :ok, 'head with ok status should have been cached'
198
+ assert_page_cached :ok
155
199
  end
156
200
 
157
201
  def test_should_cache_get_with_ok_status
202
+ draw do
203
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
204
+ end
205
+
158
206
  get :ok
159
207
  assert_response :ok
160
- assert_page_cached :ok, 'get with ok status should have been cached'
208
+ assert_page_cached :ok
161
209
  end
162
210
 
163
211
  def test_should_cache_with_custom_path
212
+ draw do
213
+ get "/page_caching_test/custom_path", to: "page_caching_test#custom_path"
214
+ end
215
+
164
216
  get :custom_path
165
- assert File.exist?("#{FILE_STORE_PATH}/index.html")
217
+ assert_page_cached :index, controller: ".", content: "custom_path"
166
218
  end
167
219
 
168
220
  def test_should_expire_cache_with_custom_path
221
+ draw do
222
+ get "/page_caching_test/custom_path", to: "page_caching_test#custom_path"
223
+ get "/page_caching_test/expire_custom_path", to: "page_caching_test#expire_custom_path"
224
+ end
225
+
169
226
  get :custom_path
170
- assert File.exist?("#{FILE_STORE_PATH}/index.html")
227
+ assert_page_cached :index, controller: ".", content: "custom_path"
171
228
 
172
229
  get :expire_custom_path
173
- assert !File.exist?("#{FILE_STORE_PATH}/index.html")
230
+ assert_page_not_cached :index, controller: ".", content: "custom_path"
174
231
  end
175
232
 
176
233
  def test_should_gzip_cache
234
+ draw do
235
+ get "/page_caching_test/custom_path", to: "page_caching_test#custom_path"
236
+ get "/page_caching_test/expire_custom_path", to: "page_caching_test#expire_custom_path"
237
+ end
238
+
177
239
  get :custom_path
178
- assert File.exist?("#{FILE_STORE_PATH}/index.html.gz")
240
+ assert_page_cached :index, controller: ".", format: "html.gz", content: "custom_path"
179
241
 
180
242
  get :expire_custom_path
181
- assert !File.exist?("#{FILE_STORE_PATH}/index.html.gz")
243
+ assert_page_not_cached :index, controller: ".", format: "html.gz"
182
244
  end
183
245
 
184
246
  def test_should_allow_to_disable_gzip
247
+ draw do
248
+ get "/page_caching_test/no_gzip", to: "page_caching_test#no_gzip"
249
+ end
250
+
185
251
  get :no_gzip
186
- assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/no_gzip.html")
187
- assert !File.exist?("#{FILE_STORE_PATH}/page_caching_test/no_gzip.html.gz")
252
+ assert_page_cached :no_gzip, format: "html"
253
+ assert_page_not_cached :no_gzip, format: "html.gz"
188
254
  end
189
255
 
190
256
  def test_should_use_config_gzip_by_default
257
+ draw do
258
+ get "/page_caching_test/default_gzip", to: "page_caching_test#default_gzip"
259
+ end
260
+
191
261
  @controller.expects(:cache_page).with(nil, nil, Zlib::BEST_COMPRESSION)
192
262
  get :default_gzip
193
263
  end
194
264
 
195
265
  def test_should_set_gzip_level
266
+ draw do
267
+ get "/page_caching_test/gzip_level", to: "page_caching_test#gzip_level"
268
+ end
269
+
196
270
  @controller.expects(:cache_page).with(nil, nil, Zlib::BEST_SPEED)
197
271
  get :gzip_level
198
272
  end
199
273
 
200
274
  def test_should_cache_without_trailing_slash_on_url
201
- @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash'
202
- assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
275
+ @controller.class.cache_page "cached content", "/page_caching_test/trailing_slash"
276
+ assert_page_cached :trailing_slash, content: "cached content"
203
277
  end
204
278
 
205
279
  def test_should_obey_http_accept_attribute
206
- @request.env['HTTP_ACCEPT'] = 'text/xml'
280
+ draw do
281
+ get "/page_caching_test/about_me", to: "page_caching_test#about_me"
282
+ end
283
+
284
+ @request.env["HTTP_ACCEPT"] = "text/xml"
207
285
  get :about_me
208
- assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/about_me.xml")
209
- assert_equal 'I am xml', @response.body
286
+ assert_equal "I am xml", @response.body
287
+ assert_page_cached :about_me, format: "xml", content: "I am xml"
210
288
  end
211
289
 
212
290
  def test_cached_page_should_not_have_trailing_slash_even_if_url_has_trailing_slash
213
- @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash/'
214
- assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
291
+ @controller.class.cache_page "cached content", "/page_caching_test/trailing_slash/"
292
+ assert_page_cached :trailing_slash, content: "cached content"
215
293
  end
216
294
 
217
295
  def test_should_cache_ok_at_custom_path
218
- @request.env['PATH_INFO'] = '/index.html'
296
+ draw do
297
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
298
+ end
299
+
300
+ @request.env["PATH_INFO"] = "/index.html"
219
301
  get :ok
220
302
  assert_response :ok
221
- assert File.exist?("#{FILE_STORE_PATH}/index.html")
303
+ assert_page_cached :index, controller: ".", content: "ok"
222
304
  end
223
305
 
224
306
  [:ok, :no_content, :found, :not_found].each do |status|
225
307
  [:get, :post, :patch, :put, :delete].each do |method|
226
308
  unless method == :get && status == :ok
227
309
  define_method "test_shouldnt_cache_#{method}_with_#{status}_status" do
310
+ draw do
311
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
312
+ match "/page_caching_test/#{status}", to: "page_caching_test##{status}", via: method
313
+ end
314
+
228
315
  send(method, status)
229
316
  assert_response status
230
- assert_page_not_cached status, "#{method} with #{status} status shouldn't have been cached"
317
+ assert_page_not_cached status
231
318
  end
232
319
  end
233
320
  end
234
321
  end
235
322
 
236
323
  def test_page_caching_conditional_options
237
- get :ok, format: 'json'
324
+ draw do
325
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
326
+ end
327
+
328
+ get :ok, format: "json"
238
329
  assert_page_not_cached :ok
239
330
  end
240
331
 
241
332
  def test_page_caching_directory_set_as_pathname
242
333
  begin
243
334
  ActionController::Base.page_cache_directory = Pathname.new(FILE_STORE_PATH)
335
+
336
+ draw do
337
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
338
+ end
339
+
244
340
  get :ok
245
341
  assert_response :ok
246
342
  assert_page_cached :ok
@@ -249,17 +345,180 @@ class PageCachingTest < ActionController::TestCase
249
345
  end
250
346
  end
251
347
 
252
- private
348
+ def test_page_caching_directory_set_on_controller_instance
349
+ draw do
350
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
351
+ end
352
+
353
+ file_store_path = File.join(TEST_TMP_DIR, "instance_cache")
354
+ @controller.page_cache_directory = file_store_path
355
+
356
+ get :ok
357
+ assert_response :ok
358
+ assert_page_cached :ok, path: file_store_path
359
+ end
360
+ end
361
+
362
+ class ProcPageCachingTestController < CachingController
363
+ self.page_cache_directory = -> { File.join(TEST_TMP_DIR, request.domain) }
364
+
365
+ caches_page :ok
366
+
367
+ def ok
368
+ render html: "ok"
369
+ end
370
+
371
+ def expire_ok
372
+ expire_page action: :ok
373
+ head :ok
374
+ end
375
+ end
376
+
377
+ class ProcPageCachingTest < ActionController::TestCase
378
+ include PageCachingTestHelpers
379
+ tests ProcPageCachingTestController
380
+
381
+ def test_page_is_cached_by_domain
382
+ draw do
383
+ get "/proc_page_caching_test/ok", to: "proc_page_caching_test#ok"
384
+ get "/proc_page_caching_test/ok/expire", to: "proc_page_caching_test#expire_ok"
385
+ end
386
+
387
+ @request.env["HTTP_HOST"] = "www.foo.com"
388
+ get :ok
389
+ assert_response :ok
390
+ assert_page_cached :ok, path: TEST_TMP_DIR + "/foo.com"
391
+
392
+ get :expire_ok
393
+ assert_response :ok
394
+ assert_page_not_cached :ok, path: TEST_TMP_DIR + "/foo.com"
395
+
396
+ @request.env["HTTP_HOST"] = "www.bar.com"
397
+ get :ok
398
+ assert_response :ok
399
+ assert_page_cached :ok, path: TEST_TMP_DIR + "/bar.com"
400
+
401
+ get :expire_ok
402
+ assert_response :ok
403
+ assert_page_not_cached :ok, path: TEST_TMP_DIR + "/bar.com"
404
+ end
405
+
406
+ def test_class_level_cache_page_raise_error
407
+ assert_raises(RuntimeError, /class-level cache_page method/) do
408
+ @controller.class.cache_page "cached content", "/proc_page_caching_test/ok"
409
+ end
410
+ end
411
+ end
412
+
413
+ class SymbolPageCachingTestController < CachingController
414
+ self.page_cache_directory = :domain_cache_directory
415
+
416
+ caches_page :ok
417
+
418
+ def ok
419
+ render html: "ok"
420
+ end
421
+
422
+ def expire_ok
423
+ expire_page action: :ok
424
+ head :ok
425
+ end
253
426
 
254
- def assert_page_cached(action, message = "#{action} should have been cached")
255
- assert page_cached?(action), message
427
+ protected
428
+ def domain_cache_directory
429
+ File.join(TEST_TMP_DIR, request.domain)
256
430
  end
431
+ end
432
+
433
+ class SymbolPageCachingTest < ActionController::TestCase
434
+ include PageCachingTestHelpers
435
+ tests SymbolPageCachingTestController
257
436
 
258
- def assert_page_not_cached(action, message = "#{action} shouldn't have been cached")
259
- assert !page_cached?(action), message
437
+ def test_page_is_cached_by_domain
438
+ draw do
439
+ get "/symbol_page_caching_test/ok", to: "symbol_page_caching_test#ok"
440
+ get "/symbol_page_caching_test/ok/expire", to: "symbol_page_caching_test#expire_ok"
260
441
  end
261
442
 
262
- def page_cached?(action)
263
- File.exist? "#{FILE_STORE_PATH}/page_caching_test/#{action}.html"
443
+ @request.env["HTTP_HOST"] = "www.foo.com"
444
+ get :ok
445
+ assert_response :ok
446
+ assert_page_cached :ok, path: TEST_TMP_DIR + "/foo.com"
447
+
448
+ get :expire_ok
449
+ assert_response :ok
450
+ assert_page_not_cached :ok, path: TEST_TMP_DIR + "/foo.com"
451
+
452
+ @request.env["HTTP_HOST"] = "www.bar.com"
453
+ get :ok
454
+ assert_response :ok
455
+ assert_page_cached :ok, path: TEST_TMP_DIR + "/bar.com"
456
+
457
+ get :expire_ok
458
+ assert_response :ok
459
+ assert_page_not_cached :ok, path: TEST_TMP_DIR + "/bar.com"
460
+ end
461
+
462
+ def test_class_level_cache_page_raise_error
463
+ assert_raises(RuntimeError, /class-level cache_page method/) do
464
+ @controller.class.cache_page "cached content", "/symbol_page_caching_test/ok"
465
+ end
466
+ end
467
+ end
468
+
469
+ class CallablePageCachingTestController < CachingController
470
+ class DomainCacheDirectory
471
+ def self.call(request)
472
+ File.join(TEST_TMP_DIR, request.domain)
264
473
  end
474
+ end
475
+
476
+ self.page_cache_directory = DomainCacheDirectory
477
+
478
+ caches_page :ok
479
+
480
+ def ok
481
+ render html: "ok"
482
+ end
483
+
484
+ def expire_ok
485
+ expire_page action: :ok
486
+ head :ok
487
+ end
488
+ end
489
+
490
+ class CallablePageCachingTest < ActionController::TestCase
491
+ include PageCachingTestHelpers
492
+ tests CallablePageCachingTestController
493
+
494
+ def test_page_is_cached_by_domain
495
+ draw do
496
+ get "/callable_page_caching_test/ok", to: "callable_page_caching_test#ok"
497
+ get "/callable_page_caching_test/ok/expire", to: "callable_page_caching_test#expire_ok"
498
+ end
499
+
500
+ @request.env["HTTP_HOST"] = "www.foo.com"
501
+ get :ok
502
+ assert_response :ok
503
+ assert_page_cached :ok, path: TEST_TMP_DIR + "/foo.com"
504
+
505
+ get :expire_ok
506
+ assert_response :ok
507
+ assert_page_not_cached :ok, path: TEST_TMP_DIR + "/foo.com"
508
+
509
+ @request.env["HTTP_HOST"] = "www.bar.com"
510
+ get :ok
511
+ assert_response :ok
512
+ assert_page_cached :ok, path: TEST_TMP_DIR + "/bar.com"
513
+
514
+ get :expire_ok
515
+ assert_response :ok
516
+ assert_page_not_cached :ok, path: TEST_TMP_DIR + "/bar.com"
517
+ end
518
+
519
+ def test_class_level_cache_page_raise_error
520
+ assert_raises(RuntimeError, /class-level cache_page method/) do
521
+ @controller.class.cache_page "cached content", "/callable_page_caching_test/ok"
522
+ end
523
+ end
265
524
  end