mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
4838c1716a
* Use Webpacker by default on new apps * Stop including coffee-rails by default * Drop using a js_compressor by default * Drop extra test for coffeescript inclusion by default * Stick with skip_javascript to signify skipping webpack * Don't install a JS runtime by default any more * app/javascript will be the new default directory for JS * Make it clear that this is just for configuring the default Webpack framework setup now * Start using the Webpack tag in the default layout * Irrelevant test * jQuery is long gone * Stop having asset pipeline compile default application.js * Add rails-ujs by default to the Webpack setup * Add Active Storage JavaScript to application.js pack by default * Consistent quoting * Add Turbolinks to default pack * Add Action Cable to default pack Need some work on how to set the global consumer that channels will work with. @javan? * Require all channels by default and use a separate consumer stub * Channel generator now targets Webpack style * Update task docs to match new generator style * Use uniform import style * Drop the JS assets generator It was barely helpful as it was. It’s no longer helpful in a Webpacked world. Sayonara! * Add app/javascript to the stats directories * Simpler import style Which match the other imports. * Address test failures from dropping JS compilation (and compression) * webpacker-default: Modify `AssetsGeneratorTest` Before: ``` $ bin/test test/generators/assets_generator_test.rb Run options: --seed 46201 F Failure: AssetsGeneratorTest#test_assets [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/assets_generator_test.rb:12]: Expected file "app/assets/javascripts/posts.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/assets_generator_test.rb:10 . Finished in 0.031343s, 63.8101 runs/s, 95.7152 assertions/s. 2 runs, 3 assertions, 1 failures, 0 errors, 0 skips ``` After: ``` $ bin/test test/generators/assets_generator_test.rb Run options: --seed 43571 .. Finished in 0.030370s, 65.8545 runs/s, 65.8545 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips ``` * webpacker-default: Modify `ChannelGeneratorTest` Before: ``` $ bin/test test/generators/channel_generator_test.rb Run options: --seed 8986 .F Failure: ChannelGeneratorTest#test_channel_with_multiple_actions_is_created [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:43]: Expected file "app/assets/javascripts/channels/chat.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:34 .F Failure: ChannelGeneratorTest#test_channel_is_created [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:29]: Expected file "app/assets/javascripts/channels/chat.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:22 E Error: ChannelGeneratorTest#test_cable_js_is_created_if_not_present_already: Errno::ENOENT: No such file or directory @ apply2files - /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/fixtures/tmp/app/assets/javascripts/cable.js bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:60 F Failure: ChannelGeneratorTest#test_channel_suffix_is_not_duplicated [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:87]: Expected file "app/assets/javascripts/channels/chat.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:80 F Failure: ChannelGeneratorTest#test_channel_on_revoke [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:77]: Expected file "app/assets/javascripts/cable.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:68 Finished in 0.064384s, 108.7227 runs/s, 481.4861 assertions/s. 7 runs, 31 assertions, 4 failures, 1 errors, 0 skips ``` After: ``` $ bin/test test/generators/channel_generator_test.rb Run options: --seed 44857 ....... Finished in 0.060243s, 116.1961 runs/s, 697.1764 assertions/s. 7 runs, 42 assertions, 0 failures, 0 errors, 0 skips ``` * Fix shared generator tests. * webpacker-default: Modify `ControllerGeneratorTest` The JS assets generator was dropped. ref.46215b1794
* Revert "Simpler import style". It's currently failing with an error of "TypeError: undefined is not an object (evaluating '__WEBPACK_IMPORTED_MODULE_2_activestorage___default.a.start')". Waiting for @javan to have a look. This reverts commit5d3ebb7105
. * require webpacker in test app * Add webpacker without making the build hang/timeout. (#33640) * use yarn workspaces to allow for installing unreleased packages and only generate js/bootsnap when required * no longer need to have webpacker in env templates as webpacker moved this config to yml file * Fix rubocop violation * Got the test passing for the running scaffold * update expected lines of code * update middleware tests to account for webpacker * disable js in plugins be default to get the tests passing (#34009) * clear codeclimate report issues * Anything newer than currently released is good * Use Webpacker development version during development of Rails * Edge should get development webpacker as well * Add changelog entry for Webpacker change
317 lines
10 KiB
Ruby
317 lines
10 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "isolation/abstract_unit"
|
|
|
|
module ApplicationTests
|
|
class MiddlewareTest < ActiveSupport::TestCase
|
|
include ActiveSupport::Testing::Isolation
|
|
|
|
def setup
|
|
build_app
|
|
FileUtils.rm_rf "#{app_path}/config/environments"
|
|
end
|
|
|
|
def teardown
|
|
teardown_app
|
|
end
|
|
|
|
def app
|
|
@app ||= Rails.application
|
|
end
|
|
|
|
test "default middleware stack" do
|
|
add_to_config "config.active_record.migration_error = :page_load"
|
|
|
|
boot!
|
|
|
|
assert_equal [
|
|
"Webpacker::DevServerProxy",
|
|
"Rack::Sendfile",
|
|
"ActionDispatch::Static",
|
|
"ActionDispatch::Executor",
|
|
"ActiveSupport::Cache::Strategy::LocalCache",
|
|
"Rack::Runtime",
|
|
"Rack::MethodOverride",
|
|
"ActionDispatch::RequestId",
|
|
"ActionDispatch::RemoteIp",
|
|
"Rails::Rack::Logger",
|
|
"ActionDispatch::ShowExceptions",
|
|
"ActionDispatch::DebugExceptions",
|
|
"ActionDispatch::Reloader",
|
|
"ActionDispatch::Callbacks",
|
|
"ActiveRecord::Migration::CheckPending",
|
|
"ActionDispatch::Cookies",
|
|
"ActionDispatch::Session::CookieStore",
|
|
"ActionDispatch::Flash",
|
|
"ActionDispatch::ContentSecurityPolicy::Middleware",
|
|
"Rack::Head",
|
|
"Rack::ConditionalGet",
|
|
"Rack::ETag",
|
|
"Rack::TempfileReaper"
|
|
], middleware
|
|
end
|
|
|
|
test "api middleware stack" do
|
|
add_to_config "config.api_only = true"
|
|
|
|
boot!
|
|
|
|
assert_equal [
|
|
"Webpacker::DevServerProxy",
|
|
"Rack::Sendfile",
|
|
"ActionDispatch::Static",
|
|
"ActionDispatch::Executor",
|
|
"ActiveSupport::Cache::Strategy::LocalCache",
|
|
"Rack::Runtime",
|
|
"ActionDispatch::RequestId",
|
|
"ActionDispatch::RemoteIp",
|
|
"Rails::Rack::Logger",
|
|
"ActionDispatch::ShowExceptions",
|
|
"ActionDispatch::DebugExceptions",
|
|
"ActionDispatch::Reloader",
|
|
"ActionDispatch::Callbacks",
|
|
"Rack::Head",
|
|
"Rack::ConditionalGet",
|
|
"Rack::ETag"
|
|
], middleware
|
|
end
|
|
|
|
test "middleware dependencies" do
|
|
boot!
|
|
|
|
# The following array-of-arrays describes dependencies between
|
|
# middlewares: the first item in each list depends on the
|
|
# remaining items (and therefore must occur later in the
|
|
# middleware stack).
|
|
|
|
dependencies = [
|
|
# Logger needs a fully "corrected" request environment
|
|
%w(Rails::Rack::Logger Rack::MethodOverride ActionDispatch::RequestId ActionDispatch::RemoteIp),
|
|
|
|
# Serving public/ doesn't invoke user code, so it should skip
|
|
# locks etc
|
|
%w(ActionDispatch::Executor ActionDispatch::Static),
|
|
|
|
# Errors during reload must be reported
|
|
%w(ActionDispatch::Reloader ActionDispatch::ShowExceptions ActionDispatch::DebugExceptions),
|
|
|
|
# Outright dependencies
|
|
%w(ActionDispatch::Static Rack::Sendfile),
|
|
%w(ActionDispatch::Flash ActionDispatch::Session::CookieStore),
|
|
%w(ActionDispatch::Session::CookieStore ActionDispatch::Cookies),
|
|
]
|
|
|
|
require "tsort"
|
|
sorted = TSort.tsort((middleware | dependencies.flatten).method(:each),
|
|
lambda { |n, &b| dependencies.each { |m, *ds| ds.each(&b) if m == n } })
|
|
assert_equal sorted, middleware
|
|
end
|
|
|
|
test "Rack::Cache is not included by default" do
|
|
boot!
|
|
|
|
assert_not_includes middleware, "Rack::Cache", "Rack::Cache is not included in the default stack unless you set config.action_dispatch.rack_cache"
|
|
end
|
|
|
|
test "Rack::Cache is present when action_dispatch.rack_cache is set" do
|
|
add_to_config "config.action_dispatch.rack_cache = true"
|
|
|
|
boot!
|
|
|
|
assert_includes middleware, "Rack::Cache"
|
|
end
|
|
|
|
test "ActiveRecord::Migration::CheckPending is present when active_record.migration_error is set to :page_load" do
|
|
add_to_config "config.active_record.migration_error = :page_load"
|
|
|
|
boot!
|
|
|
|
assert_includes middleware, "ActiveRecord::Migration::CheckPending"
|
|
end
|
|
|
|
test "ActionDispatch::SSL is present when force_ssl is set" do
|
|
add_to_config "config.force_ssl = true"
|
|
boot!
|
|
assert_includes middleware, "ActionDispatch::SSL"
|
|
end
|
|
|
|
test "ActionDispatch::SSL is configured with options when given" do
|
|
add_to_config "config.force_ssl = true"
|
|
add_to_config "config.ssl_options = { redirect: { host: 'example.com' } }"
|
|
boot!
|
|
|
|
assert_equal [{ redirect: { host: "example.com" } }], Rails.application.middleware[1].args
|
|
end
|
|
|
|
test "removing Active Record omits its middleware" do
|
|
use_frameworks []
|
|
boot!
|
|
assert_not_includes middleware, "ActiveRecord::Migration::CheckPending"
|
|
end
|
|
|
|
test "includes executor" do
|
|
boot!
|
|
assert_includes middleware, "ActionDispatch::Executor"
|
|
end
|
|
|
|
test "does not include lock if cache_classes is set and so is eager_load" do
|
|
add_to_config "config.cache_classes = true"
|
|
add_to_config "config.eager_load = true"
|
|
boot!
|
|
assert_not_includes middleware, "Rack::Lock"
|
|
end
|
|
|
|
test "does not include lock if allow_concurrency is set to :unsafe" do
|
|
add_to_config "config.allow_concurrency = :unsafe"
|
|
boot!
|
|
assert_not_includes middleware, "Rack::Lock"
|
|
end
|
|
|
|
test "includes lock if allow_concurrency is disabled" do
|
|
add_to_config "config.allow_concurrency = false"
|
|
boot!
|
|
assert_includes middleware, "Rack::Lock"
|
|
end
|
|
|
|
test "removes static asset server if public_file_server.enabled is disabled" do
|
|
add_to_config "config.public_file_server.enabled = false"
|
|
boot!
|
|
assert_not_includes middleware, "ActionDispatch::Static"
|
|
end
|
|
|
|
test "can delete a middleware from the stack" do
|
|
add_to_config "config.middleware.delete ActionDispatch::Static"
|
|
boot!
|
|
assert_not_includes middleware, "ActionDispatch::Static"
|
|
end
|
|
|
|
test "can delete a middleware from the stack even if insert_before is added after delete" do
|
|
add_to_config "config.middleware.delete Rack::Runtime"
|
|
add_to_config "config.middleware.insert_before(Rack::Runtime, Rack::Config)"
|
|
boot!
|
|
assert_includes middleware, "Rack::Config"
|
|
assert_not middleware.include?("Rack::Runtime")
|
|
end
|
|
|
|
test "can delete a middleware from the stack even if insert_after is added after delete" do
|
|
add_to_config "config.middleware.delete Rack::Runtime"
|
|
add_to_config "config.middleware.insert_after(Rack::Runtime, Rack::Config)"
|
|
boot!
|
|
assert_includes middleware, "Rack::Config"
|
|
assert_not middleware.include?("Rack::Runtime")
|
|
end
|
|
|
|
test "includes exceptions middlewares even if action_dispatch.show_exceptions is disabled" do
|
|
add_to_config "config.action_dispatch.show_exceptions = false"
|
|
boot!
|
|
assert_includes middleware, "ActionDispatch::ShowExceptions"
|
|
assert_includes middleware, "ActionDispatch::DebugExceptions"
|
|
end
|
|
|
|
test "removes ActionDispatch::Reloader if cache_classes is true" do
|
|
add_to_config "config.cache_classes = true"
|
|
boot!
|
|
assert_not_includes middleware, "ActionDispatch::Reloader"
|
|
end
|
|
|
|
test "use middleware" do
|
|
use_frameworks []
|
|
add_to_config "config.middleware.use Rack::Config"
|
|
boot!
|
|
assert_equal "Rack::Config", middleware.last
|
|
end
|
|
|
|
test "insert middleware after" do
|
|
add_to_config "config.middleware.insert_after Rack::Sendfile, Rack::Config"
|
|
boot!
|
|
assert_equal "Rack::Config", middleware.third
|
|
end
|
|
|
|
test "unshift middleware" do
|
|
add_to_config "config.middleware.unshift Rack::Config"
|
|
boot!
|
|
assert_equal "Rack::Config", middleware.second
|
|
end
|
|
|
|
test "Rails.cache does not respond to middleware" do
|
|
add_to_config "config.cache_store = :memory_store"
|
|
boot!
|
|
assert_equal "Rack::Runtime", middleware.fifth
|
|
end
|
|
|
|
test "Rails.cache does respond to middleware" do
|
|
boot!
|
|
assert_equal "ActiveSupport::Cache::Strategy::LocalCache", middleware.fifth
|
|
assert_equal "Rack::Runtime", middleware[5]
|
|
end
|
|
|
|
test "insert middleware before" do
|
|
add_to_config "config.middleware.insert_before Rack::Sendfile, Rack::Config"
|
|
boot!
|
|
assert_equal "Rack::Config", middleware.second
|
|
end
|
|
|
|
test "can't change middleware after it's built" do
|
|
boot!
|
|
assert_raise frozen_error_class do
|
|
app.config.middleware.use Rack::Config
|
|
end
|
|
end
|
|
|
|
# ConditionalGet + Etag
|
|
test "conditional get + etag middlewares handle http caching based on body" do
|
|
make_basic_app
|
|
|
|
class ::OmgController < ActionController::Base
|
|
def index
|
|
if params[:nothing]
|
|
render plain: ""
|
|
else
|
|
render plain: "OMG"
|
|
end
|
|
end
|
|
end
|
|
|
|
etag = "W/" + "c00862d1c6c1cf7c1b49388306e7b3c1".inspect
|
|
|
|
get "/"
|
|
assert_equal 200, last_response.status
|
|
assert_equal "OMG", last_response.body
|
|
assert_equal "text/plain; charset=utf-8", last_response.headers["Content-Type"]
|
|
assert_equal "max-age=0, private, must-revalidate", last_response.headers["Cache-Control"]
|
|
assert_equal etag, last_response.headers["Etag"]
|
|
|
|
get "/", {}, { "HTTP_IF_NONE_MATCH" => etag }
|
|
assert_equal 304, last_response.status
|
|
assert_equal "", last_response.body
|
|
assert_nil last_response.headers["Content-Type"]
|
|
assert_equal "max-age=0, private, must-revalidate", last_response.headers["Cache-Control"]
|
|
assert_equal etag, last_response.headers["Etag"]
|
|
|
|
get "/?nothing=true"
|
|
assert_equal 200, last_response.status
|
|
assert_equal "", last_response.body
|
|
assert_equal "text/plain; charset=utf-8", last_response.headers["Content-Type"]
|
|
assert_equal "no-cache", last_response.headers["Cache-Control"]
|
|
assert_nil last_response.headers["Etag"]
|
|
end
|
|
|
|
test "ORIGINAL_FULLPATH is passed to env" do
|
|
boot!
|
|
env = ::Rack::MockRequest.env_for("/foo/?something")
|
|
Rails.application.call(env)
|
|
|
|
assert_equal "/foo/?something", env["ORIGINAL_FULLPATH"]
|
|
end
|
|
|
|
private
|
|
|
|
def boot!
|
|
require "#{app_path}/config/environment"
|
|
end
|
|
|
|
def middleware
|
|
Rails.application.middleware.map(&:klass).map(&:name)
|
|
end
|
|
end
|
|
end
|