rack-page_caching 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.travis.yml +10 -0
- data/Appraisals +7 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +113 -0
- data/Rakefile +9 -0
- data/gemfiles/rails_3.gemfile +8 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/lib/rack/page_caching/action_controller.rb +61 -0
- data/lib/rack/page_caching/cache.rb +74 -0
- data/lib/rack/page_caching/environment.rb +64 -0
- data/lib/rack/page_caching/mime_types.rb +24 -0
- data/lib/rack/page_caching/response.rb +50 -0
- data/lib/rack/page_caching/utils.rb +16 -0
- data/lib/rack/page_caching/version.rb +5 -0
- data/lib/rack/page_caching.rb +35 -0
- data/rack-page_caching.gemspec +30 -0
- data/test/rack/page_caching/action_controller_spec.rb +272 -0
- data/test/rack/page_caching/cache_spec.rb +187 -0
- data/test/rack/page_caching/environment_spec.rb +82 -0
- data/test/rack/page_caching/mime_types_spec.rb +24 -0
- data/test/rack/page_caching/response_spec.rb +72 -0
- data/test/rack/page_caching/utils_spec.rb +18 -0
- data/test/rack/page_caching_spec.rb +81 -0
- data/test/support/file_helper.rb +26 -0
- data/test/test_helper.rb +9 -0
- metadata +179 -0
@@ -0,0 +1,272 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
require "rack/page_caching/action_controller"
|
3
|
+
require 'test_helper'
|
4
|
+
require './test/support/file_helper'
|
5
|
+
|
6
|
+
class TestController < ActionController::Base
|
7
|
+
caches_page :cache, if: Proc.new { |c| !c.request.format.json? }
|
8
|
+
caches_page :just_head
|
9
|
+
caches_page :redirect_somewhere
|
10
|
+
caches_page :no_gzip, gzip: false
|
11
|
+
caches_page :gzip_level, gzip: :best_speed
|
12
|
+
caches_page :accept_xml
|
13
|
+
|
14
|
+
def cache
|
15
|
+
render text: 'foo bar'
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_gzip
|
19
|
+
render text: 'no gzip'
|
20
|
+
end
|
21
|
+
|
22
|
+
def just_head
|
23
|
+
head :ok
|
24
|
+
end
|
25
|
+
|
26
|
+
def redirect_somewhere
|
27
|
+
redirect_to '/just_head'
|
28
|
+
end
|
29
|
+
|
30
|
+
def custom_caching
|
31
|
+
render text: 'custom'
|
32
|
+
cache_page('Cache rules everything around me', 'wootang.html')
|
33
|
+
end
|
34
|
+
|
35
|
+
def expire_custom_caching
|
36
|
+
expire_page 'wootang.html'
|
37
|
+
head :ok
|
38
|
+
end
|
39
|
+
|
40
|
+
def custom_caching_with_starting_slash
|
41
|
+
render text: 'custom'
|
42
|
+
cache_page('Starting slash', '/slash.html')
|
43
|
+
end
|
44
|
+
|
45
|
+
def expire_starting_slash
|
46
|
+
expire_page '/slash.html'
|
47
|
+
head :ok
|
48
|
+
end
|
49
|
+
|
50
|
+
def without_extension
|
51
|
+
render text: 'without extension'
|
52
|
+
cache_page('Path without extension', 'without_extension')
|
53
|
+
end
|
54
|
+
|
55
|
+
def with_trailing_slash
|
56
|
+
render text: 'trailing slash'
|
57
|
+
cache_page('trailing slash', 'hello/world/')
|
58
|
+
end
|
59
|
+
|
60
|
+
def expire_trailing_slash
|
61
|
+
expire_page 'hello/world.html'
|
62
|
+
head :ok
|
63
|
+
end
|
64
|
+
|
65
|
+
def gzip_level
|
66
|
+
render text: 'level up'
|
67
|
+
end
|
68
|
+
|
69
|
+
def accept_xml
|
70
|
+
respond_to do |format|
|
71
|
+
format.html { render text: 'I am html' }
|
72
|
+
format.xml { render text: 'I am xml' }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe Rack::PageCaching::ActionController do
|
78
|
+
include Rack::Test::Methods
|
79
|
+
include FileHelper
|
80
|
+
|
81
|
+
def app
|
82
|
+
options = {
|
83
|
+
page_cache_directory: cache_path,
|
84
|
+
include_hostname: false
|
85
|
+
}
|
86
|
+
Rack::Builder.new {
|
87
|
+
map '/with-domain' do
|
88
|
+
use Rack::PageCaching, options.merge(include_hostname: true)
|
89
|
+
run TestController.action(:cache)
|
90
|
+
end
|
91
|
+
map '/' do
|
92
|
+
use Rack::PageCaching, options
|
93
|
+
run TestController.action(:cache)
|
94
|
+
end
|
95
|
+
[:cache, :just_head, :redirect_somewhere, :custom_caching,
|
96
|
+
:no_gzip, :gzip_level, :without_extension, :accept_xml,
|
97
|
+
:custom_caching_with_starting_slash, :expire_custom_caching,
|
98
|
+
:expire_starting_slash, :with_trailing_slash, :expire_trailing_slash
|
99
|
+
].each do |action|
|
100
|
+
map "/#{action}" do
|
101
|
+
use Rack::PageCaching, options
|
102
|
+
run TestController.action(action)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
}.to_app
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_path(*path)
|
109
|
+
@cache_path = [cache_path].concat path
|
110
|
+
end
|
111
|
+
|
112
|
+
let(:cache_file) { File.join(*@cache_path) }
|
113
|
+
|
114
|
+
it 'caches the requested page and creates gzipped file by default' do
|
115
|
+
get '/cache'
|
116
|
+
set_path 'cache.html'
|
117
|
+
assert File.exist?(cache_file), 'cache.html should exist'
|
118
|
+
File.read(cache_file).must_equal 'foo bar'
|
119
|
+
assert File.exist?(File.join(cache_path, 'cache.html.gz')),
|
120
|
+
'gzipped cache.html file should exist'
|
121
|
+
assert last_request.env['rack.page_caching.compression'] == Zlib::BEST_COMPRESSION,
|
122
|
+
'compression level must use config gzip by default'
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'saves to a file with the domain as a folder' do
|
126
|
+
get 'http://www.test.org/with-domain'
|
127
|
+
set_path 'www.test.org', 'with-domain.html'
|
128
|
+
assert File.exist?(cache_file), 'with-domain.html should exist'
|
129
|
+
File.read(cache_file).must_equal 'foo bar'
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'respects conditionals' do
|
133
|
+
get '/cache', format: :json
|
134
|
+
assert_cache_folder_is_empty
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'caches to index.html when caching on /' do
|
138
|
+
get '/'
|
139
|
+
set_path 'index.html'
|
140
|
+
assert File.exist?(cache_file),
|
141
|
+
'index.html file should exist'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'caches head request' do
|
145
|
+
head '/just_head'
|
146
|
+
set_path 'just_head.html'
|
147
|
+
assert File.exist?(cache_file), 'head response should have been cached'
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'will not cache when http status is not 200' do
|
151
|
+
get '/redirect_somewhere'
|
152
|
+
assert_cache_folder_is_empty
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'caches custom text to a custom path' do
|
156
|
+
get '/custom_caching'
|
157
|
+
set_path 'wootang.html'
|
158
|
+
assert File.exist?(cache_file), 'wootang.html should exist'
|
159
|
+
File.read(cache_file).must_equal 'Cache rules everything around me'
|
160
|
+
end
|
161
|
+
|
162
|
+
def assert_file_deleted_after_expiry(path, expire_path, file)
|
163
|
+
get path
|
164
|
+
set_path file
|
165
|
+
assert File.exist?(cache_file), "#{file} should exist"
|
166
|
+
assert File.exist?(cache_file + '.gz'), "#{file}.gz should exist"
|
167
|
+
|
168
|
+
get expire_path
|
169
|
+
refute File.exist?(cache_file), "#{file} should be deleted"
|
170
|
+
refute File.exist?(cache_file + '.gz'), "#{file}.gz should be deleted"
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'expires page at custom path' do
|
174
|
+
assert_file_deleted_after_expiry '/custom_caching', '/expire_custom_caching',
|
175
|
+
'wootang.html'
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'caches custom text whose path starts with a slash' do
|
179
|
+
get '/custom_caching_with_starting_slash'
|
180
|
+
set_path 'slash.html'
|
181
|
+
assert File.exist?(cache_file), '/slash.html should exist'
|
182
|
+
File.read(cache_file).must_equal 'Starting slash'
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'expires page with path that starts with slash' do
|
186
|
+
assert_file_deleted_after_expiry '/custom_caching_with_starting_slash',
|
187
|
+
'/expire_starting_slash', 'slash.html'
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'caches path that does not have extensions' do
|
191
|
+
get '/without_extension'
|
192
|
+
set_path 'without_extension.html'
|
193
|
+
assert File.exist?(cache_file), 'without_extension.html should exist'
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'caches path with trailing slash' do
|
197
|
+
get '/with_trailing_slash'
|
198
|
+
set_path 'hello/world.html'
|
199
|
+
assert File.exist?(cache_file), 'hello/world.html should exist'
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'expires path with trailing slash' do
|
203
|
+
assert_file_deleted_after_expiry '/with_trailing_slash',
|
204
|
+
'/expire_trailing_slash', 'hello/world.html'
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'does not create a gzip file when gzip argument is false' do
|
208
|
+
get '/no_gzip'
|
209
|
+
set_path 'no_gzip.html'
|
210
|
+
assert File.exist?(cache_file), 'no_gzip.html should exist'
|
211
|
+
refute File.exist?(File.join(cache_path, 'no_gzip.html.gz')),
|
212
|
+
'gzipped no_gzip.html file should not exist'
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'allows overriding of gzip level' do
|
216
|
+
get '/gzip_level'
|
217
|
+
assert last_request.env['rack.page_caching.compression'] == Zlib::BEST_SPEED,
|
218
|
+
'compression level must be set to the requested level'
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'caches according to requested format' do
|
222
|
+
get '/accept_xml', { format: :xml }
|
223
|
+
set_path 'accept_xml.xml'
|
224
|
+
assert File.exist?(cache_file), 'accept_xml.xml should exist'
|
225
|
+
end
|
226
|
+
|
227
|
+
describe 'notifications' do
|
228
|
+
class Counter
|
229
|
+
def self.incr
|
230
|
+
@counter += 1
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.reset
|
234
|
+
@counter = 0
|
235
|
+
end
|
236
|
+
|
237
|
+
def self.check
|
238
|
+
@counter
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
let(:subscribe) do
|
243
|
+
Counter.reset
|
244
|
+
Counter.check.must_equal 0
|
245
|
+
@subscriber = ActiveSupport::Notifications.subscribe(@event) do |name, start, finish, id, payload|
|
246
|
+
payload[:path].must_equal cache_file
|
247
|
+
Counter.incr
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
after do
|
252
|
+
ActiveSupport::Notifications.unsubscribe @subscriber
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'notifies subscribers after writing' do
|
256
|
+
@event = 'write_page.action_controller'
|
257
|
+
set_path 'cache.html'
|
258
|
+
subscribe
|
259
|
+
get '/cache'
|
260
|
+
Counter.check.must_equal 1
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'notifies subscribers after deleting' do
|
264
|
+
@event = 'expire_page.action_controller'
|
265
|
+
set_path 'wootang.html'
|
266
|
+
subscribe
|
267
|
+
get '/custom_caching'
|
268
|
+
get '/expire_custom_caching'
|
269
|
+
Counter.check.must_equal 1
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require './test/support/file_helper'
|
3
|
+
|
4
|
+
describe Rack::PageCaching::Cache do
|
5
|
+
let(:options) { {} }
|
6
|
+
|
7
|
+
let(:config) { Rack::PageCaching::Environment.new(options) }
|
8
|
+
|
9
|
+
let(:content_type) { 'text/html' }
|
10
|
+
|
11
|
+
let(:path) { '/hotels/singapore' }
|
12
|
+
|
13
|
+
let(:env) do
|
14
|
+
{
|
15
|
+
'PATH_INFO' => path,
|
16
|
+
'REQUEST_METHOD' => 'GET',
|
17
|
+
'HTTP_HOST' => 'www.example.org',
|
18
|
+
'rack.page_caching.perform_caching' => true
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:response) do
|
23
|
+
Rack::PageCaching::Response.new(
|
24
|
+
[
|
25
|
+
200,
|
26
|
+
{ 'Content-Type' => content_type },
|
27
|
+
['Foo Bar']
|
28
|
+
],
|
29
|
+
env
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:cache) { Rack::PageCaching::Cache.new(response) }
|
34
|
+
|
35
|
+
before { Rack::PageCaching.environment = config }
|
36
|
+
|
37
|
+
describe '#gzip_level' do
|
38
|
+
subject { cache.gzip_level }
|
39
|
+
|
40
|
+
describe 'from config' do
|
41
|
+
let(:options) { { page_cache_compression: :best_compression } }
|
42
|
+
|
43
|
+
it 'returns the gzip_level from config if gzip level is not specified in response' do
|
44
|
+
subject.must_equal Zlib::BEST_COMPRESSION
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'from response' do
|
49
|
+
before do
|
50
|
+
env.merge! 'rack.page_caching.compression' => Rack::PageCaching::Utils.gzip_level(:best_speed)
|
51
|
+
options.merge! page_cache_compression: :best_compression
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns the gzip_level from response' do
|
55
|
+
subject.must_equal Zlib::BEST_SPEED
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#page_cache_path' do
|
61
|
+
subject { cache.page_cache_path }
|
62
|
+
|
63
|
+
it 'returns the correct page_cache_path' do
|
64
|
+
subject.must_equal '/hotels/singapore.html'
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'uses correct extension' do
|
68
|
+
let(:content_type) { 'application/xml' }
|
69
|
+
it 'returns the correct extension for the cache path' do
|
70
|
+
subject.must_equal '/hotels/singapore.xml'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'uses index.html' do
|
75
|
+
let(:path) { '/' }
|
76
|
+
|
77
|
+
it 'appends index.html when path is only a slash' do
|
78
|
+
subject.must_equal '/index.html'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'uses hostname' do
|
83
|
+
before { options.merge!(include_hostname: true) }
|
84
|
+
|
85
|
+
it 'includes hostname in cache path' do
|
86
|
+
subject.must_equal '/www.example.org/hotels/singapore.html'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'skips extension' do
|
91
|
+
let(:path) { '/index.json' }
|
92
|
+
let(:content_type) { 'application/json' }
|
93
|
+
|
94
|
+
it 'does not add extension again if path already has extension' do
|
95
|
+
subject.must_equal '/index.json'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'escapes path' do
|
100
|
+
let(:path) { '/path%20with%20spaces' }
|
101
|
+
|
102
|
+
it 'escapes the path' do
|
103
|
+
subject.must_equal '/path with spaces.html'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'saving to disk' do
|
109
|
+
include FileHelper
|
110
|
+
|
111
|
+
let(:options) { { page_cache_directory: cache_path } }
|
112
|
+
let(:cache_file) { File.join(cache_path, 'hotels', 'singapore.html') }
|
113
|
+
let(:cache_content) { File.read(cache_file) }
|
114
|
+
|
115
|
+
describe '#store' do
|
116
|
+
it 'stores the response to disk' do
|
117
|
+
cache.store
|
118
|
+
cache_content.must_equal 'Foo Bar'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'overwrites the file for the same call' do
|
122
|
+
cache.store
|
123
|
+
cache.store
|
124
|
+
cache_content.must_equal 'Foo Bar'
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'compression' do
|
128
|
+
let(:options) do
|
129
|
+
{
|
130
|
+
page_cache_compression: :best_speed,
|
131
|
+
page_cache_directory: cache_path,
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
let(:zipped_path) { File.join(cache_path, 'hotels', 'singapore.html.gz') }
|
136
|
+
|
137
|
+
it 'creates a compressed file' do
|
138
|
+
cache.store
|
139
|
+
File.exist?(zipped_path).must_equal true
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'zips the content' do
|
143
|
+
cache.store
|
144
|
+
Zlib::GzipReader.open(zipped_path) do |gz|
|
145
|
+
gz.read.must_equal 'Foo Bar'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '.store' do
|
152
|
+
it 'stores the response to disk' do
|
153
|
+
Rack::PageCaching::Cache.store(response)
|
154
|
+
cache_content.must_equal 'Foo Bar'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe '.delete' do
|
159
|
+
it 'stores the file to disk' do
|
160
|
+
Rack::PageCaching::Cache.store(response)
|
161
|
+
File.exist?(cache_file).must_equal true
|
162
|
+
Rack::PageCaching::Cache.delete(File.join('hotels', 'singapore.html'))
|
163
|
+
refute File.exist?(cache_file)
|
164
|
+
end
|
165
|
+
|
166
|
+
describe 'globs' do
|
167
|
+
let(:options) do
|
168
|
+
{
|
169
|
+
page_cache_directory: cache_path,
|
170
|
+
include_hostname: true
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
let(:cache_file) do
|
175
|
+
File.join(cache_path, 'www.example.org', 'hotels', 'singapore.html')
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'accepts globs in path' do
|
179
|
+
Rack::PageCaching::Cache.store(response)
|
180
|
+
File.exist?(cache_file).must_equal true
|
181
|
+
Rack::PageCaching::Cache.delete(File.join('**', 'hotels', 'singapore.html'))
|
182
|
+
refute File.exist?(cache_file)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
describe Rack::PageCaching::Environment do
|
5
|
+
let(:env) { Rack::PageCaching::Environment.new(options) }
|
6
|
+
|
7
|
+
describe 'defaults' do
|
8
|
+
let(:options) { {} }
|
9
|
+
|
10
|
+
it 'is not enabled when a page_cache_directory is not set' do
|
11
|
+
refute env.enabled?
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'defaults page_cache_compression to false' do
|
15
|
+
refute env.page_cache_compression
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'defaults include_hostname to false' do
|
19
|
+
refute env.include_hostname?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'set options' do
|
24
|
+
let(:options) {
|
25
|
+
{
|
26
|
+
include_hostname: true,
|
27
|
+
page_cache_compression: :best_compression,
|
28
|
+
page_cache_directory: '/var/tmp'
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
it 'includes hostname' do
|
33
|
+
env.include_hostname?.must_equal true
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'is enabled' do
|
37
|
+
env.enabled?.must_equal true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns the correct zlib compression constant' do
|
41
|
+
env.page_cache_compression.must_equal Zlib::BEST_COMPRESSION
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'sets the correct page cache directory' do
|
45
|
+
env.page_cache_directory.must_equal '/var/tmp'
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'page_cache_directory' do
|
49
|
+
before { options.merge! page_cache_directory: Pathname.new('/var/tmp') }
|
50
|
+
|
51
|
+
it 'accepts a Pathname as page cache directory' do
|
52
|
+
env.page_cache_directory.must_equal '/var/tmp'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'in Rails' do
|
58
|
+
before do
|
59
|
+
controller = Object.new
|
60
|
+
controller.define_singleton_method(:perform_caching) { true }
|
61
|
+
config = Object.new
|
62
|
+
config.define_singleton_method(:action_controller) { controller }
|
63
|
+
application = Object.new
|
64
|
+
application.define_singleton_method(:config) { config }
|
65
|
+
root = Object.new
|
66
|
+
root.define_singleton_method(:join) do |folder|
|
67
|
+
Pathname.new('/var/www/app').join(folder)
|
68
|
+
end
|
69
|
+
Rails = Class.new
|
70
|
+
Rails.define_singleton_method(:application) { application }
|
71
|
+
Rails.define_singleton_method(:root) { root }
|
72
|
+
end
|
73
|
+
|
74
|
+
let(:options) { {} }
|
75
|
+
|
76
|
+
it 'sets the page cache path to public folder relative to rails root' do
|
77
|
+
env.page_cache_directory.must_equal '/var/www/app/public'
|
78
|
+
end
|
79
|
+
|
80
|
+
after { Object.send(:remove_const, :Rails) }
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Rack::PageCaching::MimeTypes do
|
4
|
+
let(:mime_types) { Rack::PageCaching::MimeTypes }
|
5
|
+
|
6
|
+
describe '.extension_for' do
|
7
|
+
{
|
8
|
+
'text/html' => '.html',
|
9
|
+
'application/json' => '.json',
|
10
|
+
'text/css' => '.css'
|
11
|
+
}.each do |content_type, extension|
|
12
|
+
it "returns #{extension} for content type #{content_type}" do
|
13
|
+
mime_types.extension_for(content_type).must_equal extension
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.register' do
|
19
|
+
it 'allows registration of custom content_type' do
|
20
|
+
mime_types.register 'text/ing', '.ing'
|
21
|
+
mime_types.extension_for('text/ing').must_equal '.ing'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Rack::PageCaching::Response do
|
4
|
+
let(:rack_response) do
|
5
|
+
[
|
6
|
+
200,
|
7
|
+
{ 'Content-Type' => 'text/html; charset=utf-8' },
|
8
|
+
['Foo Bar']
|
9
|
+
]
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:env) do
|
13
|
+
{
|
14
|
+
'PATH_INFO' => '/hotels/singapore',
|
15
|
+
'REQUEST_METHOD' => 'GET',
|
16
|
+
'HTTP_HOST' => 'www.example.org',
|
17
|
+
'rack.page_caching.perform_caching' => true
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:response) { Rack::PageCaching::Response.new(rack_response, env) }
|
22
|
+
|
23
|
+
it 'is cacheable for successful html responses' do
|
24
|
+
response.cacheable?.must_equal true
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns the path' do
|
28
|
+
response.path.must_equal '/hotels/singapore'
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns the body' do
|
32
|
+
response.body.must_equal ['Foo Bar']
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns the content type' do
|
36
|
+
response.content_type.must_equal 'text/html'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns the host' do
|
40
|
+
response.host.must_equal 'www.example.org'
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'no caching' do
|
44
|
+
describe 'no directive provided' do
|
45
|
+
before { env.delete 'rack.page_caching.perform_caching' }
|
46
|
+
it 'is not cacheable by default' do
|
47
|
+
response.cacheable?.must_equal false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'directive is false' do
|
52
|
+
before { env.merge! 'rack.page_caching.perform_caching' => false }
|
53
|
+
it 'is not cacheable if perform_caching env is set to false' do
|
54
|
+
response.cacheable?.must_equal false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'response not cacheable' do
|
59
|
+
before { env.merge! 'REQUEST_METHOD' => 'POST' }
|
60
|
+
it 'does not cache post requests' do
|
61
|
+
response.cacheable?.must_equal false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'non-200 response' do
|
66
|
+
before { rack_response[0] = 404 }
|
67
|
+
it 'does not cache resposes where status is not 200' do
|
68
|
+
response.cacheable?.must_equal false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Rack::PageCaching::Utils do
|
4
|
+
let(:utils) { Rack::PageCaching::Utils }
|
5
|
+
describe '.gzip_level' do
|
6
|
+
it 'accepts a number and returns it' do
|
7
|
+
utils.gzip_level(1).must_equal 1
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'accepts a symbol and returns the corresponding zlib constant' do
|
11
|
+
utils.gzip_level(:best_speed).must_equal Zlib::BEST_SPEED
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns false for unrecognized input' do
|
15
|
+
utils.gzip_level('best_speed').must_equal false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|