actionpack-page_caching 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.

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