actionpack 4.2.11.3 → 5.0.7.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +890 -384
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/base.rb +28 -38
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
- data/lib/abstract_controller/caching.rb +62 -0
- data/lib/abstract_controller/callbacks.rb +54 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/error.rb +4 -0
- data/lib/abstract_controller/helpers.rb +4 -3
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +28 -18
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/abstract_controller.rb +6 -2
- data/lib/action_controller/api/api_rendering.rb +14 -0
- data/lib/action_controller/api.rb +147 -0
- data/lib/action_controller/base.rb +14 -11
- data/lib/action_controller/caching.rb +13 -58
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +3 -10
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +106 -34
- data/lib/action_controller/metal/cookies.rb +1 -3
- data/lib/action_controller/metal/data_streaming.rb +14 -34
- data/lib/action_controller/metal/etag_with_template_digest.rb +8 -2
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +11 -11
- data/lib/action_controller/metal/head.rb +14 -8
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +44 -35
- data/lib/action_controller/metal/implicit_render.rb +61 -6
- data/lib/action_controller/metal/instrumentation.rb +5 -5
- data/lib/action_controller/metal/live.rb +71 -88
- data/lib/action_controller/metal/mime_responds.rb +27 -42
- data/lib/action_controller/metal/params_wrapper.rb +9 -9
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +83 -40
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
- data/lib/action_controller/metal/rescue.rb +3 -12
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +527 -134
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/metal.rb +88 -63
- data/lib/action_controller/railtie.rb +11 -7
- data/lib/action_controller/renderer.rb +113 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +311 -374
- data/lib/action_controller.rb +12 -9
- data/lib/action_dispatch/http/cache.rb +73 -34
- data/lib/action_dispatch/http/filter_parameters.rb +16 -12
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +45 -14
- data/lib/action_dispatch/http/mime_negotiation.rb +42 -23
- data/lib/action_dispatch/http/mime_type.rb +126 -90
- data/lib/action_dispatch/http/mime_types.rb +3 -4
- data/lib/action_dispatch/http/parameter_filter.rb +19 -9
- data/lib/action_dispatch/http/parameters.rb +70 -40
- data/lib/action_dispatch/http/request.rb +144 -89
- data/lib/action_dispatch/http/response.rb +215 -102
- data/lib/action_dispatch/http/upload.rb +6 -2
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +47 -30
- data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
- data/lib/action_dispatch/journey/nodes/node.rb +14 -4
- data/lib/action_dispatch/journey/parser.rb +2 -0
- data/lib/action_dispatch/journey/parser_extras.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +38 -42
- data/lib/action_dispatch/journey/route.rb +88 -26
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/router.rb +8 -10
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +89 -44
- data/lib/action_dispatch/middleware/callbacks.rb +10 -1
- data/lib/action_dispatch/middleware/cookies.rb +188 -134
- data/lib/action_dispatch/middleware/debug_exceptions.rb +128 -49
- data/lib/action_dispatch/middleware/debug_locks.rb +122 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
- data/lib/action_dispatch/middleware/executor.rb +19 -0
- data/lib/action_dispatch/middleware/flash.rb +66 -45
- data/lib/action_dispatch/middleware/params_parser.rb +32 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +14 -58
- data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
- data/lib/action_dispatch/middleware/request_id.rb +11 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
- data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
- data/lib/action_dispatch/middleware/ssl.rb +124 -36
- data/lib/action_dispatch/middleware/stack.rb +44 -40
- data/lib/action_dispatch/middleware/static.rb +51 -35
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
- data/lib/action_dispatch/railtie.rb +2 -2
- data/lib/action_dispatch/request/session.rb +69 -33
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing/inspector.rb +32 -43
- data/lib/action_dispatch/routing/mapper.rb +515 -348
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +5 -4
- data/lib/action_dispatch/routing/route_set.rb +148 -240
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/routing.rb +17 -13
- data/lib/action_dispatch/testing/assertion_response.rb +45 -0
- data/lib/action_dispatch/testing/assertions/response.rb +38 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +377 -149
- data/lib/action_dispatch/testing/request_encoder.rb +53 -0
- data/lib/action_dispatch/testing/test_process.rb +24 -20
- data/lib/action_dispatch/testing/test_request.rb +22 -31
- data/lib/action_dispatch/testing/test_response.rb +12 -4
- data/lib/action_dispatch.rb +4 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +32 -34
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
- /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -2,19 +2,8 @@ module ActionController
|
|
2
2
|
module Testing
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
include RackDelegation
|
6
|
-
|
7
|
-
# TODO : Rewrite tests using controller.headers= to use Rack env
|
8
|
-
def headers=(new_headers)
|
9
|
-
@_response ||= ActionDispatch::Response.new
|
10
|
-
@_response.headers.replace(new_headers)
|
11
|
-
end
|
12
|
-
|
13
5
|
# Behavior specific to functional tests
|
14
6
|
module Functional # :nodoc:
|
15
|
-
def set_response!(request)
|
16
|
-
end
|
17
|
-
|
18
7
|
def recycle!
|
19
8
|
@_url_options = nil
|
20
9
|
self.formats = nil
|
@@ -24,7 +13,7 @@ module ActionController
|
|
24
13
|
|
25
14
|
module ClassMethods
|
26
15
|
def before_filters
|
27
|
-
_process_action_callbacks.find_all{|x| x.kind == :before}.map
|
16
|
+
_process_action_callbacks.find_all{|x| x.kind == :before}.map(&:name)
|
28
17
|
end
|
29
18
|
end
|
30
19
|
end
|
@@ -4,7 +4,10 @@ module ActionController
|
|
4
4
|
#
|
5
5
|
# In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
|
6
6
|
# url options like the +host+. In order to do so, this module requires the host class
|
7
|
-
# to implement +env+
|
7
|
+
# to implement +env+ which needs to be Rack-compatible and +request+
|
8
|
+
# which is either an instance of +ActionDispatch::Request+ or an object
|
9
|
+
# that responds to the +host+, +optional_port+, +protocol+ and
|
10
|
+
# +symbolized_path_parameter+ methods.
|
8
11
|
#
|
9
12
|
# class RootUrl
|
10
13
|
# include ActionController::UrlFor
|
@@ -30,15 +33,19 @@ module ActionController
|
|
30
33
|
:_recall => request.path_parameters
|
31
34
|
}.merge!(super).freeze
|
32
35
|
|
33
|
-
if (same_origin = _routes.equal?(
|
34
|
-
(script_name =
|
35
|
-
(original_script_name =
|
36
|
+
if (same_origin = _routes.equal?(request.routes)) ||
|
37
|
+
(script_name = request.engine_script_name(_routes)) ||
|
38
|
+
(original_script_name = request.original_script_name)
|
36
39
|
|
37
40
|
options = @_url_options.dup
|
38
41
|
if original_script_name
|
39
42
|
options[:original_script_name] = original_script_name
|
40
43
|
else
|
41
|
-
|
44
|
+
if same_origin
|
45
|
+
options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup
|
46
|
+
else
|
47
|
+
options[:script_name] = script_name
|
48
|
+
end
|
42
49
|
end
|
43
50
|
options.freeze
|
44
51
|
else
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'active_support/core_ext/array/extract_options'
|
2
2
|
require 'action_dispatch/middleware/stack'
|
3
|
+
require 'action_dispatch/http/request'
|
4
|
+
require 'action_dispatch/http/response'
|
3
5
|
|
4
6
|
module ActionController
|
5
7
|
# Extend ActionDispatch middleware stack to make it aware of options
|
@@ -11,22 +13,14 @@ module ActionController
|
|
11
13
|
#
|
12
14
|
class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
|
13
15
|
class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
|
14
|
-
def initialize(klass,
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
args << options unless options.empty?
|
19
|
-
super
|
16
|
+
def initialize(klass, args, actions, strategy, block)
|
17
|
+
@actions = actions
|
18
|
+
@strategy = strategy
|
19
|
+
super(klass, args, block)
|
20
20
|
end
|
21
21
|
|
22
22
|
def valid?(action)
|
23
|
-
|
24
|
-
@only.include?(action)
|
25
|
-
elsif @except.present?
|
26
|
-
!@except.include?(action)
|
27
|
-
else
|
28
|
-
true
|
29
|
-
end
|
23
|
+
@strategy.call @actions, action
|
30
24
|
end
|
31
25
|
end
|
32
26
|
|
@@ -37,6 +31,32 @@ module ActionController
|
|
37
31
|
middleware.valid?(action) ? middleware.build(a) : a
|
38
32
|
end
|
39
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
INCLUDE = ->(list, action) { list.include? action }
|
38
|
+
EXCLUDE = ->(list, action) { !list.include? action }
|
39
|
+
NULL = ->(list, action) { true }
|
40
|
+
|
41
|
+
def build_middleware(klass, args, block)
|
42
|
+
options = args.extract_options!
|
43
|
+
only = Array(options.delete(:only)).map(&:to_s)
|
44
|
+
except = Array(options.delete(:except)).map(&:to_s)
|
45
|
+
args << options unless options.empty?
|
46
|
+
|
47
|
+
strategy = NULL
|
48
|
+
list = nil
|
49
|
+
|
50
|
+
if only.any?
|
51
|
+
strategy = INCLUDE
|
52
|
+
list = only
|
53
|
+
elsif except.any?
|
54
|
+
strategy = EXCLUDE
|
55
|
+
list = except
|
56
|
+
end
|
57
|
+
|
58
|
+
Middleware.new(get_class(klass), args, list, strategy, block)
|
59
|
+
end
|
40
60
|
end
|
41
61
|
|
42
62
|
# <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
|
@@ -98,11 +118,10 @@ module ActionController
|
|
98
118
|
class Metal < AbstractController::Base
|
99
119
|
abstract!
|
100
120
|
|
101
|
-
attr_internal_writer :env
|
102
|
-
|
103
121
|
def env
|
104
|
-
@
|
122
|
+
@_request.env
|
105
123
|
end
|
124
|
+
deprecate :env
|
106
125
|
|
107
126
|
# Returns the last part of the controller's name, underscored, without the ending
|
108
127
|
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
|
@@ -114,23 +133,23 @@ module ActionController
|
|
114
133
|
@controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
|
115
134
|
end
|
116
135
|
|
136
|
+
def self.make_response!(request)
|
137
|
+
ActionDispatch::Response.new.tap do |res|
|
138
|
+
res.request = request
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
117
142
|
# Delegates to the class' <tt>controller_name</tt>
|
118
143
|
def controller_name
|
119
144
|
self.class.controller_name
|
120
145
|
end
|
121
146
|
|
122
|
-
|
123
|
-
# Request and Response object. The default ActionController::Base
|
124
|
-
# implementation includes RackDelegation, which makes a request
|
125
|
-
# and response object available. You might wish to control the
|
126
|
-
# environment and response manually for performance reasons.
|
127
|
-
|
128
|
-
attr_internal :headers, :response, :request
|
147
|
+
attr_internal :response, :request
|
129
148
|
delegate :session, :to => "@_request"
|
149
|
+
delegate :headers, :status=, :location=, :content_type=,
|
150
|
+
:status, :location, :content_type, :to => "@_response"
|
130
151
|
|
131
152
|
def initialize
|
132
|
-
@_headers = {"Content-Type" => "text/html"}
|
133
|
-
@_status = 200
|
134
153
|
@_request = nil
|
135
154
|
@_response = nil
|
136
155
|
@_routes = nil
|
@@ -145,60 +164,49 @@ module ActionController
|
|
145
164
|
@_params = val
|
146
165
|
end
|
147
166
|
|
148
|
-
|
149
|
-
# provided to reduce the dependency on the RackDelegation module
|
150
|
-
# in Renderer and Redirector.
|
151
|
-
|
152
|
-
def content_type=(type)
|
153
|
-
headers["Content-Type"] = type.to_s
|
154
|
-
end
|
155
|
-
|
156
|
-
def content_type
|
157
|
-
headers["Content-Type"]
|
158
|
-
end
|
159
|
-
|
160
|
-
def location
|
161
|
-
headers["Location"]
|
162
|
-
end
|
163
|
-
|
164
|
-
def location=(url)
|
165
|
-
headers["Location"] = url
|
166
|
-
end
|
167
|
+
alias :response_code :status # :nodoc:
|
167
168
|
|
168
|
-
# Basic url_for that can be overridden for more robust functionality
|
169
|
+
# Basic url_for that can be overridden for more robust functionality.
|
169
170
|
def url_for(string)
|
170
171
|
string
|
171
172
|
end
|
172
173
|
|
173
|
-
def status
|
174
|
-
@_status
|
175
|
-
end
|
176
|
-
alias :response_code :status # :nodoc:
|
177
|
-
|
178
|
-
def status=(status)
|
179
|
-
@_status = Rack::Utils.status_code(status)
|
180
|
-
end
|
181
|
-
|
182
174
|
def response_body=(body)
|
183
175
|
body = [body] unless body.nil? || body.respond_to?(:each)
|
176
|
+
response.reset_body!
|
177
|
+
return unless body
|
178
|
+
response.body = body
|
184
179
|
super
|
185
180
|
end
|
186
181
|
|
187
182
|
# Tests if render or redirect has already happened.
|
188
183
|
def performed?
|
189
|
-
response_body ||
|
184
|
+
response_body || response.committed?
|
190
185
|
end
|
191
186
|
|
192
|
-
def dispatch(name, request) #:nodoc:
|
193
|
-
|
194
|
-
|
195
|
-
@_env['action_controller.instance'] = self
|
187
|
+
def dispatch(name, request, response) #:nodoc:
|
188
|
+
set_request!(request)
|
189
|
+
set_response!(response)
|
196
190
|
process(name)
|
191
|
+
request.commit_flash
|
197
192
|
to_a
|
198
193
|
end
|
199
194
|
|
195
|
+
def set_response!(response) # :nodoc:
|
196
|
+
@_response = response
|
197
|
+
end
|
198
|
+
|
199
|
+
def set_request!(request) #:nodoc:
|
200
|
+
@_request = request
|
201
|
+
@_request.controller_instance = self
|
202
|
+
end
|
203
|
+
|
200
204
|
def to_a #:nodoc:
|
201
|
-
response
|
205
|
+
response.to_a
|
206
|
+
end
|
207
|
+
|
208
|
+
def reset_session
|
209
|
+
@_request.reset_session
|
202
210
|
end
|
203
211
|
|
204
212
|
class_attribute :middleware_stack
|
@@ -226,15 +234,32 @@ module ActionController
|
|
226
234
|
req = ActionDispatch::Request.new env
|
227
235
|
action(req.path_parameters[:action]).call(env)
|
228
236
|
end
|
237
|
+
class << self; deprecate :call; end
|
229
238
|
|
230
239
|
# Returns a Rack endpoint for the given action name.
|
231
|
-
def self.action(name
|
240
|
+
def self.action(name)
|
232
241
|
if middleware_stack.any?
|
233
242
|
middleware_stack.build(name) do |env|
|
234
|
-
|
243
|
+
req = ActionDispatch::Request.new(env)
|
244
|
+
res = make_response! req
|
245
|
+
new.dispatch(name, req, res)
|
235
246
|
end
|
236
247
|
else
|
237
|
-
lambda { |env|
|
248
|
+
lambda { |env|
|
249
|
+
req = ActionDispatch::Request.new(env)
|
250
|
+
res = make_response! req
|
251
|
+
new.dispatch(name, req, res)
|
252
|
+
}
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# Direct dispatch to the controller. Instantiates the controller, then
|
257
|
+
# executes the action named +name+.
|
258
|
+
def self.dispatch(name, req, res)
|
259
|
+
if middleware_stack.any?
|
260
|
+
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
|
261
|
+
else
|
262
|
+
new.dispatch(name, req, res)
|
238
263
|
end
|
239
264
|
end
|
240
265
|
end
|
@@ -22,13 +22,17 @@ module ActionController
|
|
22
22
|
initializer "action_controller.parameters_config" do |app|
|
23
23
|
options = app.config.action_controller
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
ActiveSupport.on_load(:action_controller, run_once: true) do
|
26
|
+
ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
|
27
|
+
if app.config.action_controller[:always_permitted_parameters]
|
28
|
+
ActionController::Parameters.always_permitted_parameters =
|
29
|
+
app.config.action_controller.delete(:always_permitted_parameters)
|
30
|
+
end
|
31
|
+
ActionController::Parameters.raise_on_unfiltered_parameters =
|
32
|
+
options.delete(:raise_on_unfiltered_parameters) { false }
|
33
|
+
ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
|
34
|
+
(Rails.env.test? || Rails.env.development?) ? :log : false
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
# ActionController::Renderer allows to render arbitrary templates
|
5
|
+
# without requirement of being in controller actions.
|
6
|
+
#
|
7
|
+
# You get a concrete renderer class by invoking ActionController::Base#renderer.
|
8
|
+
# For example,
|
9
|
+
#
|
10
|
+
# ApplicationController.renderer
|
11
|
+
#
|
12
|
+
# It allows you to call method #render directly.
|
13
|
+
#
|
14
|
+
# ApplicationController.renderer.render template: '...'
|
15
|
+
#
|
16
|
+
# You can use this shortcut in a controller, instead of the previous example:
|
17
|
+
#
|
18
|
+
# ApplicationController.render template: '...'
|
19
|
+
#
|
20
|
+
# #render allows you to use the same options that you can use when rendering in a controller.
|
21
|
+
# For example,
|
22
|
+
#
|
23
|
+
# FooController.render :action, locals: { ... }, assigns: { ... }
|
24
|
+
#
|
25
|
+
# The template will be rendered in a Rack environment which is accessible through
|
26
|
+
# ActionController::Renderer#env. You can set it up in two ways:
|
27
|
+
#
|
28
|
+
# * by changing renderer defaults, like
|
29
|
+
#
|
30
|
+
# ApplicationController.renderer.defaults # => hash with default Rack environment
|
31
|
+
#
|
32
|
+
# * by initializing an instance of renderer by passing it a custom environment.
|
33
|
+
#
|
34
|
+
# ApplicationController.renderer.new(method: 'post', https: true)
|
35
|
+
#
|
36
|
+
class Renderer
|
37
|
+
attr_reader :defaults, :controller
|
38
|
+
|
39
|
+
DEFAULTS = {
|
40
|
+
http_host: 'example.org',
|
41
|
+
https: false,
|
42
|
+
method: 'get',
|
43
|
+
script_name: '',
|
44
|
+
input: ''
|
45
|
+
}.freeze
|
46
|
+
|
47
|
+
# Create a new renderer instance for a specific controller class.
|
48
|
+
def self.for(controller, env = {}, defaults = DEFAULTS.dup)
|
49
|
+
new(controller, env, defaults)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a new renderer for the same controller but with a new env.
|
53
|
+
def new(env = {})
|
54
|
+
self.class.new controller, env, defaults
|
55
|
+
end
|
56
|
+
|
57
|
+
# Create a new renderer for the same controller but with new defaults.
|
58
|
+
def with_defaults(defaults)
|
59
|
+
self.class.new controller, env, self.defaults.merge(defaults)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Accepts a custom Rack environment to render templates in.
|
63
|
+
# It will be merged with the default Rack environment defined by
|
64
|
+
# +ActionController::Renderer::DEFAULTS+.
|
65
|
+
def initialize(controller, env, defaults)
|
66
|
+
@controller = controller
|
67
|
+
@defaults = defaults
|
68
|
+
@env = normalize_keys defaults.merge(env)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Render templates with any options from ActionController::Base#render_to_string.
|
72
|
+
def render(*args)
|
73
|
+
raise 'missing controller' unless controller
|
74
|
+
|
75
|
+
request = ActionDispatch::Request.new @env
|
76
|
+
request.routes = controller._routes
|
77
|
+
|
78
|
+
instance = controller.new
|
79
|
+
instance.set_request! request
|
80
|
+
instance.set_response! controller.make_response!(request)
|
81
|
+
instance.render_to_string(*args)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
def normalize_keys(env)
|
86
|
+
new_env = {}
|
87
|
+
env.each_pair { |k,v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
|
88
|
+
new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
|
89
|
+
new_env
|
90
|
+
end
|
91
|
+
|
92
|
+
RACK_KEY_TRANSLATION = {
|
93
|
+
http_host: 'HTTP_HOST',
|
94
|
+
https: 'HTTPS',
|
95
|
+
method: 'REQUEST_METHOD',
|
96
|
+
script_name: 'SCRIPT_NAME',
|
97
|
+
input: 'rack.input'
|
98
|
+
}
|
99
|
+
|
100
|
+
IDENTITY = ->(_) { _ }
|
101
|
+
|
102
|
+
RACK_VALUE_TRANSLATION = {
|
103
|
+
https: ->(v) { v ? 'on' : 'off' },
|
104
|
+
method: ->(v) { v.upcase },
|
105
|
+
}
|
106
|
+
|
107
|
+
def rack_key_for(key); RACK_KEY_TRANSLATION[key]; end
|
108
|
+
|
109
|
+
def rack_value_for(key, value)
|
110
|
+
RACK_VALUE_TRANSLATION.fetch(key, IDENTITY).call value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module ActionController
|
2
|
+
module TemplateAssertions
|
3
|
+
def assert_template(options = {}, message = nil)
|
4
|
+
raise NoMethodError,
|
5
|
+
"assert_template has been extracted to a gem. To continue using it,
|
6
|
+
add `gem 'rails-controller-testing'` to your Gemfile."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|