railties 8.0.3 → 8.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +103 -205
  3. data/lib/minitest/rails_plugin.rb +48 -12
  4. data/lib/rails/application/bootstrap.rb +5 -0
  5. data/lib/rails/application/configuration.rb +31 -9
  6. data/lib/rails/application/default_middleware_stack.rb +1 -1
  7. data/lib/rails/application/finisher.rb +2 -1
  8. data/lib/rails/application/routes_reloader.rb +0 -1
  9. data/lib/rails/application.rb +1 -3
  10. data/lib/rails/code_statistics.rb +4 -1
  11. data/lib/rails/command/base.rb +0 -2
  12. data/lib/rails/command/environment_argument.rb +0 -1
  13. data/lib/rails/command.rb +1 -1
  14. data/lib/rails/commands/app/update_command.rb +1 -0
  15. data/lib/rails/commands/console/irb_console.rb +4 -4
  16. data/lib/rails/commands/credentials/credentials_command.rb +25 -5
  17. data/lib/rails/commands/encrypted/encrypted_command.rb +0 -1
  18. data/lib/rails/engine.rb +0 -1
  19. data/lib/rails/gem_version.rb +3 -3
  20. data/lib/rails/generators/actions.rb +2 -3
  21. data/lib/rails/generators/app_base.rb +49 -28
  22. data/lib/rails/generators/database.rb +1 -1
  23. data/lib/rails/generators/erb/authentication/authentication_generator.rb +2 -0
  24. data/lib/rails/generators/erb/scaffold/templates/partial.html.erb.tt +2 -2
  25. data/lib/rails/generators/generated_attribute.rb +1 -1
  26. data/lib/rails/generators/migration.rb +0 -1
  27. data/lib/rails/generators/rails/app/app_generator.rb +16 -5
  28. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +19 -15
  29. data/lib/rails/generators/rails/app/templates/Gemfile.tt +6 -1
  30. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +5 -0
  31. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -0
  32. data/lib/rails/generators/rails/app/templates/bin/bundler-audit.tt +5 -0
  33. data/lib/rails/generators/rails/app/templates/bin/ci.tt +5 -0
  34. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +1 -1
  35. data/lib/rails/generators/rails/app/templates/bin/setup.tt +1 -0
  36. data/lib/rails/generators/rails/app/templates/config/bundler-audit.yml.tt +5 -0
  37. data/lib/rails/generators/rails/app/templates/config/ci.rb.tt +38 -0
  38. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +9 -1
  39. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +10 -2
  40. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
  41. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +9 -1
  42. data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +8 -5
  43. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +8 -0
  44. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +2 -2
  45. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +4 -0
  46. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_1.rb.tt +93 -0
  47. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +3 -2
  48. data/lib/rails/generators/rails/app/templates/config/storage.yml.tt +0 -7
  49. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +0 -6
  50. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +107 -21
  51. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +2 -2
  52. data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +3 -0
  53. data/lib/rails/generators/rails/app/templates/public/400.html +1 -1
  54. data/lib/rails/generators/rails/app/templates/public/404.html +2 -2
  55. data/lib/rails/generators/rails/app/templates/public/422.html +1 -1
  56. data/lib/rails/generators/rails/app/templates/public/500.html +2 -2
  57. data/lib/rails/generators/rails/authentication/authentication_generator.rb +8 -6
  58. data/lib/rails/generators/rails/authentication/templates/app/controllers/passwords_controller.rb.tt +6 -0
  59. data/lib/rails/generators/rails/authentication/templates/app/controllers/sessions_controller.rb.tt +2 -2
  60. data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.html.erb.tt +3 -1
  61. data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.text.erb.tt +3 -1
  62. data/lib/rails/generators/rails/benchmark/USAGE +1 -1
  63. data/lib/rails/generators/rails/benchmark/templates/benchmark.rb.tt +0 -2
  64. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +1 -1
  65. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +4 -0
  66. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +2 -2
  67. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
  68. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +17 -5
  69. data/lib/rails/generators/rails/master_key/master_key_generator.rb +0 -12
  70. data/lib/rails/generators/rails/plugin/plugin_generator.rb +1 -0
  71. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +0 -4
  72. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +20 -9
  73. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +2 -2
  74. data/lib/rails/generators/rails/script/USAGE +1 -1
  75. data/lib/rails/generators/test_unit/authentication/authentication_generator.rb +13 -0
  76. data/lib/rails/generators/test_unit/authentication/templates/test/controllers/passwords_controller_test.rb.tt +67 -0
  77. data/lib/rails/generators/test_unit/authentication/templates/test/controllers/sessions_controller_test.rb +33 -0
  78. data/lib/rails/generators/test_unit/authentication/templates/test/models/user_test.rb.tt +4 -3
  79. data/lib/rails/generators/test_unit/authentication/templates/test/test_helpers/session_test_helper.rb.tt +19 -0
  80. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +1 -1
  81. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +4 -2
  82. data/lib/rails/generators/testing/behavior.rb +0 -3
  83. data/lib/rails/generators.rb +3 -1
  84. data/lib/rails/health_controller.rb +8 -2
  85. data/lib/rails/info.rb +4 -5
  86. data/lib/rails/info_controller.rb +4 -5
  87. data/lib/rails/initializable.rb +63 -19
  88. data/lib/rails/rack/silence_request.rb +5 -2
  89. data/lib/rails/railtie/configurable.rb +0 -1
  90. data/lib/rails/railtie.rb +0 -1
  91. data/lib/rails/tasks/statistics.rake +3 -21
  92. data/lib/rails/tasks.rb +1 -3
  93. data/lib/rails/templates/rails/info/notes.html.erb +23 -0
  94. data/lib/rails/templates/rails/mailers/email.html.erb +2 -1
  95. data/lib/rails/templates/rails/welcome/index.html.erb +19 -3
  96. data/lib/rails/test_unit/reporter.rb +5 -4
  97. data/lib/rails/test_unit/runner.rb +8 -5
  98. data/lib/rails.rb +9 -2
  99. metadata +18 -15
  100. data/lib/rails/console/methods.rb +0 -7
  101. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +0 -30
  102. data/lib/rails/generators/test_unit/plugin/plugin_generator.rb +0 -15
  103. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +0 -7
  104. data/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +0 -2
@@ -105,7 +105,7 @@
105
105
  <svg height="172" viewBox="0 0 480 172" width="480" xmlns="http://www.w3.org/2000/svg"><path d="m124.48 3.00509-45.6889 100.02991h26.2239v-28.1168h38.119v28.1168h21.628v35.145h-21.628v30.82h-37.308v-30.82h-72.1833v-31.901l50.2851-103.27391zm130.453 51.63681c0-8.9215-6.218-15.4099-15.681-15.4099-10.273 0-15.95 7.5698-16.491 16.4913h-44.608c3.244-30.8199 25.683-55.421707 61.099-55.421707 36.498 0 59.477 20.816907 59.477 51.636807 0 21.3577-14.869 36.7676-31.901 52.7186l-27.305 27.035h59.747v37.308h-120.306v-27.846l57.044-56.7736c11.084-11.8954 18.925-20.0059 18.925-29.7385zm140.455 0c0-8.9215-6.218-15.4099-15.68-15.4099-10.274 0-15.951 7.5698-16.492 16.4913h-44.608c3.245-30.8199 25.684-55.421707 61.1-55.421707 36.497 0 59.477 20.816907 59.477 51.636807 0 21.3577-14.87 36.7676-31.902 52.7186l-27.305 27.035h59.747v37.308h-120.305v-27.846l57.043-56.7736c11.085-11.8954 18.925-20.0059 18.925-29.7385z" fill="#f0eff0"/><path d="m19.3936 103.554c-8.9715 0-14.84183-5.0952-14.84183-14.4544v-20.1029h8.86083v19.3276c0 4.8181 2.2706 7.3102 5.981 7.3102 3.6551 0 5.9257-2.4921 5.9257-7.3102v-19.3276h8.8608v20.1583c0 9.3038-5.8149 14.399-14.7865 14.399zm18.734-.554v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm36.8584-1.994v10.799h-8.6946v-33.726h8.6946v1.9937c1.163-1.3291 3.5997-2.5475 6.1472-2.5475 7.1994 0 11.1314 5.8703 11.1314 13.0143 0 7.0886-3.932 13.0145-11.1314 13.0145-2.5475 0-4.9842-1.219-6.1472-2.548zm0-13.7893v6.5902c.6646 1.3845 2.1599 2.326 3.8213 2.326 2.9905 0 4.7626-2.3814 4.7626-5.5934s-1.7721-5.6488-4.7626-5.6488c-1.7168 0-3.1567.9969-3.8213 2.326zm36.789-9.2485v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.6949v-24.921h8.6949v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.528 0c0-3.4336-1.496-5.8703-4.209-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.209-2.3813 4.209-5.8149zm10.352 0c0-7.6978 5.095-13.0143 12.571-13.0143 6.701 0 10.855 3.9874 11.574 9.8023h-8.417c-.222-1.4953-1.385-2.6029-3.157-2.6029-2.437 0-3.987 2.2706-3.987 5.8149s1.55 5.7595 3.987 5.7595c1.772 0 2.935-1.0522 3.157-2.5475h8.417c-.719 5.7596-4.873 9.8025-11.574 9.8025-7.476 0-12.571-5.3167-12.571-13.0145zm42.013 3.7658h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.156-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.544-3.5997zm13.428 11.0206h8.473c.387 1.3845 1.606 2.1598 3.156 2.1598 1.44 0 2.548-.5538 2.548-1.7168 0-.9414-.72-1.2737-1.938-1.5506l-4.874-.9969c-4.153-.886-6.867-2.8797-6.867-7.2547 0-5.3165 4.763-8.4178 10.633-8.4178 6.812 0 10.522 3.1567 11.297 8.0855h-8.03c-.277-1.0522-1.052-1.9937-3.046-1.9937-1.273 0-2.326.5538-2.326 1.6614 0 .7753.554 1.163 1.717 1.3845l4.929 1.163c4.541 1.0522 6.978 3.4335 6.978 7.4763 0 5.3168-4.818 8.2518-10.91 8.2518-6.369 0-10.965-2.88-11.74-8.2518zm24.269 0h8.474c.387 1.3845 1.606 2.1598 3.156 2.1598 1.44 0 2.548-.5538 2.548-1.7168 0-.9414-.72-1.2737-1.939-1.5506l-4.873-.9969c-4.154-.886-6.867-2.8797-6.867-7.2547 0-5.3165 4.763-8.4178 10.633-8.4178 6.812 0 10.522 3.1567 11.297 8.0855h-8.03c-.277-1.0522-1.052-1.9937-3.046-1.9937-1.273 0-2.326.5538-2.326 1.6614 0 .7753.554 1.163 1.717 1.3845l4.929 1.163c4.541 1.0522 6.978 3.4335 6.978 7.4763 0 5.3168-4.818 8.2518-10.91 8.2518-6.369 0-10.965-2.88-11.741-8.2518zm47.918 7.6978h-8.363v-1.274c-.831.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.434.7199-3.434 2.3813 0 1.7168 1.717 2.4367 3.434 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742 4.9839v1.994h-8.695v-35.997h8.695v13.0697c1.163-1.3291 3.6-2.5475 6.147-2.5475 7.2 0 11.132 5.8149 11.132 13.0143s-3.932 13.0145-11.132 13.0145c-2.547 0-4.984-1.219-6.147-2.548zm0-13.7893v6.5902c.665 1.3845 2.105 2.326 3.821 2.326 2.991 0 4.763-2.3814 4.763-5.5934s-1.772-5.6488-4.763-5.6488c-1.661 0-3.156.9969-3.821 2.326zm28.759-20.2137v35.997h-8.695v-35.997zm19.172 27.3023h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.515-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.32 4.5965 1.772 0 3.156-.7753 3.655-2.4921zm-3.822-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm25.461-15.2849h24.311v7.6424h-15.561v5.3165h14.232v7.4763h-14.232v5.8703h15.561v7.6978h-24.311zm27.942 34.0033v-24.921h8.694v2.1598c1.385-1.5506 3.822-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.639v-14.2327c0-2.049-1.053-3.5443-3.268-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm29.991-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.206v6.7564h-5.206v8.307c0 1.9383.941 2.769 2.658 2.769.942 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm26.161-16.3371v24.921h-8.694v-24.921zm.61-6.7564c0 2.8244-2.271 4.652-4.929 4.652s-4.929-1.8276-4.929-4.652c0-2.8797 2.271-4.7073 4.929-4.7073s4.929 1.8276 4.929 4.7073zm5.382 23.0935v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.206v6.7564h-5.206v8.307c0 1.9383.941 2.769 2.658 2.769.941 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm29.22 17.3889h-8.584l3.655-9.414-9.303-24.312h9.026l4.763 14.1773 4.652-14.1773h8.639z" fill="#d30001"/></svg>
106
106
  </header>
107
107
  <article>
108
- <p><strong>The change you wanted was rejected.</strong> Maybe you tried to change something you didnt have access to. If youre the application owner check the logs for more information.</p>
108
+ <p><strong>The change you wanted was rejected.</strong> Maybe you tried to change something you didn't have access to. If you're the application owner check the logs for more information.</p>
109
109
  </article>
110
110
  </main>
111
111
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  <head>
6
6
 
7
- <title>Were sorry, but something went wrong (500 Internal Server Error)</title>
7
+ <title>We're sorry, but something went wrong (500 Internal Server Error)</title>
8
8
 
9
9
  <meta charset="utf-8">
10
10
  <meta name="viewport" content="initial-scale=1, width=device-width">
@@ -105,7 +105,7 @@
105
105
  <svg height="172" viewBox="0 0 480 172" width="480" xmlns="http://www.w3.org/2000/svg"><path d="m101.23 93.8427c-8.1103 0-15.4098 3.7849-19.7354 8.3813h-36.2269v-99.21891h103.8143v37.03791h-68.3984v24.8722c5.1366-2.7035 15.1396-5.9477 24.6014-5.9477 35.146 0 56.233 22.7094 56.233 55.4215 0 34.605-23.791 57.315-60.558 57.315-37.8492 0-61.64-22.169-63.8028-55.963h42.9857c1.0814 10.814 9.1919 19.195 21.6281 19.195 11.355 0 19.465-8.381 19.465-20.547 0-11.625-7.299-20.5463-20.006-20.5463zm138.833 77.8613c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm140.456 133.2831c-40.823 0-64.884-35.146-64.884-85.7015 0-50.5554 24.061-85.700907 64.884-85.700907 40.822 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.062 85.7015-64.884 85.7015zm0-133.2831c-17.573 0-22.71 21.8984-22.71 47.5816 0 25.6835 5.137 47.5815 22.71 47.5815 17.302 0 22.709-21.898 22.709-47.5815 0-25.6832-5.407-47.5816-22.709-47.5816z" fill="#f0eff0"/><path d="m23.1377 68.9967v34.0033h-8.9162v-34.0033zm4.3157 34.0033v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm29.9913-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.5839v6.8671h5.2058v6.7564h-5.2058v8.307c0 1.9383.9415 2.769 2.6583 2.769.9414 0 1.9937-.2216 2.769-.5538v7.3654c-.9969.443-2.8798.775-4.8181.775-5.8703 0-9.1931-2.769-9.1931-9.0819zm32.3666-.1108h8.0301c-.8861 5.7597-5.2057 9.2487-11.6852 9.2487-7.6424 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.3165-13.0143 12.5159-13.0143 7.6424 0 11.9621 5.095 11.9621 12.5159v2.1598h-16.1156c.2769 2.9905 1.8275 4.5965 4.3196 4.5965 1.7722 0 3.1567-.7753 3.6551-2.4921zm-3.8212-10.0237c-2.0491 0-3.4336 1.2737-3.9874 3.5997h7.5317c-.1107-2.0491-1.3845-3.5997-3.5443-3.5997zm31.4299-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.599-.7753-2.382 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.381.443zm2.949 25.0318v-24.921h8.694v2.1598c1.385-1.5506 3.821-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.64v-14.2327c0-2.049-1.052-3.5443-3.267-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm50.371 0h-8.363v-1.274c-.83.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.433.7199-3.433 2.3813 0 1.7168 1.716 2.4367 3.433 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742-29.0191v35.997h-8.694v-35.997zm13.036 25.9178h9.248c.72 2.326 2.714 3.489 5.483 3.489 2.713 0 4.596-1.163 4.596-3.2674 0-1.6061-1.052-2.326-3.212-2.8244l-6.534-1.3845c-4.985-1.1076-8.751-3.7105-8.751-9.47 0-6.6456 5.538-11.0206 13.07-11.0206 8.307 0 13.014 4.5411 13.956 10.4114h-8.695c-.72-1.8829-2.27-3.3228-5.205-3.3228-2.548 0-4.265 1.1076-4.265 2.9905 0 1.4953 1.052 2.326 2.825 2.7137l6.645 1.5506c5.815 1.3845 9.027 4.5412 9.027 9.8023 0 6.9778-5.87 10.9654-13.291 10.9654-8.141 0-13.679-3.9322-14.897-10.6332zm46.509 1.3845h8.031c-.887 5.7597-5.206 9.2487-11.686 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.317-13.0143 12.516-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.319 4.5965 1.773 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm31.431-6.3134v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.382.443zm18.288 25.0318h-7.809l-9.47-24.921h8.861l4.763 14.288 4.652-14.288h8.528zm25.614-8.6947h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.384-3.5997-3.544-3.5997zm31.43-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443zm13.703-8.9715h24.312v7.6424h-15.562v5.3165h14.232v7.4763h-14.232v5.8703h15.562v7.6978h-24.312zm44.667 8.9715v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm19.673 0v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm28.082-12.5713v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443z" fill="#d30001"/></svg>
106
106
  </header>
107
107
  <article>
108
- <p><strong>Were sorry, but something went wrong.</strong><br> If youre the application owner check the logs for more information.</p>
108
+ <p><strong>We're sorry, but something went wrong.</strong><br> If you're the application owner check the logs for more information.</p>
109
109
  </article>
110
110
  </main>
111
111
 
@@ -25,10 +25,12 @@ module Rails
25
25
 
26
26
  template "app/channels/application_cable/connection.rb" if defined?(ActionCable::Engine)
27
27
 
28
- template "app/mailers/passwords_mailer.rb"
28
+ if defined?(ActionMailer::Railtie)
29
+ template "app/mailers/passwords_mailer.rb"
29
30
 
30
- template "app/views/passwords_mailer/reset.html.erb"
31
- template "app/views/passwords_mailer/reset.text.erb"
31
+ template "app/views/passwords_mailer/reset.html.erb"
32
+ template "app/views/passwords_mailer/reset.text.erb"
33
+ end
32
34
  end
33
35
 
34
36
  def configure_application_controller
@@ -41,7 +43,7 @@ module Rails
41
43
  end
42
44
 
43
45
  def enable_bcrypt
44
- if File.read("Gemfile").include?('gem "bcrypt"')
46
+ if File.read(File.expand_path("Gemfile", destination_root)).include?('gem "bcrypt"')
45
47
  uncomment_lines "Gemfile", /gem "bcrypt"/
46
48
  bundle_command("install --quiet")
47
49
  else
@@ -50,8 +52,8 @@ module Rails
50
52
  end
51
53
 
52
54
  def add_migrations
53
- generate "migration CreateUsers email_address:string!:uniq password_digest:string! --force"
54
- generate "migration CreateSessions user:references ip_address:string user_agent:string --force"
55
+ generate "migration", "CreateUsers", "email_address:string!:uniq password_digest:string!", "--force"
56
+ generate "migration", "CreateSessions", "user:references ip_address:string user_agent:string", "--force"
55
57
  end
56
58
 
57
59
  hook_for :test_framework
@@ -1,9 +1,13 @@
1
1
  class PasswordsController < ApplicationController
2
2
  allow_unauthenticated_access
3
3
  before_action :set_user_by_token, only: %i[ edit update ]
4
+ <%- if defined?(ActionMailer::Railtie) -%>
5
+ rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_password_path, alert: "Try again later." }
6
+ <%- end -%>
4
7
 
5
8
  def new
6
9
  end
10
+ <%- if defined?(ActionMailer::Railtie) -%>
7
11
 
8
12
  def create
9
13
  if user = User.find_by(email_address: params[:email_address])
@@ -12,12 +16,14 @@ class PasswordsController < ApplicationController
12
16
 
13
17
  redirect_to new_session_path, notice: "Password reset instructions sent (if user with that email address exists)."
14
18
  end
19
+ <%- end -%>
15
20
 
16
21
  def edit
17
22
  end
18
23
 
19
24
  def update
20
25
  if @user.update(params.permit(:password, :password_confirmation))
26
+ @user.sessions.destroy_all
21
27
  redirect_to new_session_path, notice: "Password has been reset."
22
28
  else
23
29
  redirect_to edit_password_path(params[:token]), alert: "Passwords did not match."
@@ -1,6 +1,6 @@
1
1
  class SessionsController < ApplicationController
2
2
  allow_unauthenticated_access only: %i[ new create ]
3
- rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_url, alert: "Try again later." }
3
+ rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_path, alert: "Try again later." }
4
4
 
5
5
  def new
6
6
  end
@@ -16,6 +16,6 @@ class SessionsController < ApplicationController
16
16
 
17
17
  def destroy
18
18
  terminate_session
19
- redirect_to new_session_path
19
+ redirect_to new_session_path, status: :see_other
20
20
  end
21
21
  end
@@ -1,4 +1,6 @@
1
1
  <p>
2
- You can reset your password within the next 15 minutes on
2
+ You can reset your password on
3
3
  <%%= link_to "this password reset page", edit_password_url(@user.password_reset_token) %>.
4
+
5
+ This link will expire in <%%= distance_of_time_in_words(0, @user.password_reset_token_expires_in) %>.
4
6
  </p>
@@ -1,2 +1,4 @@
1
- You can reset your password within the next 15 minutes on this password reset page:
1
+ You can reset your password on
2
2
  <%%= edit_password_url(@user.password_reset_token) %>
3
+
4
+ This link will expire in <%%= distance_of_time_in_words(0, @user.password_reset_token_expires_in) %>.
@@ -13,7 +13,7 @@ Example:
13
13
  script/benchmarks/opt_compare.rb
14
14
 
15
15
  You can run the generated benchmark file using:
16
- `ruby script/benchmarks/opt_compare.rb`
16
+ `bin/rails runner script/benchmarks/opt_compare.rb`
17
17
 
18
18
  You can specify different reports:
19
19
  `bin/rails generate benchmark opt_compare patch1 patch2 patch3`
@@ -4,8 +4,6 @@ require_relative "../../config/environment"
4
4
 
5
5
  # Any benchmarking setup goes here...
6
6
 
7
-
8
-
9
7
  Benchmark.ips do |x|
10
8
  <%- reports.each do |report| -%>
11
9
  x.report("<%= report %>") { }
@@ -112,7 +112,7 @@ module Rails
112
112
 
113
113
  @features["ghcr.io/rails/devcontainer/features/activestorage"] = {} if options[:active_storage]
114
114
  @features["ghcr.io/devcontainers/features/node:1"] = {} if options[:node]
115
- @features["ghcr.io/devcontainers/features/docker-outside-of-docker:1"] = {} if options[:kamal]
115
+ @features["ghcr.io/devcontainers/features/docker-outside-of-docker:1"] = { moby: false } if options[:kamal]
116
116
 
117
117
  @features.merge!(database.feature) if database.feature
118
118
 
@@ -1,3 +1,7 @@
1
1
  # Make sure RUBY_VERSION matches the Ruby version in .ruby-version
2
2
  ARG RUBY_VERSION=<%= Gem.ruby_version %>
3
3
  FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION
4
+
5
+ # Ensure binding is always 0.0.0.0
6
+ # Binds the server to all IP addresses of the container, so it can be accessed from outside the container.
7
+ ENV BINDING="0.0.0.0"
@@ -7,7 +7,7 @@ services:
7
7
  dockerfile: .devcontainer/Dockerfile
8
8
 
9
9
  volumes:
10
- - ../..:/workspaces:cached
10
+ - ../../<%= options[:app_name] %>:/workspaces/<%= options[:app_name] %>:cached
11
11
 
12
12
  # Overrides default command so things don't shut down after the process ends.
13
13
  command: sleep infinity
@@ -32,7 +32,7 @@ services:
32
32
 
33
33
  <%- if options[:redis] -%>
34
34
  redis:
35
- image: redis:7.2
35
+ image: valkey/valkey:8
36
36
  restart: unless-stopped
37
37
  volumes:
38
38
  - redis-data:/data
@@ -8,7 +8,7 @@
8
8
 
9
9
  // Features to add to the dev container. More info: https://containers.dev/features.
10
10
  "features": {
11
- <%= features.map { |key, value| "\"#{key}\": #{value.as_json}" }.join(",\n ") %>
11
+ <%= features.map { |key, value| "\"#{key}\": #{value.to_json}" }.join(",\n ") %>
12
12
  },
13
13
 
14
14
  <%- if !container_env.empty? -%>
@@ -21,18 +21,20 @@ module Rails
21
21
 
22
22
  log ""
23
23
  add_key_file_silently(key_path, key)
24
+ ensure_key_files_are_ignored(key_path)
24
25
  log ""
25
26
  end
26
27
  end
27
28
 
28
29
  def add_key_file_silently(key_path, key = nil)
29
30
  create_file key_path, key || ActiveSupport::EncryptedFile.generate_key, perm: 0600
31
+ ensure_key_files_are_ignored_silently(key_path)
30
32
  end
31
33
 
32
- def ignore_key_file(key_path, ignore: key_ignore(key_path))
34
+ def ensure_key_files_are_ignored(key_path, ignore: key_ignore(key_path))
33
35
  if File.exist?(".gitignore")
34
36
  unless File.read(".gitignore").include?(ignore)
35
- log "Ignoring #{key_path} so it won't end up in Git history:"
37
+ log "Ignoring #{ignore} so it won't end up in Git history:"
36
38
  log ""
37
39
  append_to_file ".gitignore", ignore
38
40
  log ""
@@ -44,13 +46,23 @@ module Rails
44
46
  end
45
47
  end
46
48
 
47
- def ignore_key_file_silently(key_path, ignore: key_ignore(key_path))
48
- append_to_file ".gitignore", ignore if File.exist?(".gitignore")
49
+ def ensure_key_files_are_ignored_silently(key_path, ignore: key_ignore(key_path))
50
+ if File.exist?(".gitignore")
51
+ unless File.read(".gitignore").include?(ignore)
52
+ append_to_file ".gitignore", ignore
53
+ end
54
+ end
49
55
  end
50
56
 
51
57
  private
52
58
  def key_ignore(key_path)
53
- [ "", "/#{key_path}", "" ].join("\n")
59
+ key_path = Pathname.new(key_path) unless key_path.is_a?(Pathname)
60
+ <<~IGNORE
61
+
62
+ # Ignore key files for decrypting credentials and more.
63
+ /#{key_path.dirname.join("*.key")}
64
+
65
+ IGNORE
54
66
  end
55
67
  end
56
68
  end
@@ -32,22 +32,10 @@ module Rails
32
32
  end
33
33
  end
34
34
 
35
- def ignore_master_key_file
36
- key_file_generator.ignore_key_file(MASTER_KEY_PATH, ignore: key_ignore)
37
- end
38
-
39
- def ignore_master_key_file_silently
40
- key_file_generator.ignore_key_file_silently(MASTER_KEY_PATH, ignore: key_ignore)
41
- end
42
-
43
35
  private
44
36
  def key_file_generator
45
37
  EncryptionKeyFileGenerator.new([], options)
46
38
  end
47
-
48
- def key_ignore
49
- [ "", "# Ignore master key for decrypting credentials and more.", "/#{MASTER_KEY_PATH}", "" ].join("\n")
50
- end
51
39
  end
52
40
  end
53
41
  end
@@ -124,6 +124,7 @@ module Rails
124
124
  opts[:force] = force
125
125
  opts[:skip_thruster] = true
126
126
  opts[:skip_brakeman] = true
127
+ opts[:skip_bundler_audit] = true
127
128
  opts[:skip_bundle] = true
128
129
  opts[:skip_ci] = true
129
130
  opts[:skip_kamal] = true
@@ -4,10 +4,6 @@ require "bundler/setup"
4
4
  APP_RAKEFILE = File.expand_path("<%= dummy_path -%>/Rakefile", __dir__)
5
5
  load "rails/tasks/engine.rake"
6
6
  <% end -%>
7
- <% if engine? -%>
8
-
9
- load "rails/tasks/statistics.rake"
10
- <% end -%>
11
7
  <% unless options[:skip_gemspec] -%>
12
8
 
13
9
  require "bundler/gem_tasks"
@@ -3,22 +3,35 @@ name: CI
3
3
  on:
4
4
  pull_request:
5
5
  push:
6
- branches: [ main ]
6
+ branches: [ <%= user_default_branch %> ]
7
7
 
8
8
  jobs:
9
9
  <%- unless skip_rubocop? -%>
10
10
  lint:
11
11
  runs-on: ubuntu-latest
12
+ env:
13
+ RUBY_VERSION: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %>
14
+ RUBOCOP_CACHE_ROOT: tmp/rubocop
12
15
  steps:
13
16
  - name: Checkout code
14
- uses: actions/checkout@v4
17
+ uses: actions/checkout@v5
15
18
 
16
19
  - name: Set up Ruby
17
20
  uses: ruby/setup-ruby@v1
18
21
  with:
19
- ruby-version: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %>
22
+ ruby-version: ${{ env.RUBY_VERSION }}
20
23
  bundler-cache: true
21
24
 
25
+ - name: Prepare RuboCop cache
26
+ uses: actions/cache@v4
27
+ env:
28
+ DEPENDENCIES_HASH: ${{ hashFiles('**/.rubocop.yml', '**/.rubocop_todo.yml', 'Gemfile.lock') }}
29
+ with:
30
+ path: ${{ env.RUBOCOP_CACHE_ROOT }}
31
+ key: rubocop-${{ runner.os }}-${{ env.RUBY_VERSION }}-${{ env.DEPENDENCIES_HASH }}-${{ github.ref_name == github.event.repository.default_branch && github.run_id || 'default' }}
32
+ restore-keys: |
33
+ rubocop-${{ runner.os }}-${{ env.RUBY_VERSION }}-${{ env.DEPENDENCIES_HASH }}-
34
+
22
35
  - name: Lint code for consistent style
23
36
  run: bin/rubocop -f github
24
37
 
@@ -30,7 +43,7 @@ jobs:
30
43
  <%- if options[:database] == "sqlite3" -%>
31
44
  # services:
32
45
  # redis:
33
- # image: redis
46
+ # image: valkey/valkey:8
34
47
  # ports:
35
48
  # - 6379:6379
36
49
  # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
@@ -56,18 +69,15 @@ jobs:
56
69
  <%- end -%>
57
70
 
58
71
  # redis:
59
- # image: redis
72
+ # image: valkey/valkey:8
60
73
  # ports:
61
74
  # - 6379:6379
62
75
  # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
63
76
 
64
77
  <%- end -%>
65
78
  steps:
66
- - name: Install packages
67
- run: sudo apt-get update && sudo apt-get install --no-install-recommends -y <%= ci_packages.join(" ") %>
68
-
69
79
  - name: Checkout code
70
- uses: actions/checkout@v4
80
+ uses: actions/checkout@v5
71
81
 
72
82
  - name: Set up Ruby
73
83
  uses: ruby/setup-ruby@v1
@@ -91,6 +101,7 @@ jobs:
91
101
  <%- elsif options[:database] == "postgresql" -%>
92
102
  DATABASE_URL: postgres://postgres:postgres@localhost:5432
93
103
  <%- end -%>
104
+ # RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
94
105
  # REDIS_URL: redis://localhost:6379/0
95
106
  run: <%= test_command %>
96
107
 
@@ -3,10 +3,10 @@ updates:
3
3
  - package-ecosystem: bundler
4
4
  directory: "/"
5
5
  schedule:
6
- interval: daily
6
+ interval: weekly
7
7
  open-pull-requests-limit: 10
8
8
  - package-ecosystem: github-actions
9
9
  directory: "/"
10
10
  schedule:
11
- interval: daily
11
+ interval: weekly
12
12
  open-pull-requests-limit: 10
@@ -9,7 +9,7 @@ Example:
9
9
  script/my_script.rb
10
10
 
11
11
  You can run the script using:
12
- `ruby script/my_script.rb`
12
+ `bin/rails runner script/my_script.rb`
13
13
 
14
14
  You can specify a folder:
15
15
  `bin/rails generate script cleanup/my_script`
@@ -10,9 +10,22 @@ module TestUnit # :nodoc:
10
10
  template "test/models/user_test.rb"
11
11
  end
12
12
 
13
+ def create_controller_test_files
14
+ template "test/controllers/sessions_controller_test.rb"
15
+ template "test/controllers/passwords_controller_test.rb"
16
+ end
17
+
13
18
  def create_mailer_preview_files
14
19
  template "test/mailers/previews/passwords_mailer_preview.rb" if defined?(ActionMailer::Railtie)
15
20
  end
21
+
22
+ def create_test_helper_files
23
+ template "test/test_helpers/session_test_helper.rb"
24
+ end
25
+
26
+ def configure_test_helper
27
+ inject_into_file "test/test_helper.rb", "require_relative \"test_helpers/session_test_helper\"\n", after: "require \"rails/test_help\"\n"
28
+ end
16
29
  end
17
30
  end
18
31
  end
@@ -0,0 +1,67 @@
1
+ require "test_helper"
2
+
3
+ class PasswordsControllerTest < ActionDispatch::IntegrationTest
4
+ setup { @user = User.take }
5
+
6
+ test "new" do
7
+ get new_password_path
8
+ assert_response :success
9
+ end
10
+
11
+ test "create" do
12
+ post passwords_path, params: { email_address: @user.email_address }
13
+ assert_enqueued_email_with PasswordsMailer, :reset, args: [ @user ]
14
+ assert_redirected_to new_session_path
15
+
16
+ follow_redirect!
17
+ assert_notice "reset instructions sent"
18
+ end
19
+
20
+ test "create for an unknown user redirects but sends no mail" do
21
+ post passwords_path, params: { email_address: "missing-user@example.com" }
22
+ assert_enqueued_emails 0
23
+ assert_redirected_to new_session_path
24
+
25
+ follow_redirect!
26
+ assert_notice "reset instructions sent"
27
+ end
28
+
29
+ test "edit" do
30
+ get edit_password_path(@user.password_reset_token)
31
+ assert_response :success
32
+ end
33
+
34
+ test "edit with invalid password reset token" do
35
+ get edit_password_path("invalid token")
36
+ assert_redirected_to new_password_path
37
+
38
+ follow_redirect!
39
+ assert_notice "reset link is invalid"
40
+ end
41
+
42
+ test "update" do
43
+ assert_changes -> { @user.reload.password_digest } do
44
+ put password_path(@user.password_reset_token), params: { password: "new", password_confirmation: "new" }
45
+ assert_redirected_to new_session_path
46
+ end
47
+
48
+ follow_redirect!
49
+ assert_notice "Password has been reset"
50
+ end
51
+
52
+ test "update with non matching passwords" do
53
+ token = @user.password_reset_token
54
+ assert_no_changes -> { @user.reload.password_digest } do
55
+ put password_path(token), params: { password: "no", password_confirmation: "match" }
56
+ assert_redirected_to edit_password_path(token)
57
+ end
58
+
59
+ follow_redirect!
60
+ assert_notice "Passwords did not match"
61
+ end
62
+
63
+ private
64
+ def assert_notice(text)
65
+ assert_select "div", /#{text}/
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ require "test_helper"
2
+
3
+ class SessionsControllerTest < ActionDispatch::IntegrationTest
4
+ setup { @user = User.take }
5
+
6
+ test "new" do
7
+ get new_session_path
8
+ assert_response :success
9
+ end
10
+
11
+ test "create with valid credentials" do
12
+ post session_path, params: { email_address: @user.email_address, password: "password" }
13
+
14
+ assert_redirected_to root_path
15
+ assert cookies[:session_id]
16
+ end
17
+
18
+ test "create with invalid credentials" do
19
+ post session_path, params: { email_address: @user.email_address, password: "wrong" }
20
+
21
+ assert_redirected_to new_session_path
22
+ assert_nil cookies[:session_id]
23
+ end
24
+
25
+ test "destroy" do
26
+ sign_in_as(User.take)
27
+
28
+ delete session_path
29
+
30
+ assert_redirected_to new_session_path
31
+ assert_empty cookies[:session_id]
32
+ end
33
+ end
@@ -1,7 +1,8 @@
1
1
  require "test_helper"
2
2
 
3
3
  class UserTest < ActiveSupport::TestCase
4
- # test "the truth" do
5
- # assert true
6
- # end
4
+ test "downcases and strips email_address" do
5
+ user = User.new(email_address: " DOWNCASED@EXAMPLE.COM ")
6
+ assert_equal("downcased@example.com", user.email_address)
7
+ end
7
8
  end
@@ -0,0 +1,19 @@
1
+ module SessionTestHelper
2
+ def sign_in_as(user)
3
+ Current.session = user.sessions.create!
4
+
5
+ ActionDispatch::TestRequest.create.cookie_jar.tap do |cookie_jar|
6
+ cookie_jar.signed[:session_id] = Current.session.id
7
+ cookies["session_id"] = cookie_jar[:session_id]
8
+ end
9
+ end
10
+
11
+ def sign_out
12
+ Current.session&.destroy!
13
+ cookies.delete("session_id")
14
+ end
15
+ end
16
+
17
+ ActiveSupport.on_load(:action_dispatch_integration_test) do
18
+ include SessionTestHelper
19
+ end
@@ -4,7 +4,7 @@
4
4
  <%= name %>:
5
5
  <% attributes.each do |attribute| -%>
6
6
  <%- if attribute.password_digest? -%>
7
- password_digest: <%%= BCrypt::Password.create("secret") %>
7
+ password_digest: <%= BCrypt::Password.create("secret") %> # Generated with BCrypt::Password.create("secret")
8
8
  <%- elsif attribute.reference? -%>
9
9
  <%= yaml_key_value(attribute.column_name.delete_suffix("_id"), attribute.default || name) %>
10
10
  <%- elsif !attribute.virtual? -%>
@@ -14,7 +14,7 @@ module TestUnit # :nodoc:
14
14
  desc: "Generate API functional tests"
15
15
 
16
16
  class_option :system_tests, type: :string,
17
- desc: "Skip system test files"
17
+ desc: "Generate system test files (set to 'true' to enable)"
18
18
 
19
19
  argument :attributes, type: :array, default: [], banner: "field:type field:type"
20
20
 
@@ -23,7 +23,9 @@ module TestUnit # :nodoc:
23
23
  template template_file,
24
24
  File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb")
25
25
 
26
- if !options.api? && options[:system_tests]
26
+ # Generate system tests if this isn't an API only app and the system
27
+ # tests option is true
28
+ if !options.api? && options[:system_tests] == "true"
27
29
  template "system_test.rb", File.join("test/system", class_path, "#{file_name.pluralize}_test.rb")
28
30
  end
29
31
  end
@@ -1,11 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/class/attribute"
4
- require "active_support/core_ext/module/delegation"
5
3
  require "active_support/core_ext/hash/reverse_merge"
6
4
  require "active_support/core_ext/kernel/reporting"
7
5
  require "active_support/testing/stream"
8
- require "active_support/concern"
9
6
  require "rails/generators"
10
7
 
11
8
  module Rails
@@ -157,7 +157,9 @@ module Rails
157
157
  "action_text:install",
158
158
  "action_mailbox:install",
159
159
  "devcontainer"
160
- ]
160
+ ].tap do |h|
161
+ h << "test_unit" if test.to_s != "test_unit"
162
+ end
161
163
  end
162
164
  end
163
165
 
@@ -43,11 +43,17 @@ module Rails
43
43
 
44
44
  private
45
45
  def render_up
46
- render html: html_status(color: "green")
46
+ respond_to do |format|
47
+ format.html { render html: html_status(color: "green") }
48
+ format.json { render json: { status: "up", timestamp: Time.current.iso8601 } }
49
+ end
47
50
  end
48
51
 
49
52
  def render_down
50
- render html: html_status(color: "red"), status: 500
53
+ respond_to do |format|
54
+ format.html { render html: html_status(color: "red"), status: 500 }
55
+ format.json { render json: { status: "down", timestamp: Time.current.iso8601 }, status: 500 }
56
+ end
51
57
  end
52
58
 
53
59
  def html_status(color:)