2016-08-06 12:54:50 -04:00
|
|
|
require "abstract_unit"
|
2015-04-06 09:03:13 -04:00
|
|
|
require "active_support/log_subscriber/test_helper"
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
class RespondToController < ActionController::Base
|
|
|
|
layout :set_layout
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
before_action {
|
|
|
|
case params[:v]
|
|
|
|
when String then request.variant = params[:v].to_sym
|
|
|
|
when Array then request.variant = params[:v].map(&:to_sym)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
2013-08-17 11:30:00 -04:00
|
|
|
def html_xml_or_rss
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.xml { render body: "XML" }
|
|
|
|
type.rss { render body: "RSS" }
|
|
|
|
type.all { render body: "Nothing" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def js_or_html
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.js { render body: "JS" }
|
|
|
|
type.all { render body: "Nothing" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def json_or_yaml
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.json { render body: "JSON" }
|
|
|
|
type.yaml { render body: "YAML" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def html_or_xml
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.xml { render body: "XML" }
|
|
|
|
type.all { render body: "Nothing" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def json_xml_or_html
|
|
|
|
respond_to do |type|
|
2016-08-06 12:54:50 -04:00
|
|
|
type.json { render body: "JSON" }
|
2016-08-06 13:35:13 -04:00
|
|
|
type.xml { render xml: "XML" }
|
2016-08-06 12:54:50 -04:00
|
|
|
type.html { render body: "HTML" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def forced_xml
|
|
|
|
request.format = :xml
|
|
|
|
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.xml { render body: "XML" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def just_xml
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.xml { render body: "XML" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def using_defaults
|
|
|
|
respond_to do |type|
|
|
|
|
type.html
|
|
|
|
type.xml
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-12-30 13:59:23 -05:00
|
|
|
def missing_templates
|
|
|
|
respond_to do |type|
|
|
|
|
# This test requires a block that is empty
|
2016-08-16 03:30:11 -04:00
|
|
|
type.json {}
|
2015-12-30 13:59:23 -05:00
|
|
|
type.xml
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-17 11:30:00 -04:00
|
|
|
def using_defaults_with_type_list
|
|
|
|
respond_to(:html, :xml)
|
|
|
|
end
|
|
|
|
|
|
|
|
def using_defaults_with_all
|
|
|
|
respond_to do |type|
|
|
|
|
type.html
|
2015-10-05 01:14:04 -04:00
|
|
|
type.all { render body: "ALL" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def made_for_content_type
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.rss { render body: "RSS" }
|
|
|
|
type.atom { render body: "ATOM" }
|
|
|
|
type.all { render body: "Nothing" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def custom_type_handling
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.custom("application/crazy-xml") { render body: "Crazy XML" }
|
|
|
|
type.all { render body: "Nothing" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def custom_constant_handling
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.mobile { render body: "Mobile" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def custom_constant_handling_without_block
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
2013-08-17 11:30:00 -04:00
|
|
|
type.mobile
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def handle_any
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.any(:js, :xml) { render body: "Either JS or XML" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def handle_any_any
|
|
|
|
respond_to do |type|
|
2016-08-06 12:54:50 -04:00
|
|
|
type.html { render body: "HTML" }
|
|
|
|
type.any { render body: "Whatever you ask for, I got it" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def all_types_with_layout
|
|
|
|
respond_to do |type|
|
|
|
|
type.html
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-07-02 17:48:04 -04:00
|
|
|
def json_with_callback
|
|
|
|
respond_to do |type|
|
2016-08-06 13:35:13 -04:00
|
|
|
type.json { render json: "JS", callback: "alert" }
|
2014-07-02 17:48:04 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-17 11:30:00 -04:00
|
|
|
def iphone_with_html_response_type
|
|
|
|
request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone"
|
|
|
|
|
|
|
|
respond_to do |type|
|
|
|
|
type.html { @type = "Firefox" }
|
|
|
|
type.iphone { @type = "iPhone" }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def iphone_with_html_response_type_without_layout
|
|
|
|
request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
|
|
|
|
|
|
|
|
respond_to do |type|
|
2016-08-06 13:35:13 -04:00
|
|
|
type.html { @type = "Firefox"; render action: "iphone_with_html_response_type" }
|
|
|
|
type.iphone { @type = "iPhone" ; render action: "iphone_with_html_response_type" }
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
def variant_with_implicit_template_rendering
|
|
|
|
# This has exactly one variant template defined in the file system (+mobile.html.erb),
|
|
|
|
# which raises the regular MissingTemplate error for other variants.
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_without_implicit_template_rendering
|
|
|
|
# This differs from the above in that it does not have any templates defined in the file
|
|
|
|
# system, which triggers the ImplicitRender (204 No Content) behavior.
|
2013-12-03 05:17:01 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def variant_with_format_and_custom_render
|
|
|
|
request.variant = :mobile
|
|
|
|
|
|
|
|
respond_to do |type|
|
2015-07-17 21:48:00 -04:00
|
|
|
type.html { render body: "mobile" }
|
2013-12-03 05:17:01 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def multiple_variants_for_format
|
|
|
|
respond_to do |type|
|
|
|
|
type.html do |html|
|
2015-07-17 21:48:00 -04:00
|
|
|
html.tablet { render body: "tablet" }
|
|
|
|
html.phone { render body: "phone" }
|
2013-12-03 05:17:01 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-12-07 18:00:35 -05:00
|
|
|
def variant_plus_none_for_format
|
|
|
|
respond_to do |format|
|
|
|
|
format.html do |variant|
|
2015-07-17 21:48:00 -04:00
|
|
|
variant.phone { render body: "phone" }
|
2013-12-07 19:32:38 -05:00
|
|
|
variant.none
|
2013-12-07 18:00:35 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-12-09 18:36:18 -05:00
|
|
|
def variant_inline_syntax
|
|
|
|
respond_to do |format|
|
2015-07-17 21:48:00 -04:00
|
|
|
format.js { render body: "js" }
|
|
|
|
format.html.none { render body: "none" }
|
|
|
|
format.html.phone { render body: "phone" }
|
2013-12-09 18:36:18 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_inline_syntax_without_block
|
|
|
|
respond_to do |format|
|
|
|
|
format.js
|
|
|
|
format.html.none
|
|
|
|
format.html.phone
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-12-24 10:53:10 -05:00
|
|
|
def variant_any
|
|
|
|
respond_to do |format|
|
|
|
|
format.html do |variant|
|
2016-08-16 03:30:11 -04:00
|
|
|
variant.any(:tablet, :phablet) { render body: "any" }
|
2015-07-17 21:48:00 -04:00
|
|
|
variant.phone { render body: "phone" }
|
2013-12-24 10:53:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_any_any
|
|
|
|
respond_to do |format|
|
|
|
|
format.html do |variant|
|
2015-07-17 21:48:00 -04:00
|
|
|
variant.any { render body: "any" }
|
|
|
|
variant.phone { render body: "phone" }
|
2013-12-24 10:53:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_inline_any
|
|
|
|
respond_to do |format|
|
2016-08-16 03:30:11 -04:00
|
|
|
format.html.any(:tablet, :phablet) { render body: "any" }
|
2015-07-17 21:48:00 -04:00
|
|
|
format.html.phone { render body: "phone" }
|
2013-12-24 10:53:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_inline_any_any
|
|
|
|
respond_to do |format|
|
2015-07-17 21:48:00 -04:00
|
|
|
format.html.phone { render body: "phone" }
|
|
|
|
format.html.any { render body: "any" }
|
2013-12-24 10:53:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_any_implicit_render
|
|
|
|
respond_to do |format|
|
|
|
|
format.html.phone
|
|
|
|
format.html.any(:tablet, :phablet)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def variant_any_with_none
|
|
|
|
respond_to do |format|
|
2016-08-16 03:30:11 -04:00
|
|
|
format.html.any(:none, :phone) { render body: "none or phone" }
|
2013-12-24 10:53:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def format_any_variant_any
|
|
|
|
respond_to do |format|
|
2015-07-17 21:48:00 -04:00
|
|
|
format.html { render body: "HTML" }
|
2013-12-24 10:53:10 -05:00
|
|
|
format.any(:js, :xml) do |variant|
|
2016-08-16 03:30:11 -04:00
|
|
|
variant.phone { render body: "phone" }
|
|
|
|
variant.any(:tablet, :phablet) { render body: "tablet" }
|
2013-12-24 10:53:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-17 11:30:00 -04:00
|
|
|
protected
|
|
|
|
def set_layout
|
|
|
|
case action_name
|
2016-08-06 14:20:22 -04:00
|
|
|
when "all_types_with_layout", "iphone_with_html_response_type"
|
|
|
|
"respond_to/layouts/standard"
|
|
|
|
when "iphone_with_html_response_type_without_layout"
|
|
|
|
"respond_to/layouts/missing"
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class RespondToControllerTest < ActionController::TestCase
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
NO_CONTENT_WARNING = "No template found for RespondToController#variant_without_implicit_template_rendering, rendering head :no_content"
|
|
|
|
|
2013-08-17 11:30:00 -04:00
|
|
|
def setup
|
|
|
|
super
|
|
|
|
@request.host = "www.example.com"
|
|
|
|
Mime::Type.register_alias("text/html", :iphone)
|
|
|
|
Mime::Type.register("text/x-mobile", :mobile)
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
super
|
|
|
|
Mime::Type.unregister(:iphone)
|
|
|
|
Mime::Type.unregister(:mobile)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_html
|
|
|
|
@request.accept = "text/html"
|
|
|
|
get :js_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
get :html_or_xml
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
|
|
|
get :just_xml
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_all
|
|
|
|
@request.accept = "*/*"
|
|
|
|
get :js_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body # js is not part of all
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
get :html_or_xml
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
get :just_xml
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "XML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_xml
|
|
|
|
@request.accept = "application/xml"
|
|
|
|
get :html_xml_or_rss
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "XML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_js_or_html
|
|
|
|
@request.accept = "text/javascript, text/html"
|
2015-02-01 08:07:42 -05:00
|
|
|
get :js_or_html, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "JS", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "text/javascript, text/html"
|
2015-02-01 08:07:42 -05:00
|
|
|
get :html_or_xml, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "text/javascript, text/html"
|
|
|
|
|
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
2015-02-01 08:07:42 -05:00
|
|
|
get :just_xml, xhr: true
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_json_or_yaml_with_leading_star_star
|
|
|
|
@request.accept = "*/*, application/json"
|
|
|
|
get :json_xml_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "*/* , application/json"
|
|
|
|
get :json_xml_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_json_or_yaml
|
2015-02-01 08:07:42 -05:00
|
|
|
get :json_or_yaml, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "JSON", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
get :json_or_yaml, format: "json"
|
|
|
|
assert_equal "JSON", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
get :json_or_yaml, format: "yaml"
|
|
|
|
assert_equal "YAML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
{ "YAML" => %w(text/yaml),
|
|
|
|
"JSON" => %w(application/json text/x-json)
|
2013-08-17 11:30:00 -04:00
|
|
|
}.each do |body, content_types|
|
|
|
|
content_types.each do |content_type|
|
|
|
|
@request.accept = content_type
|
|
|
|
get :json_or_yaml
|
|
|
|
assert_equal body, @response.body
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_js_or_anything
|
|
|
|
@request.accept = "text/javascript, */*"
|
2015-02-01 08:07:42 -05:00
|
|
|
get :js_or_html, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "JS", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
2015-02-01 08:07:42 -05:00
|
|
|
get :html_or_xml, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
2015-02-01 08:07:42 -05:00
|
|
|
get :just_xml, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "XML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_using_defaults
|
|
|
|
@request.accept = "*/*"
|
|
|
|
get :using_defaults
|
|
|
|
assert_equal "text/html", @response.content_type
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Hello world!", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "application/xml"
|
|
|
|
get :using_defaults
|
|
|
|
assert_equal "application/xml", @response.content_type
|
|
|
|
assert_equal "<p>Hello world!</p>\n", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_using_defaults_with_all
|
|
|
|
@request.accept = "*/*"
|
|
|
|
get :using_defaults_with_all
|
|
|
|
assert_equal "HTML!", @response.body.strip
|
|
|
|
|
|
|
|
@request.accept = "text/html"
|
|
|
|
get :using_defaults_with_all
|
|
|
|
assert_equal "HTML!", @response.body.strip
|
|
|
|
|
|
|
|
@request.accept = "application/json"
|
|
|
|
get :using_defaults_with_all
|
|
|
|
assert_equal "ALL", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_using_defaults_with_type_list
|
|
|
|
@request.accept = "*/*"
|
|
|
|
get :using_defaults_with_type_list
|
|
|
|
assert_equal "text/html", @response.content_type
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Hello world!", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "application/xml"
|
|
|
|
get :using_defaults_with_type_list
|
|
|
|
assert_equal "application/xml", @response.content_type
|
|
|
|
assert_equal "<p>Hello world!</p>\n", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_with_atom_content_type
|
|
|
|
@request.accept = ""
|
|
|
|
@request.env["CONTENT_TYPE"] = "application/atom+xml"
|
2015-02-01 08:07:42 -05:00
|
|
|
get :made_for_content_type, xhr: true
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "ATOM", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_with_rss_content_type
|
|
|
|
@request.accept = ""
|
|
|
|
@request.env["CONTENT_TYPE"] = "application/rss+xml"
|
2015-02-01 08:07:42 -05:00
|
|
|
get :made_for_content_type, xhr: true
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "RSS", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_synonyms
|
|
|
|
@request.accept = "application/javascript"
|
|
|
|
get :js_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "JS", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "application/x-xml"
|
|
|
|
get :html_xml_or_rss
|
|
|
|
assert_equal "XML", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_custom_types
|
|
|
|
@request.accept = "application/crazy-xml"
|
|
|
|
get :custom_type_handling
|
|
|
|
assert_equal "application/crazy-xml", @response.content_type
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Crazy XML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "text/html"
|
|
|
|
get :custom_type_handling
|
|
|
|
assert_equal "text/html", @response.content_type
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_xhtml_alias
|
|
|
|
@request.accept = "application/xhtml+xml,application/xml"
|
|
|
|
get :html_or_xml
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_firefox_simulation
|
|
|
|
@request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
|
|
|
|
get :html_or_xml
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_handle_any
|
|
|
|
@request.accept = "*/*"
|
|
|
|
get :handle_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "text/javascript"
|
|
|
|
get :handle_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Either JS or XML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "text/xml"
|
|
|
|
get :handle_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Either JS or XML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_handle_any_any
|
|
|
|
@request.accept = "*/*"
|
|
|
|
get :handle_any_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_handle_any_any_parameter_format
|
2016-08-06 12:54:50 -04:00
|
|
|
get :handle_any_any, format: "html"
|
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_handle_any_any_explicit_html
|
|
|
|
@request.accept = "text/html"
|
|
|
|
get :handle_any_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_handle_any_any_javascript
|
|
|
|
@request.accept = "text/javascript"
|
|
|
|
get :handle_any_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Whatever you ask for, I got it", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_handle_any_any_xml
|
|
|
|
@request.accept = "text/xml"
|
|
|
|
get :handle_any_any
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "Whatever you ask for, I got it", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
2014-04-14 15:59:47 -04:00
|
|
|
|
|
|
|
def test_handle_any_any_unkown_format
|
2016-08-06 12:54:50 -04:00
|
|
|
get :handle_any_any, format: "php"
|
|
|
|
assert_equal "Whatever you ask for, I got it", @response.body
|
2014-04-14 15:59:47 -04:00
|
|
|
end
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
def test_browser_check_with_any_any
|
|
|
|
@request.accept = "application/json, application/xml"
|
|
|
|
get :json_xml_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "JSON", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
|
|
|
@request.accept = "application/json, application/xml, */*"
|
|
|
|
get :json_xml_or_html
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "HTML", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_html_type_with_layout
|
|
|
|
@request.accept = "text/html"
|
|
|
|
get :all_types_with_layout
|
|
|
|
assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
|
|
|
|
end
|
|
|
|
|
2014-07-02 17:48:04 -04:00
|
|
|
def test_json_with_callback_sets_javascript_content_type
|
2016-08-06 12:54:50 -04:00
|
|
|
@request.accept = "application/json"
|
2014-07-02 17:48:04 -04:00
|
|
|
get :json_with_callback
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "/**/alert(JS)", @response.body
|
|
|
|
assert_equal "text/javascript", @response.content_type
|
2014-07-02 17:48:04 -04:00
|
|
|
end
|
|
|
|
|
2013-08-17 11:30:00 -04:00
|
|
|
def test_xhr
|
2015-02-01 08:07:42 -05:00
|
|
|
get :js_or_html, xhr: true
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_equal "JS", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_custom_constant
|
2015-01-04 04:35:06 -05:00
|
|
|
get :custom_constant_handling, format: "mobile"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "text/x-mobile", @response.content_type
|
|
|
|
assert_equal "Mobile", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_custom_constant_handling_without_block
|
2015-01-04 04:35:06 -05:00
|
|
|
get :custom_constant_handling_without_block, format: "mobile"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "text/x-mobile", @response.content_type
|
|
|
|
assert_equal "Mobile", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_forced_format
|
|
|
|
get :html_xml_or_rss
|
|
|
|
assert_equal "HTML", @response.body
|
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get :html_xml_or_rss, format: "html"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "HTML", @response.body
|
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get :html_xml_or_rss, format: "xml"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "XML", @response.body
|
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get :html_xml_or_rss, format: "rss"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "RSS", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_internally_forced_format
|
|
|
|
get :forced_xml
|
|
|
|
assert_equal "XML", @response.body
|
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get :forced_xml, format: "html"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "XML", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_extension_synonyms
|
2015-01-04 04:35:06 -05:00
|
|
|
get :html_xml_or_rss, format: "xhtml"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "HTML", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_render_action_for_html
|
|
|
|
@controller.instance_eval do
|
|
|
|
def render(*args)
|
|
|
|
@action = args.first[:action] unless args.empty?
|
|
|
|
@action ||= action_name
|
|
|
|
|
|
|
|
response.body = "#{@action} - #{formats}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
get :using_defaults
|
2014-10-29 21:18:48 -04:00
|
|
|
assert_equal "using_defaults - #{[:html]}", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get :using_defaults, format: "xml"
|
2014-10-29 21:18:48 -04:00
|
|
|
assert_equal "using_defaults - #{[:xml]}", @response.body
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_format_with_custom_response_type
|
|
|
|
get :iphone_with_html_response_type
|
|
|
|
assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body
|
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get :iphone_with_html_response_type, format: "iphone"
|
2013-08-17 11:30:00 -04:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_format_with_custom_response_type_and_request_headers
|
|
|
|
@request.accept = "text/iphone"
|
|
|
|
get :iphone_with_html_response_type
|
|
|
|
assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
|
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_invalid_format
|
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
2015-01-04 04:35:06 -05:00
|
|
|
get :using_defaults, format: "invalidformat"
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|
|
|
|
end
|
2013-12-03 05:17:01 -05:00
|
|
|
|
2015-12-30 13:59:23 -05:00
|
|
|
def test_missing_templates
|
|
|
|
get :missing_templates, format: :json
|
|
|
|
assert_response :no_content
|
|
|
|
get :missing_templates, format: :xml
|
|
|
|
assert_response :no_content
|
|
|
|
end
|
|
|
|
|
2013-12-03 05:17:01 -05:00
|
|
|
def test_invalid_variant
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
|
|
|
get :variant_with_implicit_template_rendering, params: { v: :invalid }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_not_set_regular_unknown_format
|
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
|
|
|
get :variant_with_implicit_template_rendering
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_with_implicit_template_rendering
|
|
|
|
get :variant_with_implicit_template_rendering, params: { v: :mobile }
|
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "mobile", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_without_implicit_rendering_from_browser
|
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
|
|
|
get :variant_without_implicit_template_rendering, params: { v: :does_not_matter }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_variant_not_set_and_without_implicit_rendering_from_browser
|
|
|
|
assert_raises(ActionController::UnknownFormat) do
|
|
|
|
get :variant_without_implicit_template_rendering
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_without_implicit_rendering_from_xhr
|
2015-03-17 10:36:21 -04:00
|
|
|
logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
|
|
|
|
old_logger, ActionController::Base.logger = ActionController::Base.logger, logger
|
|
|
|
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
get :variant_without_implicit_template_rendering, xhr: true, params: { v: :does_not_matter }
|
2015-03-17 10:36:21 -04:00
|
|
|
assert_response :no_content
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
|
2016-08-16 03:30:11 -04:00
|
|
|
assert_equal 1, logger.logged(:info).select { |s| s == NO_CONTENT_WARNING }.size, "Implicit head :no_content not logged"
|
2015-03-17 10:36:21 -04:00
|
|
|
ensure
|
|
|
|
ActionController::Base.logger = old_logger
|
2013-12-03 05:17:01 -05:00
|
|
|
end
|
|
|
|
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
def test_variant_without_implicit_rendering_from_api
|
|
|
|
logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
|
|
|
|
old_logger, ActionController::Base.logger = ActionController::Base.logger, logger
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
get :variant_without_implicit_template_rendering, format: "json", params: { v: :does_not_matter }
|
2015-03-17 10:36:21 -04:00
|
|
|
assert_response :no_content
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
|
2016-08-16 03:30:11 -04:00
|
|
|
assert_equal 1, logger.logged(:info).select { |s| s == NO_CONTENT_WARNING }.size, "Implicit head :no_content not logged"
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
ensure
|
|
|
|
ActionController::Base.logger = old_logger
|
2013-12-03 05:17:01 -05:00
|
|
|
end
|
|
|
|
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
def test_variant_variant_not_set_and_without_implicit_rendering_from_xhr
|
|
|
|
logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
|
|
|
|
old_logger, ActionController::Base.logger = ActionController::Base.logger, logger
|
|
|
|
|
|
|
|
get :variant_without_implicit_template_rendering, xhr: true
|
2015-03-17 10:36:21 -04:00
|
|
|
assert_response :no_content
|
|
|
|
|
Lock down new `ImplicitRender` behavior for 5.0 RC
1. Conceptually revert #20276
The feature was implemented for the `responders` gem. In the end,
they did not need that feature, and have found a better fix (see
plataformatec/responders#131).
`ImplicitRender` is the place where Rails specifies our default
policies for the case where the user did not explicitly tell us
what to render, essentially describing a set of heuristics. If
the gem (or the user) knows exactly what they want, they could
just perform the correct `render` to avoid falling through to
here, as `responders` did (the user called `respond_with`).
Reverting the patch allows us to avoid exploding the complexity
and defining “the fallback for a fallback” policies.
2. `respond_to` and templates are considered exhaustive enumerations
If the user specified a list of formats/variants in a `respond_to`
block, anything that is not explicitly included should result
in an `UnknownFormat` error (which is then caught upstream to
mean “406 Not Acceptable” by default). This is already how it
works before this commit.
Same goes for templates – if the user defined a set of templates
(usually in the file system), that set is now considered exhaustive,
which means that “missing” templates are considered `UnknownFormat`
errors (406).
3. To keep API endpoints simple, the implicit render behavior for
actions with no templates defined at all (regardless of formats,
locales, variants, etc) are defaulted to “204 No Content”. This
is a strictly narrower version of the feature landed in #19036 and
#19377.
4. To avoid confusion when interacting in the browser, these actions
will raise an `UnknownFormat` error for “interactive” requests
instead. (The precise definition of “interactive” requests might
change – the spirit here is to give helpful messages and avoid
confusions.)
Closes #20666, #23062, #23077, #23564
[Godfrey Chan, Jon Moss, Kasper Timm Hansen, Mike Clark, Matthew Draper]
2016-02-23 12:41:26 -05:00
|
|
|
assert_equal 1, logger.logged(:info).select { |s| s == NO_CONTENT_WARNING }.size, "Implicit head :no_content not logged"
|
|
|
|
ensure
|
|
|
|
ActionController::Base.logger = old_logger
|
2013-12-03 05:17:01 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_with_format_and_custom_render
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_with_format_and_custom_render, params: { v: :phone }
|
2013-12-03 05:17:01 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "mobile", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_multiple_variants_for_format
|
2015-07-07 18:51:01 -04:00
|
|
|
get :multiple_variants_for_format, params: { v: :tablet }
|
2013-12-03 05:17:01 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "tablet", @response.body
|
|
|
|
end
|
2013-12-07 18:00:35 -05:00
|
|
|
|
|
|
|
def test_no_variant_in_variant_setup
|
|
|
|
get :variant_plus_none_for_format
|
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "none", @response.body
|
|
|
|
end
|
2013-12-09 18:36:18 -05:00
|
|
|
|
|
|
|
def test_variant_inline_syntax
|
|
|
|
get :variant_inline_syntax
|
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "none", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_syntax, params: { v: :phone }
|
2013-12-09 18:36:18 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
end
|
|
|
|
|
2015-07-06 20:33:19 -04:00
|
|
|
def test_variant_inline_syntax_with_format
|
|
|
|
get :variant_inline_syntax, format: :js
|
|
|
|
assert_equal "text/javascript", @response.content_type
|
|
|
|
assert_equal "js", @response.body
|
|
|
|
end
|
|
|
|
|
2013-12-09 18:36:18 -05:00
|
|
|
def test_variant_inline_syntax_without_block
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_syntax_without_block, params: { v: :phone }
|
2013-12-09 18:36:18 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
end
|
2013-12-24 10:53:10 -05:00
|
|
|
|
|
|
|
def test_variant_any
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any, params: { v: :phone }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any, params: { v: :tablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any, params: { v: :phablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_any_any
|
2014-02-13 14:38:33 -05:00
|
|
|
get :variant_any_any
|
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any_any, params: { v: :phone }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any_any, params: { v: :yolo }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_inline_any
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any, params: { v: :phone }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_any, params: { v: :tablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_any, params: { v: :phablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_inline_any_any
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_any_any, params: { v: :phone }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_any_any, params: { v: :yolo }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "any", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_any_implicit_render
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any_implicit_render, params: { v: :tablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "tablet", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any_implicit_render, params: { v: :phablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phablet", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_any_with_none
|
|
|
|
get :variant_any_with_none
|
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "none or phone", @response.body
|
|
|
|
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_any_with_none, params: { v: :phone }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "none or phone", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_format_any_variant_any
|
2015-07-07 18:51:01 -04:00
|
|
|
get :format_any_variant_any, format: :js, params: { v: :tablet }
|
2013-12-24 10:53:10 -05:00
|
|
|
assert_equal "text/javascript", @response.content_type
|
|
|
|
assert_equal "tablet", @response.body
|
|
|
|
end
|
2014-02-13 09:59:09 -05:00
|
|
|
|
|
|
|
def test_variant_negotiation_inline_syntax
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_syntax_without_block, params: { v: [:tablet, :phone] }
|
2014-02-13 09:59:09 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_negotiation_block_syntax
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_plus_none_for_format, params: { v: [:tablet, :phone] }
|
2014-02-13 09:59:09 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_variant_negotiation_without_block
|
2015-07-07 18:51:01 -04:00
|
|
|
get :variant_inline_syntax_without_block, params: { v: [:tablet, :phone] }
|
2014-02-13 09:59:09 -05:00
|
|
|
assert_equal "text/html", @response.content_type
|
|
|
|
assert_equal "phone", @response.body
|
|
|
|
end
|
2013-08-17 11:30:00 -04:00
|
|
|
end
|