aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actioncable/lib/action_cable/connection/test_case.rb2
-rw-r--r--actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb2
-rw-r--r--actionmailbox/app/views/layouts/rails/conductor.html.erb1
-rw-r--r--actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb31
-rw-r--r--actionmailbox/test/dummy/config/puma.rb2
-rw-r--r--actionpack/CHANGELOG.md10
-rw-r--r--actionpack/lib/action_controller/metal/basic_implicit_render.rb2
-rw-r--r--actionpack/lib/action_controller/metal/force_ssl.rb3
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb4
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb33
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb9
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb6
-rw-r--r--actionpack/test/controller/log_subscriber_test.rb4
-rw-r--r--actionpack/test/controller/new_base/render_context_test.rb55
-rw-r--r--actionpack/test/controller/redirect_test.rb44
-rw-r--r--actionpack/test/dispatch/debug_exceptions_test.rb2
-rw-r--r--actionpack/test/dispatch/live_response_test.rb2
-rw-r--r--actionpack/test/journey/router_test.rb6
-rw-r--r--actiontext/test/dummy/config/puma.rb2
-rw-r--r--actionview/lib/action_view/base.rb18
-rw-r--r--actionview/lib/action_view/context.rb5
-rw-r--r--actionview/lib/action_view/rendering.rb4
-rw-r--r--actionview/lib/action_view/template.rb14
-rw-r--r--actionview/lib/action_view/template/handlers/erb/erubi.rb10
-rw-r--r--actionview/test/abstract_unit.rb2
-rw-r--r--actionview/test/template/template_test.rb2
-rw-r--r--activemodel/CHANGELOG.md28
-rw-r--r--activemodel/lib/active_model/type/time.rb2
-rw-r--r--activemodel/lib/active_model/validations/numericality.rb11
-rw-r--r--activemodel/test/cases/type/time_test.rb1
-rw-r--r--activemodel/test/cases/validations/numericality_validation_test.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb36
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb30
-rw-r--r--activerecord/lib/active_record/migration/compatibility.rb4
-rw-r--r--activerecord/lib/arel/nodes/case.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb14
-rw-r--r--activerecord/test/cases/arel/nodes/case_test.rb10
-rw-r--r--activerecord/test/cases/type/time_test.rb22
-rw-r--r--activestorage/test/controllers/blobs_controller_test.rb25
-rw-r--r--activestorage/test/controllers/representations_controller_test.rb30
-rw-r--r--guides/CHANGELOG.md8
-rw-r--r--guides/source/caching_with_rails.md4
-rw-r--r--guides/source/development_dependencies_install.md1
-rw-r--r--guides/source/rails_on_rack.md2
-rw-r--r--guides/source/testing.md2
-rw-r--r--railties/lib/rails/generators/app_base.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt2
-rw-r--r--railties/lib/rails/tasks/statistics.rake3
-rw-r--r--railties/test/application/rake_test.rb2
50 files changed, 312 insertions, 222 deletions
diff --git a/actioncable/lib/action_cable/connection/test_case.rb b/actioncable/lib/action_cable/connection/test_case.rb
index 26a183d1ec..8d25a55c8a 100644
--- a/actioncable/lib/action_cable/connection/test_case.rb
+++ b/actioncable/lib/action_cable/connection/test_case.rb
@@ -42,8 +42,6 @@ module ActionCable
class TestRequest < ActionDispatch::TestRequest
attr_accessor :session, :cookie_jar
-
- attr_writer :cookie_jar
end
module TestConnection
diff --git a/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb b/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb
index 2cde3db8a0..d051dfe665 100644
--- a/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb
+++ b/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb
@@ -22,7 +22,7 @@ module Rails
def new_mail
Mail.new(params.require(:mail).permit(:from, :to, :cc, :bcc, :in_reply_to, :subject, :body).to_h).tap do |mail|
params[:mail][:attachments].to_a.each do |attachment|
- mail.attachments[attachment.original_filename] = { filename: attachment.path, content_type: attachment.content_type }
+ mail.add_file(filename: attachment.path, content: attachment.read)
end
end
end
diff --git a/actionmailbox/app/views/layouts/rails/conductor.html.erb b/actionmailbox/app/views/layouts/rails/conductor.html.erb
index 75157feb78..1cad6560c4 100644
--- a/actionmailbox/app/views/layouts/rails/conductor.html.erb
+++ b/actionmailbox/app/views/layouts/rails/conductor.html.erb
@@ -4,4 +4,5 @@
</head>
<body>
<%= yield %>
+</body>
</html>
diff --git a/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb b/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb
index 60077d86e2..fcd9ad839f 100644
--- a/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb
+++ b/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb
@@ -10,16 +10,39 @@ class Rails::Conductor::ActionMailbox::InboundEmailsControllerTest < ActionDispa
mail: {
from: "Jason Fried <jason@37signals.com>",
to: "Replies <replies@example.com>",
- bcc: "",
in_reply_to: "<4e6e35f5a38b4_479f13bb90078178@small-app-01.mail>",
- subject: "Discussion: Let's debate these attachments",
+ subject: "Hey there",
+ body: "How's it going?"
+ }
+ }
+ end
+
+ mail = ActionMailbox::InboundEmail.last.mail
+ assert_equal %w[ jason@37signals.com ], mail.from
+ assert_equal %w[ replies@example.com ], mail.to
+ assert_equal "4e6e35f5a38b4_479f13bb90078178@small-app-01.mail", mail.in_reply_to
+ assert_equal "Hey there", mail.subject
+ assert_equal "How's it going?", mail.body.decoded
+ end
+ end
+
+ test "create inbound email with attachments" do
+ with_rails_env("development") do
+ assert_difference -> { ActionMailbox::InboundEmail.count }, +1 do
+ post rails_conductor_inbound_emails_path, params: {
+ mail: {
+ from: "Jason Fried <jason@37signals.com>",
+ to: "Replies <replies@example.com>",
+ subject: "Let's debate some attachments",
body: "Let's talk about these images:",
- attachments: [fixture_file_upload("files/avatar1.jpeg"), fixture_file_upload("files/avatar2.jpeg")]
+ attachments: [ fixture_file_upload("files/avatar1.jpeg"), fixture_file_upload("files/avatar2.jpeg") ]
}
}
end
- assert_equal 2, ActionMailbox::InboundEmail.last.mail.attachments.size
+ mail = ActionMailbox::InboundEmail.last.mail
+ assert_equal "Let's talk about these images:", mail.text_part.decoded
+ assert_equal 2, mail.attachments.count
end
end
diff --git a/actionmailbox/test/dummy/config/puma.rb b/actionmailbox/test/dummy/config/puma.rb
index a5eccf816b..71ed69a895 100644
--- a/actionmailbox/test/dummy/config/puma.rb
+++ b/actionmailbox/test/dummy/config/puma.rb
@@ -16,7 +16,7 @@ port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode.
-# Workers are forked webserver processes. If using threads and workers together
+# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 1a1b1034aa..1d2f6b09c3 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -11,12 +11,6 @@
*Rafael Mendonça França*
-* Ensure external redirects are explicitly allowed
-
- Add `fallback_location` and `allow_other_host` options to `redirect_to`.
-
- *Gannon McGibbon*
-
* Introduce ActionDispatch::HostAuthorization
This is a new middleware that guards against DNS rebinding attacks by
@@ -82,7 +76,7 @@
* Apply mapping to symbols returned from dynamic CSP sources
Previously if a dynamic source returned a symbol such as :self it
- would be converted to a string implicity, e.g:
+ would be converted to a string implicitly, e.g:
policy.default_src -> { :self }
@@ -135,7 +129,7 @@
*Assain Jaleel*
-* Raises `ActionController::RespondToMismatchError` with confliciting `respond_to` invocations.
+* Raises `ActionController::RespondToMismatchError` with conflicting `respond_to` invocations.
`respond_to` can match multiple types and lead to undefined behavior when
multiple invocations are made and the types do not match:
diff --git a/actionpack/lib/action_controller/metal/basic_implicit_render.rb b/actionpack/lib/action_controller/metal/basic_implicit_render.rb
index 2dc990f303..f9a758ff0e 100644
--- a/actionpack/lib/action_controller/metal/basic_implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/basic_implicit_render.rb
@@ -6,7 +6,7 @@ module ActionController
super.tap { default_render unless performed? }
end
- def default_render(*args)
+ def default_render
head :no_content
end
end
diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb
index 205f84ae36..93fd57b640 100644
--- a/actionpack/lib/action_controller/metal/force_ssl.rb
+++ b/actionpack/lib/action_controller/metal/force_ssl.rb
@@ -13,7 +13,7 @@ module ActionController
ACTION_OPTIONS = [:only, :except, :if, :unless]
URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
- REDIRECT_OPTIONS = [:status, :flash, :alert, :notice, :allow_other_host]
+ REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
module ClassMethods # :nodoc:
def force_ssl(options = {})
@@ -41,7 +41,6 @@ module ActionController
host: request.host,
path: request.fullpath,
status: :moved_permanently,
- allow_other_host: true,
}
if host_or_options.is_a?(Hash)
diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb
index d3bb58f48b..8365ddca57 100644
--- a/actionpack/lib/action_controller/metal/implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/implicit_render.rb
@@ -30,9 +30,9 @@ module ActionController
# :stopdoc:
include BasicImplicitRender
- def default_render(*args)
+ def default_render
if template_exists?(action_name.to_s, _prefixes, variants: request.variant)
- render(*args)
+ render
elsif any_templates?(action_name.to_s, _prefixes)
message = "#{self.class.name}\##{action_name} is missing a template " \
"for this request format and variant.\n" \
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 8bd003f5ed..67c198d150 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -60,7 +60,7 @@ module ActionController
raise AbstractController::DoubleRenderError if response_body
self.status = _extract_redirect_to_status(options, response_options)
- self.location = _compute_safe_redirect_to_location(request, options, response_options)
+ self.location = _compute_redirect_to_location(request, options)
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
end
@@ -88,13 +88,9 @@ module ActionController
# All other options that can be passed to <tt>redirect_to</tt> are accepted as
# options and the behavior is identical.
def redirect_back(fallback_location:, allow_other_host: true, **args)
- referer = request.headers.fetch("Referer", fallback_location)
- response_options = {
- fallback_location: fallback_location,
- allow_other_host: allow_other_host,
- **args,
- }
- redirect_to referer, response_options
+ referer = request.headers["Referer"]
+ redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
+ redirect_to redirect_to_referer ? referer : fallback_location, **args
end
def _compute_redirect_to_location(request, options) #:nodoc:
@@ -118,23 +114,6 @@ module ActionController
public :_compute_redirect_to_location
private
- def _compute_safe_redirect_to_location(request, options, response_options)
- location = _compute_redirect_to_location(request, options)
- location_options = options.is_a?(Hash) ? options : {}
- if response_options[:allow_other_host] || _url_host_allowed?(location, location_options)
- location
- else
- fallback_location = response_options.fetch(:fallback_location) do
- raise ArgumentError, <<~MSG.squish
- Unsafe redirect #{location.inspect},
- use :fallback_location to specify a fallback
- or :allow_other_host to redirect anyway.
- MSG
- end
- _compute_redirect_to_location(request, fallback_location)
- end
- end
-
def _extract_redirect_to_status(options, response_options)
if options.is_a?(Hash) && options.key?(:status)
Rack::Utils.status_code(options.delete(:status))
@@ -145,8 +124,8 @@ module ActionController
end
end
- def _url_host_allowed?(url, options = {})
- URI(url.to_s).host.in?([request.host, options[:host]])
+ def _url_host_allowed?(url)
+ URI(url.to_s).host == request.host
rescue ArgumentError, URI::Error
false
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index af41521c5c..28cde6704e 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -160,9 +160,16 @@ module ActionDispatch
@controller.singleton_class.include(_routes.url_helpers)
if @controller.respond_to? :view_context_class
- @controller.view_context_class = Class.new(@controller.view_context_class) do
+ view_context_class = Class.new(@controller.view_context_class) do
include _routes.url_helpers
end
+
+ custom_view_context = Module.new {
+ define_method(:view_context_class) do
+ view_context_class
+ end
+ }
+ @controller.extend(custom_view_context)
end
end
yield @routes
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index c7aae034dd..ecb8c37e6b 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -28,13 +28,13 @@ class ActionPackAssertionsController < ActionController::Base
def redirect_to_path() redirect_to "/some/path" end
- def redirect_invalid_external_route() redirect_to "ht_tp://www.rubyonrails.org", allow_other_host: true end
+ def redirect_invalid_external_route() redirect_to "ht_tp://www.rubyonrails.org" end
def redirect_to_named_route() redirect_to route_one_url end
- def redirect_external() redirect_to "http://www.rubyonrails.org", allow_other_host: true; end
+ def redirect_external() redirect_to "http://www.rubyonrails.org"; end
- def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org", allow_other_host: true; end
+ def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org"; end
def response404() head "404 AWOL" end
diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb
index cbebc6b59c..0562c16284 100644
--- a/actionpack/test/controller/log_subscriber_test.rb
+++ b/actionpack/test/controller/log_subscriber_test.rb
@@ -25,11 +25,11 @@ module Another
end
def redirector
- redirect_to "http://foo.bar/", allow_other_host: true
+ redirect_to "http://foo.bar/"
end
def filterable_redirector
- redirect_to "http://secret.foo.bar/", allow_other_host: true
+ redirect_to "http://secret.foo.bar/"
end
def data_sender
diff --git a/actionpack/test/controller/new_base/render_context_test.rb b/actionpack/test/controller/new_base/render_context_test.rb
deleted file mode 100644
index 5e570a1d79..0000000000
--- a/actionpack/test/controller/new_base/render_context_test.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-require "abstract_unit"
-
-# This is testing the decoupling of view renderer and view context
-# by allowing the controller to be used as view context. This is
-# similar to the way sinatra renders templates.
-module RenderContext
- class BasicController < ActionController::Base
- self.view_paths = [ActionView::FixtureResolver.new(
- "render_context/basic/hello_world.html.erb" => "<%= @value %> from <%= self.__controller_method__ %>",
- "layouts/basic.html.erb" => "?<%= yield %>?"
- )]
-
- # 1) Include ActionView::Context to bring the required dependencies
- include ActionView::Context
-
- # 2) Call _prepare_context that will do the required initialization
- before_action :_prepare_context
-
- def hello_world
- @value = "Hello"
- render action: "hello_world", layout: false
- end
-
- def with_layout
- @value = "Hello"
- render action: "hello_world", layout: "basic"
- end
-
- protected def __controller_method__
- "controller context!"
- end
-
- private
- # 3) Set view_context to self
- def view_context
- self
- end
- end
-
- class RenderContextTest < Rack::TestCase
- test "rendering using the controller as context" do
- get "/render_context/basic/hello_world"
- assert_body "Hello from controller context!"
- assert_status 200
- end
-
- test "rendering using the controller as context with layout" do
- get "/render_context/basic/with_layout"
- assert_body "?Hello from controller context!?"
- assert_status 200
- end
- end
-end
diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb
index 945d2275c0..998498e1b2 100644
--- a/actionpack/test/controller/redirect_test.rb
+++ b/actionpack/test/controller/redirect_test.rb
@@ -49,11 +49,11 @@ class RedirectController < ActionController::Base
end
def url_redirect_with_status
- redirect_to("http://www.example.com", status: :moved_permanently, allow_other_host: true)
+ redirect_to("http://www.example.com", status: :moved_permanently)
end
def url_redirect_with_status_hash
- redirect_to("http://www.example.com", status: 301, allow_other_host: true)
+ redirect_to("http://www.example.com", status: 301)
end
def relative_url_redirect_with_status
@@ -81,27 +81,19 @@ class RedirectController < ActionController::Base
end
def redirect_to_url
- redirect_to "http://www.rubyonrails.org/", allow_other_host: true
- end
-
- def redirect_to_unsafe_url
redirect_to "http://www.rubyonrails.org/"
end
- def redirect_to_relative_unsafe_url
- redirect_to ".br"
- end
-
def redirect_to_url_with_unescaped_query_string
- redirect_to "http://example.com/query?status=new", allow_other_host: true
+ redirect_to "http://example.com/query?status=new"
end
def redirect_to_url_with_complex_scheme
- redirect_to "x-test+scheme.complex:redirect", allow_other_host: true
+ redirect_to "x-test+scheme.complex:redirect"
end
def redirect_to_url_with_network_path_reference
- redirect_to "//www.rubyonrails.org/", allow_other_host: true
+ redirect_to "//www.rubyonrails.org/"
end
def redirect_to_existing_record
@@ -121,12 +113,12 @@ class RedirectController < ActionController::Base
end
def redirect_to_with_block
- redirect_to proc { "http://www.rubyonrails.org/" }, allow_other_host: true
+ redirect_to proc { "http://www.rubyonrails.org/" }
end
def redirect_to_with_block_and_assigns
@url = "http://www.rubyonrails.org/"
- redirect_to proc { @url }, allow_other_host: true
+ redirect_to proc { @url }
end
def redirect_to_with_block_and_options
@@ -253,28 +245,6 @@ class RedirectTest < ActionController::TestCase
assert_redirected_to "http://www.rubyonrails.org/"
end
- def test_redirect_to_unsafe_url
- error = assert_raises(ArgumentError) do
- get :redirect_to_unsafe_url
- end
- assert_equal <<~MSG.squish, error.message
- Unsafe redirect \"http://www.rubyonrails.org/\",
- use :fallback_location to specify a fallback or
- :allow_other_host to redirect anyway.
- MSG
- end
-
- def test_redirect_to_relative_unsafe_url
- error = assert_raises(ArgumentError) do
- get :redirect_to_relative_unsafe_url
- end
- assert_equal <<~MSG.squish, error.message
- Unsafe redirect \"http://test.host.br\",
- use :fallback_location to specify a fallback or
- :allow_other_host to redirect anyway.
- MSG
- end
-
def test_redirect_to_url_with_unescaped_query_string
get :redirect_to_url_with_unescaped_query_string
assert_response :redirect
diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb
index c326f276bf..aadc6be077 100644
--- a/actionpack/test/dispatch/debug_exceptions_test.rb
+++ b/actionpack/test/dispatch/debug_exceptions_test.rb
@@ -8,7 +8,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
class Boomer
attr_accessor :closed
- def initialize(detailed = false)
+ def initialize(detailed = false)
@detailed = detailed
@closed = false
end
diff --git a/actionpack/test/dispatch/live_response_test.rb b/actionpack/test/dispatch/live_response_test.rb
index a9a56f205f..b673fd3805 100644
--- a/actionpack/test/dispatch/live_response_test.rb
+++ b/actionpack/test/dispatch/live_response_test.rb
@@ -62,7 +62,7 @@ module ActionController
assert_nil @response.headers["Content-Length"]
end
- def test_headers_cannot_be_written_after_webserver_reads
+ def test_headers_cannot_be_written_after_web_server_reads
@response.stream.write "omg"
latch = Concurrent::CountDownLatch.new
diff --git a/actionpack/test/journey/router_test.rb b/actionpack/test/journey/router_test.rb
index 1f4e14aef6..f8d89def6a 100644
--- a/actionpack/test/journey/router_test.rb
+++ b/actionpack/test/journey/router_test.rb
@@ -284,7 +284,7 @@ module ActionDispatch
def test_generate_missing_keys_no_matches_different_format_keys
get "/:controller/:action/:name", to: "foo#bar"
- primarty_parameters = {
+ primary_parameters = {
id: 1,
controller: "tasks",
action: "show",
@@ -297,9 +297,9 @@ module ActionDispatch
missing_parameters = {
missing_key => "task_1"
}
- request_parameters = primarty_parameters.merge(redirection_parameters).merge(missing_parameters)
+ request_parameters = primary_parameters.merge(redirection_parameters).merge(missing_parameters)
- message = "No route matches #{Hash[request_parameters.sort_by { |k, v|k.to_s }].inspect}, missing required keys: #{[missing_key.to_sym].inspect}"
+ message = "No route matches #{Hash[request_parameters.sort_by { |k, _|k.to_s }].inspect}, missing required keys: #{[missing_key.to_sym].inspect}"
error = assert_raises(ActionController::UrlGenerationError) do
@formatter.generate(
diff --git a/actiontext/test/dummy/config/puma.rb b/actiontext/test/dummy/config/puma.rb
index a5eccf816b..71ed69a895 100644
--- a/actiontext/test/dummy/config/puma.rb
+++ b/actiontext/test/dummy/config/puma.rb
@@ -16,7 +16,7 @@ port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode.
-# Workers are forked webserver processes. If using threads and workers together
+# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index d41fe2a608..6cb342a0a9 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -10,6 +10,10 @@ require "action_view/template"
require "action_view/lookup_context"
module ActionView #:nodoc:
+ module CompiledTemplates #:nodoc:
+ # holds compiled template code
+ end
+
# = Action View Base
#
# Action View templates can be written in several ways.
@@ -141,6 +145,8 @@ module ActionView #:nodoc:
class Base
include Helpers, ::ERB::Util, Context
+ include CompiledTemplates
+
# Specify the proc used to decorate input tags that refer to attributes with errors.
cattr_accessor :field_error_proc, default: Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
@@ -210,6 +216,18 @@ module ActionView #:nodoc:
_prepare_context
end
+ def run(method, locals, buffer, &block)
+ _old_output_buffer, _old_virtual_path = @output_buffer, @virtual_path
+ @output_buffer = buffer
+ send(method, locals, buffer, &block)
+ ensure
+ @output_buffer, @virtual_path = _old_output_buffer, _old_virtual_path
+ end
+
+ def compiled_method_container
+ CompiledTemplates
+ end
+
ActiveSupport.run_load_hooks(:action_view, self)
end
end
diff --git a/actionview/lib/action_view/context.rb b/actionview/lib/action_view/context.rb
index 3c605c3ee3..2b22c30a3a 100644
--- a/actionview/lib/action_view/context.rb
+++ b/actionview/lib/action_view/context.rb
@@ -1,10 +1,6 @@
# frozen_string_literal: true
module ActionView
- module CompiledTemplates #:nodoc:
- # holds compiled template code
- end
-
# = Action View Context
#
# Action View contexts are supplied to Action Controller to render a template.
@@ -16,7 +12,6 @@ module ActionView
# object that includes this module (although you can call _prepare_context
# defined below).
module Context
- include CompiledTemplates
attr_accessor :output_buffer, :view_flow
# Prepares the context by setting the appropriate instance variables.
diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb
index cb4327cf16..205665a8c6 100644
--- a/actionview/lib/action_view/rendering.rb
+++ b/actionview/lib/action_view/rendering.rb
@@ -55,10 +55,8 @@ module ActionView
end
end
- attr_internal_writer :view_context_class
-
def view_context_class
- @_view_context_class ||= self.class.view_context_class
+ self.class.view_context_class
end
# An instance of a view class. The default view class is ActionView::Base.
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb
index 070d82cf17..8ce8053011 100644
--- a/actionview/lib/action_view/template.rb
+++ b/actionview/lib/action_view/template.rb
@@ -155,10 +155,10 @@ module ActionView
# This method is instrumented as "!render_template.action_view". Notice that
# we use a bang in this instrumentation because you don't want to
# consume this in production. This is only slow if it's being listened to.
- def render(view, locals, buffer = nil, &block)
+ def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
instrument_render_template do
compile!(view)
- view.send(method_name, locals, buffer, &block)
+ view.run(method_name, locals, buffer, &block)
end
rescue => e
handle_render_error(view, e)
@@ -264,11 +264,7 @@ module ActionView
# re-compilation
return if @compiled
- if view.is_a?(ActionView::CompiledTemplates)
- mod = ActionView::CompiledTemplates
- else
- mod = view.singleton_class
- end
+ mod = view.compiled_method_container
instrument("!compile_template") do
compile(mod)
@@ -301,9 +297,7 @@ module ActionView
# encoding of the code
source = +<<-end_src
def #{method_name}(local_assigns, output_buffer)
- _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
- ensure
- @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
+ @virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
end
end_src
diff --git a/actionview/lib/action_view/template/handlers/erb/erubi.rb b/actionview/lib/action_view/template/handlers/erb/erubi.rb
index db75f028ed..e155bae89d 100644
--- a/actionview/lib/action_view/template/handlers/erb/erubi.rb
+++ b/actionview/lib/action_view/template/handlers/erb/erubi.rb
@@ -13,7 +13,7 @@ module ActionView
# Dup properties so that we don't modify argument
properties = Hash[properties]
- properties[:preamble] = "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
+ properties[:preamble] = ""
properties[:postamble] = "@output_buffer.to_s"
properties[:bufvar] = "@output_buffer"
properties[:escapefunc] = ""
@@ -22,8 +22,12 @@ module ActionView
end
def evaluate(action_view_erb_handler_context)
- pr = eval("proc { #{@src} }", binding, @filename || "(erubi)")
- action_view_erb_handler_context.instance_eval(&pr)
+ src = @src
+ view = Class.new(ActionView::Base) {
+ include action_view_erb_handler_context._routes.url_helpers
+ class_eval("define_method(:_template) { |local_assigns, output_buffer| #{src} }", @filename || "(erubi)", 0)
+ }.new(action_view_erb_handler_context)
+ view.run(:_template, {}, ActionView::OutputBuffer.new)
end
private
diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb
index f90626ad9e..d71944e938 100644
--- a/actionview/test/abstract_unit.rb
+++ b/actionview/test/abstract_unit.rb
@@ -61,7 +61,7 @@ module RenderERBUtils
ActionView::Template::Handlers::ERB,
{})
- template.render(self, {}).strip
+ template.render(ActionView::Base.new, {}).strip
end
end
diff --git a/actionview/test/template/template_test.rb b/actionview/test/template/template_test.rb
index b348d1f17b..8257d97b7c 100644
--- a/actionview/test/template/template_test.rb
+++ b/actionview/test/template/template_test.rb
@@ -18,7 +18,7 @@ class TestERBTemplate < ActiveSupport::TestCase
attr_accessor :formats
end
- class Context
+ class Context < ActionView::Base
def initialize
@output_buffer = "original"
@virtual_path = nil
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 571c050f2f..912b307683 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,3 +1,31 @@
+* Fix year value when casting a multiparameter time hash
+
+ When assigning a hash to a time attribute that's missing a year component
+ (e.g. a `time_select` with `:ignore_date` set to `true`) then the year
+ defaults to 1970 instead of the expected 2000. This results in the attribute
+ changing as a result of the save.
+
+ Before:
+ ```
+ event = Event.new(start_time: { 4 => 20, 5 => 30 })
+ event.start_time # => 1970-01-01 20:30:00 UTC
+ event.save
+ event.reload
+ event.start_time # => 2000-01-01 20:30:00 UTC
+ ```
+
+ After:
+ ```
+ event = Event.new(start_time: { 4 => 20, 5 => 30 })
+ event.start_time # => 2000-01-01 20:30:00 UTC
+ event.save
+ event.reload
+ event.start_time # => 2000-01-01 20:30:00 UTC
+ ```
+
+ *Andrew White*
+
+
## Rails 6.0.0.beta1 (January 18, 2019) ##
* Add `ActiveModel::Errors#of_kind?`.
diff --git a/activemodel/lib/active_model/type/time.rb b/activemodel/lib/active_model/type/time.rb
index b3056b1333..8fba01b86a 100644
--- a/activemodel/lib/active_model/type/time.rb
+++ b/activemodel/lib/active_model/type/time.rb
@@ -5,7 +5,7 @@ module ActiveModel
class Time < Value # :nodoc:
include Helpers::TimeValue
include Helpers::AcceptsMultiparameterTime.new(
- defaults: { 1 => 1970, 2 => 1, 3 => 1, 4 => 0, 5 => 0 }
+ defaults: { 1 => 2000, 2 => 1, 3 => 1, 4 => 0, 5 => 0 }
)
def type
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index c5997283ea..9cb8b543b0 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -10,7 +10,6 @@ module ActiveModel
RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
INTEGER_REGEX = /\A[+-]?\d+\z/
- DECIMAL_REGEX = /\A[+-]?\d+\.?\d*(e|e[+-])?\d+\z/
def check_validity!
keys = CHECKS.keys - [:odd, :even]
@@ -92,8 +91,8 @@ module ActiveModel
raw_value
elsif is_integer?(raw_value)
raw_value.to_i
- elsif is_decimal?(raw_value) && !is_hexadecimal_literal?(raw_value)
- BigDecimal(raw_value)
+ elsif !is_hexadecimal_literal?(raw_value)
+ Kernel.Float(raw_value).to_d
end
end
@@ -101,12 +100,8 @@ module ActiveModel
INTEGER_REGEX.match?(raw_value.to_s)
end
- def is_decimal?(raw_value)
- DECIMAL_REGEX.match?(raw_value.to_s)
- end
-
def is_hexadecimal_literal?(raw_value)
- /\A0[xX]/.match?(raw_value)
+ /\A0[xX]/.match?(raw_value.to_s)
end
def filtered_options(value)
diff --git a/activemodel/test/cases/type/time_test.rb b/activemodel/test/cases/type/time_test.rb
index 3fbae1a169..5c6271241d 100644
--- a/activemodel/test/cases/type/time_test.rb
+++ b/activemodel/test/cases/type/time_test.rb
@@ -16,6 +16,7 @@ module ActiveModel
assert_equal ::Time.utc(2000, 1, 1, 16, 45, 54), type.cast("2015-06-13T19:45:54+03:00")
assert_equal ::Time.utc(1999, 12, 31, 21, 7, 8), type.cast("06:07:08+09:00")
+ assert_equal ::Time.utc(2000, 1, 1, 16, 45, 54), type.cast(4 => 16, 5 => 45, 6 => 54)
end
def test_user_input_in_time_zone
diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb
index eb4b02df93..fcdf123062 100644
--- a/activemodel/test/cases/validations/numericality_validation_test.rb
+++ b/activemodel/test/cases/validations/numericality_validation_test.rb
@@ -281,6 +281,19 @@ class NumericalityValidationTest < ActiveModel::TestCase
assert_predicate topic, :invalid?
end
+ def test_validates_numericalty_with_object_acting_as_numeric
+ klass = Class.new do
+ def to_f
+ 123.54
+ end
+ end
+
+ Topic.validates_numericality_of :price
+ topic = Topic.new(price: klass.new)
+
+ assert_predicate topic, :valid?
+ end
+
def test_validates_numericality_with_invalid_args
assert_raise(ArgumentError) { Topic.validates_numericality_of :approved, greater_than_or_equal_to: "foo" }
assert_raise(ArgumentError) { Topic.validates_numericality_of :approved, less_than_or_equal_to: "foo" }
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 70d281b62b..5479ddab71 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -627,6 +627,7 @@ module ActiveRecord
ER_LOCK_WAIT_TIMEOUT = 1205
ER_QUERY_INTERRUPTED = 1317
ER_QUERY_TIMEOUT = 3024
+ ER_FK_INCOMPATIBLE_COLUMNS = 3780
def translate_exception(exception, message:, sql:, binds:)
case error_number(exception)
@@ -634,7 +635,7 @@ module ActiveRecord
RecordNotUnique.new(message, sql: sql, binds: binds)
when ER_NO_REFERENCED_ROW, ER_ROW_IS_REFERENCED, ER_ROW_IS_REFERENCED_2, ER_NO_REFERENCED_ROW_2
InvalidForeignKey.new(message, sql: sql, binds: binds)
- when ER_CANNOT_ADD_FOREIGN
+ when ER_CANNOT_ADD_FOREIGN, ER_FK_INCOMPATIBLE_COLUMNS
mismatched_foreign_key(message, sql: sql, binds: binds)
when ER_CANNOT_CREATE_TABLE
if message.include?("errno: 150")
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb
index ceb8b40bd9..84dd28907b 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb
@@ -17,6 +17,42 @@ module ActiveRecord
"VALIDATE CONSTRAINT #{quote_column_name(name)}"
end
+ def visit_ChangeColumnDefinition(o)
+ column = o.column
+ column.sql_type = type_to_sql(column.type, column.options)
+ quoted_column_name = quote_column_name(o.name)
+
+ change_column_sql = +"ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}"
+
+ options = column_options(column)
+
+ if options[:collation]
+ change_column_sql << " COLLATE \"#{options[:collation]}\""
+ end
+
+ if options[:using]
+ change_column_sql << " USING #{options[:using]}"
+ elsif options[:cast_as]
+ cast_as_type = type_to_sql(options[:cast_as], options)
+ change_column_sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
+ end
+
+ if options.key?(:default)
+ if options[:default].nil?
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} DROP DEFAULT"
+ else
+ quoted_default = quote_default_expression(options[:default], column)
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} SET DEFAULT #{quoted_default}"
+ end
+ end
+
+ if options.key?(:null)
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL"
+ end
+
+ change_column_sql
+ end
+
def add_column_options!(sql, options)
if options[:collation]
sql << " COLLATE \"#{options[:collation]}\""
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 3516bef75a..7cf371be68 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -683,38 +683,20 @@ module ActiveRecord
end
end
- def change_column_sql(table_name, column_name, type, options = {})
- quoted_column_name = quote_column_name(column_name)
- sql_type = type_to_sql(type, options)
- sql = +"ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}"
- if options[:collation]
- sql << " COLLATE \"#{options[:collation]}\""
- end
- if options[:using]
- sql << " USING #{options[:using]}"
- elsif options[:cast_as]
- cast_as_type = type_to_sql(options[:cast_as], options)
- sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
- end
-
- sql
- end
-
def add_column_for_alter(table_name, column_name, type, options = {})
return super unless options.key?(:comment)
[super, Proc.new { change_column_comment(table_name, column_name, options[:comment]) }]
end
def change_column_for_alter(table_name, column_name, type, options = {})
- sqls = [change_column_sql(table_name, column_name, type, options)]
- sqls << change_column_default_for_alter(table_name, column_name, options[:default]) if options.key?(:default)
- sqls << change_column_null_for_alter(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
+ td = create_table_definition(table_name)
+ cd = td.new_column_definition(column_name, type, options)
+ sqls = [schema_creation.accept(ChangeColumnDefinition.new(cd, column_name))]
sqls << Proc.new { change_column_comment(table_name, column_name, options[:comment]) } if options.key?(:comment)
sqls
end
- # Changes the default value of a table column.
- def change_column_default_for_alter(table_name, column_name, default_or_changes) # :nodoc:
+ def change_column_default_for_alter(table_name, column_name, default_or_changes)
column = column_for(table_name, column_name)
return unless column
@@ -729,8 +711,8 @@ module ActiveRecord
end
end
- def change_column_null_for_alter(table_name, column_name, null, default = nil) #:nodoc:
- "ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL"
+ def change_column_null_for_alter(table_name, column_name, null, default = nil)
+ "ALTER COLUMN #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL"
end
def add_timestamps_for_alter(table_name, options = {})
diff --git a/activerecord/lib/active_record/migration/compatibility.rb b/activerecord/lib/active_record/migration/compatibility.rb
index 8f6fcfcaea..608182e363 100644
--- a/activerecord/lib/active_record/migration/compatibility.rb
+++ b/activerecord/lib/active_record/migration/compatibility.rb
@@ -36,9 +36,7 @@ module ActiveRecord
class V5_1 < V5_2
def change_column(table_name, column_name, type, options = {})
if adapter_name == "PostgreSQL"
- clear_cache!
- sql = connection.send(:change_column_sql, table_name, column_name, type, options)
- execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}"
+ super(table_name, column_name, type, options.except(:default, :null, :comment))
change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
diff --git a/activerecord/lib/arel/nodes/case.rb b/activerecord/lib/arel/nodes/case.rb
index 654a54825e..b8f83128c8 100644
--- a/activerecord/lib/arel/nodes/case.rb
+++ b/activerecord/lib/arel/nodes/case.rb
@@ -3,6 +3,8 @@
module Arel # :nodoc: all
module Nodes
class Case < Arel::Nodes::Node
+ include Arel::AliasPredication
+
attr_accessor :case, :conditions, :default
def initialize(expression = nil, default = nil)
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index b12055a40a..2e7a4b498f 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -17,7 +17,7 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
enable_extension!("hstore", @connection)
@connection.transaction do
- @connection.create_table("pg_arrays") do |t|
+ @connection.create_table "pg_arrays", force: true do |t|
t.string "tags", array: true, limit: 255
t.integer "ratings", array: true
t.datetime :datetimes, array: true
@@ -112,6 +112,18 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
assert_predicate column, :array?
end
+ def test_change_column_from_non_array_to_array
+ @connection.add_column :pg_arrays, :snippets, :string
+ @connection.change_column :pg_arrays, :snippets, :text, array: true, default: [], using: "string_to_array(\"snippets\", ',')"
+
+ PgArray.reset_column_information
+ column = PgArray.columns_hash["snippets"]
+
+ assert_equal :text, column.type
+ assert_equal [], PgArray.column_defaults["snippets"]
+ assert_predicate column, :array?
+ end
+
def test_change_column_cant_make_non_array_column_to_array
@connection.add_column :pg_arrays, :a_string, :string
assert_raises ActiveRecord::StatementInvalid do
diff --git a/activerecord/test/cases/arel/nodes/case_test.rb b/activerecord/test/cases/arel/nodes/case_test.rb
index 89861488df..946c2b0453 100644
--- a/activerecord/test/cases/arel/nodes/case_test.rb
+++ b/activerecord/test/cases/arel/nodes/case_test.rb
@@ -80,6 +80,16 @@ module Arel
assert_equal 2, array.uniq.size
end
end
+
+ describe "#as" do
+ it "allows aliasing" do
+ node = Case.new "foo"
+ as = node.as("bar")
+
+ assert_equal node, as.left
+ assert_kind_of Arel::Nodes::SqlLiteral, as.right
+ end
+ end
end
end
end
diff --git a/activerecord/test/cases/type/time_test.rb b/activerecord/test/cases/type/time_test.rb
new file mode 100644
index 0000000000..1a2c47479f
--- /dev/null
+++ b/activerecord/test/cases/type/time_test.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "models/topic"
+
+module ActiveRecord
+ module Type
+ class TimeTest < ActiveRecord::TestCase
+ def test_default_year_is_correct
+ expected_time = ::Time.utc(2000, 1, 1, 10, 30, 0)
+ topic = Topic.new(bonus_time: { 4 => 10, 5 => 30 })
+
+ assert_equal expected_time, topic.bonus_time
+
+ topic.save!
+ topic.reload
+
+ assert_equal expected_time, topic.bonus_time
+ end
+ end
+ end
+end
diff --git a/activestorage/test/controllers/blobs_controller_test.rb b/activestorage/test/controllers/blobs_controller_test.rb
index 9c811df895..9bf2641de6 100644
--- a/activestorage/test/controllers/blobs_controller_test.rb
+++ b/activestorage/test/controllers/blobs_controller_test.rb
@@ -20,3 +20,28 @@ class ActiveStorage::BlobsControllerTest < ActionDispatch::IntegrationTest
assert_equal "max-age=300, private", @response.headers["Cache-Control"]
end
end
+
+if SERVICE_CONFIGURATIONS[:s3] && SERVICE_CONFIGURATIONS[:s3][:access_key_id].present?
+ class ActiveStorage::S3BlobsControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @old_service = ActiveStorage::Blob.service
+ ActiveStorage::Blob.service = ActiveStorage::Service.configure(:s3, SERVICE_CONFIGURATIONS)
+ end
+
+ teardown do
+ ActiveStorage::Blob.service = @old_service
+ end
+
+ test "allow redirection to the different host" do
+ blob = create_file_blob filename: "racecar.jpg"
+
+ assert_nothing_raised { get rails_blob_url(blob) }
+ assert_response :redirect
+ assert_no_match @request.host, @response.headers["Location"]
+ ensure
+ blob.purge
+ end
+ end
+else
+ puts "Skipping S3 redirection tests because no S3 configuration was supplied"
+end
diff --git a/activestorage/test/controllers/representations_controller_test.rb b/activestorage/test/controllers/representations_controller_test.rb
index 2662cc5283..4ae0ff877e 100644
--- a/activestorage/test/controllers/representations_controller_test.rb
+++ b/activestorage/test/controllers/representations_controller_test.rb
@@ -59,3 +59,33 @@ class ActiveStorage::RepresentationsControllerWithPreviewsTest < ActionDispatch:
assert_response :not_found
end
end
+
+if SERVICE_CONFIGURATIONS[:s3] && SERVICE_CONFIGURATIONS[:s3][:access_key_id].present?
+ class ActiveStorage::S3RepresentationsControllerWithVariantsTest < ActionDispatch::IntegrationTest
+ setup do
+ @old_service = ActiveStorage::Blob.service
+ ActiveStorage::Blob.service = ActiveStorage::Service.configure(:s3, SERVICE_CONFIGURATIONS)
+ end
+
+ teardown do
+ ActiveStorage::Blob.service = @old_service
+ end
+
+ test "allow redirection to the different host" do
+ blob = create_file_blob filename: "racecar.jpg"
+
+ assert_nothing_raised do
+ get rails_blob_representation_url(
+ filename: blob.filename,
+ signed_blob_id: blob.signed_id,
+ variation_key: ActiveStorage::Variation.encode(resize: "100x100"))
+ end
+ assert_response :redirect
+ assert_no_match @request.host, @response.headers["Location"]
+ ensure
+ blob.purge
+ end
+ end
+else
+ puts "Skipping S3 redirection tests because no S3 configuration was supplied"
+end
diff --git a/guides/CHANGELOG.md b/guides/CHANGELOG.md
index 5a97fbb586..6432dbfd00 100644
--- a/guides/CHANGELOG.md
+++ b/guides/CHANGELOG.md
@@ -1,5 +1,13 @@
## Rails 6.0.0.beta1 (January 18, 2019) ##
+* Add "Action Text Overview" Guide.
+
+ *DHH*
+
+* Add "Action Mailbox Basics" Guide.
+
+ *DHH*
+
* New section _Troubleshooting_ in the _Autoloading and Reloading Constants_ guide.
*Xavier Noria*
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 3ac3f8fa8b..56c0ca78a0 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -51,10 +51,10 @@ For instance, it will not impact low-level caching, that we address
### Page Caching
Page caching is a Rails mechanism which allows the request for a generated page
-to be fulfilled by the webserver (i.e. Apache or NGINX) without having to go
+to be fulfilled by the web server (i.e. Apache or NGINX) without having to go
through the entire Rails stack. While this is super fast it can't be applied to
every situation (such as pages that need authentication). Also, because the
-webserver is serving a file directly from the filesystem you will need to
+web server is serving a file directly from the filesystem you will need to
implement cache expiration.
INFO: Page Caching has been removed from Rails 4. See the [actionpack-page_caching gem](https://github.com/rails/actionpack-page_caching).
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index b3baf726e3..e84e5561f2 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -227,7 +227,6 @@ If you're using another database, check the file `activerecord/test/config.yml`
If you installed Yarn, you will need to install the javascript dependencies:
```bash
-$ cd activestorage
$ yarn install
```
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index c33851a0f9..69b5f254bf 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -35,7 +35,7 @@ application. Any Rack compliant web server should be using
### `rails server`
-`rails server` does the basic job of creating a `Rack::Server` object and starting the webserver.
+`rails server` does the basic job of creating a `Rack::Server` object and starting the web server.
Here's how `rails server` creates an instance of `Rack::Server`
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 1a2f480407..f9661c52a0 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -1775,7 +1775,7 @@ test "connects with cookies" do
end
```
-See the API documentation for [`AcionCable::Connection::TestCase`](http://api.rubyonrails.org/classes/ActionCable/Connection/TestCase.html) for more information.
+See the API documentation for [`ActionCable::Connection::TestCase`](http://api.rubyonrails.org/classes/ActionCable/Connection/TestCase.html) for more information.
### Channel Test Case
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 0023a9a6a6..0eed552042 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -128,7 +128,7 @@ module Rails
def gemfile_entries # :doc:
[rails_gemfile_entry,
database_gemfile_entry,
- webserver_gemfile_entry,
+ web_server_gemfile_entry,
assets_gemfile_entry,
webpacker_gemfile_entry,
javascript_gemfile_entry,
@@ -189,7 +189,7 @@ module Rails
"Use #{options[:database]} as the database for Active Record"
end
- def webserver_gemfile_entry # :doc:
+ def web_server_gemfile_entry # :doc:
return [] if options[:skip_puma]
comment = "Use Puma as the app server"
GemfileEntry.new("puma", "~> 3.11", comment)
diff --git a/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt
index f6146e7259..649253aeca 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt
@@ -17,7 +17,7 @@ port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode.
-# Workers are forked webserver processes. If using threads and workers together
+# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake
index 8cacf4a49f..5abba7d3b4 100644
--- a/railties/lib/rails/tasks/statistics.rake
+++ b/railties/lib/rails/tasks/statistics.rake
@@ -9,6 +9,7 @@ STATS_DIRECTORIES = [
%w(Jobs app/jobs),
%w(Models app/models),
%w(Mailers app/mailers),
+ %w(Mailboxes app/mailboxes),
%w(Channels app/channels),
%w(JavaScripts app/assets/javascripts),
%w(JavaScript app/javascript),
@@ -18,6 +19,8 @@ STATS_DIRECTORIES = [
%w(Helper\ tests test/helpers),
%w(Model\ tests test/models),
%w(Mailer\ tests test/mailers),
+ %w(Mailbox\ tests test/mailboxes),
+ %w(Channel\ tests test/channels),
%w(Job\ tests test/jobs),
%w(Integration\ tests test/integration),
%w(System\ tests test/system),
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 830c36671c..44e3b0f66b 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -118,7 +118,7 @@ module ApplicationTests
end
def test_code_statistics_sanity
- assert_match "Code LOC: 29 Test LOC: 0 Code to Test Ratio: 1:0.0",
+ assert_match "Code LOC: 32 Test LOC: 0 Code to Test Ratio: 1:0.0",
rails("stats")
end