From af13563ec84fe05004500857a5d9a08ad8f1b14c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robin=20Bo=CC=88ning?= <robin.boening@gmail.com>
Date: Wed, 27 Jan 2021 23:00:01 +0100
Subject: [PATCH 01/12] Allow Rails 6.1 and make it the default

---
 .github/workflows/ci.yml | 1 +
 Gemfile                  | 2 +-
 alchemy_cms.gemspec      | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fef23c7fb8..5b22867759 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,6 +10,7 @@ jobs:
       matrix:
         rails:
           - '6.0'
+          - '6.1'
         ruby:
           - '2.6.6'
           - '2.7.2'
diff --git a/Gemfile b/Gemfile
index 139c9bad6e..00f09a7e51 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,7 +3,7 @@ source "https://rubygems.org"
 
 gemspec
 
-rails_version = ENV.fetch("RAILS_VERSION", 6.0).to_f
+rails_version = ENV.fetch("RAILS_VERSION", 6.1).to_f
 gem "rails", "~> #{rails_version}.0"
 
 if ENV["DB"].nil? || ENV["DB"] == "sqlite"
diff --git a/alchemy_cms.gemspec b/alchemy_cms.gemspec
index 8128f5edd9..1d705d55bc 100644
--- a/alchemy_cms.gemspec
+++ b/alchemy_cms.gemspec
@@ -29,7 +29,7 @@ Gem::Specification.new do |gem|
     activesupport
     railties
   ].each do |rails_gem|
-    gem.add_runtime_dependency rails_gem, [">= 6.0", "< 6.1"]
+    gem.add_runtime_dependency rails_gem, [">= 6.0", "< 6.2"]
   end
 
   gem.add_runtime_dependency "active_model_serializers", ["~> 0.10.0"]

From 7d6bc25d2adac1770565bfbe8c4239550bff5b61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robin=20Bo=CC=88ning?= <robin.boening@gmail.com>
Date: Fri, 12 Mar 2021 12:03:38 +0100
Subject: [PATCH 02/12] Fix tinymce feature spec

This feature spec failed with Rails 6.1 as it was defaulting to example.com instead of 127.0.0.1.

Setting `asset_host` inside the test is more explicit as it was before and reflects what an actual app does.
---
 spec/features/admin/tinymce_feature_spec.rb | 9 ++++++---
 spec/views/admin/attachments/show_spec.rb   | 1 +
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/spec/features/admin/tinymce_feature_spec.rb b/spec/features/admin/tinymce_feature_spec.rb
index 604890f911..d74a22aa92 100644
--- a/spec/features/admin/tinymce_feature_spec.rb
+++ b/spec/features/admin/tinymce_feature_spec.rb
@@ -15,14 +15,17 @@
   end
 
   context "with asset host" do
-    before do
-      expect(ActionController::Base.config).to receive(:asset_host_set?).and_return(true)
+    around do |example|
+      host = ActionController::Base.config.asset_host
+      ActionController::Base.config.asset_host = "myhost.com"
+      example.run
+      ActionController::Base.config.asset_host = host
     end
 
     it "base path should be set to tinymce asset folder" do
       visit admin_dashboard_path
       expect(page).to have_content(
-        "var tinyMCEPreInit = { base: 'http://127.0.0.1/assets/tinymce', suffix: '.min' };",
+        "var tinyMCEPreInit = { base: 'http://myhost.com/assets/tinymce', suffix: '.min' };",
       )
     end
   end
diff --git a/spec/views/admin/attachments/show_spec.rb b/spec/views/admin/attachments/show_spec.rb
index 9cada308d8..d0a985ba88 100644
--- a/spec/views/admin/attachments/show_spec.rb
+++ b/spec/views/admin/attachments/show_spec.rb
@@ -10,6 +10,7 @@
   it "displays urls to file" do
     assign(:attachment, attachment)
     render
+    puts rendered
     aggregate_failures do
       expect(rendered).to have_selector("label:contains('URL') + p:contains('/attachment/#{attachment.id}/show')")
       expect(rendered).to have_selector("label:contains('Download-URL') + p:contains('/attachment/#{attachment.id}/download')")

From 25ffa9e3d8f34e10692f1630766e14546cfb4fe3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robin=20Bo=CC=88ning?= <robin.boening@gmail.com>
Date: Sat, 13 Mar 2021 11:52:44 +0100
Subject: [PATCH 03/12] Fix page specs failing with Rails 6.1

---
 spec/models/alchemy/page_spec.rb | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/spec/models/alchemy/page_spec.rb b/spec/models/alchemy/page_spec.rb
index e9e67910db..481ece7b71 100644
--- a/spec/models/alchemy/page_spec.rb
+++ b/spec/models/alchemy/page_spec.rb
@@ -1755,7 +1755,7 @@ class AnotherUrlPathClass; end
         end
 
         it "uses the primary key defined on user class" do
-          expect(Alchemy.user_class).to receive(:primary_key).at_least(:once) { :id }
+          expect(Alchemy.user_class).to receive(:primary_key).at_least(:once) { "id" }
           subject
         end
       end
@@ -1769,7 +1769,7 @@ class AnotherUrlPathClass; end
         end
 
         it "uses the primary key defined on user class" do
-          expect(Alchemy.user_class).to receive(:primary_key).at_least(:once) { :id }
+          expect(Alchemy.user_class).to receive(:primary_key).at_least(:once) { "id" }
           subject
         end
       end
@@ -1783,7 +1783,7 @@ class AnotherUrlPathClass; end
         end
 
         it "uses the primary key defined on user class" do
-          expect(Alchemy.user_class).to receive(:primary_key).at_least(:once) { :id }
+          expect(Alchemy.user_class).to receive(:primary_key).at_least(:once) { "id" }
           subject
         end
       end

From 76a1f9bff7d320a1db440fc4e1faa9783988fd00 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Sat, 28 Aug 2021 12:26:19 +0200
Subject: [PATCH 04/12] Update dummy app to Rails 6.1

---
 spec/dummy/config.ru                          |  2 +
 spec/dummy/config/application.rb              |  2 +-
 spec/dummy/config/environments/development.rb | 30 +++++++++----
 spec/dummy/config/environments/production.rb  | 28 +++++++-----
 spec/dummy/config/environments/test.rb        | 13 +++++-
 .../initializers/backtrace_silencers.rb       |  7 +--
 .../initializers/content_security_policy.rb   | 23 +++++-----
 .../initializers/filter_parameter_logging.rb  |  4 +-
 .../config/initializers/permissions_policy.rb | 11 +++++
 spec/dummy/config/puma.rb                     | 43 +++++++++++++++++++
 10 files changed, 125 insertions(+), 38 deletions(-)
 create mode 100644 spec/dummy/config/initializers/permissions_policy.rb
 create mode 100644 spec/dummy/config/puma.rb

diff --git a/spec/dummy/config.ru b/spec/dummy/config.ru
index a591fdd72c..a97566a7d5 100644
--- a/spec/dummy/config.ru
+++ b/spec/dummy/config.ru
@@ -2,4 +2,6 @@
 # This file is used by Rack-based servers to start the application.
 
 require_relative "config/environment"
+
 run Rails.application
+Rails.application.load_server
diff --git a/spec/dummy/config/application.rb b/spec/dummy/config/application.rb
index fe8f540397..ea4fb07d1e 100644
--- a/spec/dummy/config/application.rb
+++ b/spec/dummy/config/application.rb
@@ -23,7 +23,7 @@ module Dummy
   class Application < Rails::Application
     # Initialize configuration defaults for originally generated Rails version.
     if config.respond_to?(:load_defaults)
-      config.load_defaults ENV["RAILS_VERSION"] || 6.0
+      config.load_defaults ENV["RAILS_VERSION"] || 6.1
     end
 
     # Settings in config/environments/* take precedence over those specified here.
diff --git a/spec/dummy/config/environments/development.rb b/spec/dummy/config/environments/development.rb
index 0166cdc2fd..d334e53532 100644
--- a/spec/dummy/config/environments/development.rb
+++ b/spec/dummy/config/environments/development.rb
@@ -1,8 +1,10 @@
+require "active_support/core_ext/integer/time"
+
 Rails.application.configure do
   # Settings specified here will take precedence over those in config/application.rb.
 
-  # In the development environment your application's code is reloaded on
-  # every request. This slows down response time but is perfect for development
+  # In the development environment your application's code is reloaded any time
+  # it changes. This slows down response time but is perfect for development
   # since you don't have to restart the web server when you make code changes.
   config.cache_classes = false
 
@@ -14,13 +16,13 @@
 
   # Enable/disable caching. By default caching is disabled.
   # Run rails dev:cache to toggle caching.
-  if Rails.root.join('tmp', 'caching-dev.txt').exist?
+  if Rails.root.join("tmp", "caching-dev.txt").exist?
     config.action_controller.perform_caching = true
     config.action_controller.enable_fragment_cache_logging = true
 
     config.cache_store = :memory_store
     config.public_file_server.headers = {
-      'Cache-Control' => "public, max-age=#{2.days.to_i}"
+      "Cache-Control" => "public, max-age=#{2.days.to_i}",
     }
   else
     config.action_controller.perform_caching = false
@@ -36,13 +38,17 @@
   # Print deprecation notices to the Rails logger.
   config.active_support.deprecation = :log
 
+  # Raise exceptions for disallowed deprecations.
+  config.active_support.disallowed_deprecation = :raise
+
+  # Tell Active Support which deprecation messages to disallow.
+  config.active_support.disallowed_deprecation_warnings = []
+
   # Raise an error on page load if there are pending migrations.
   config.active_record.migration_error = :page_load
 
-  if ActiveRecord::Base.respond_to?(:verbose_query_logs=)
-    # Highlight code that triggered database queries in logs.
-    config.active_record.verbose_query_logs = true
-  end
+  # Highlight code that triggered database queries in logs.
+  config.active_record.verbose_query_logs = true
 
   # Debug mode disables concatenation and preprocessing of assets.
   # This option may cause significant delays in view rendering with a large
@@ -53,11 +59,17 @@
   config.assets.quiet = true
 
   # Raises error for missing translations.
-  # config.action_view.raise_on_missing_translations = true
+  # config.i18n.raise_on_missing_translations = true
+
+  # Annotate rendered view with file names.
+  # config.action_view.annotate_rendered_view_with_filenames = true
 
   # Use an evented file watcher to asynchronously detect changes in source code,
   # routes, locales, etc. This feature depends on the listen gem.
   config.file_watcher = ActiveSupport::EventedFileUpdateChecker
 
   config.hosts << "alchemy.test"
+
+  # Uncomment if you wish to allow Action Cable access from any origin.
+  # config.action_cable.disable_request_forgery_protection = true
 end
diff --git a/spec/dummy/config/environments/production.rb b/spec/dummy/config/environments/production.rb
index b6e408c8b8..6671da2b33 100644
--- a/spec/dummy/config/environments/production.rb
+++ b/spec/dummy/config/environments/production.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/integer/time"
+
 Rails.application.configure do
   # Settings specified here will take precedence over those in config/application.rb.
 
@@ -11,7 +13,7 @@
   config.eager_load = true
 
   # Full error reports are disabled and caching is turned on.
-  config.consider_all_requests_local       = false
+  config.consider_all_requests_local = false
   config.action_controller.perform_caching = true
 
   # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
@@ -20,7 +22,7 @@
 
   # Disable serving static files from the `/public` folder by default since
   # Apache or NGINX already handles this.
-  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+  config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
 
   # Compress CSS using a preprocessor.
   # config.assets.css_compressor = :sass
@@ -29,7 +31,7 @@
   config.assets.compile = false
 
   # Enable serving of images, stylesheets, and JavaScripts from an asset server.
-  # config.action_controller.asset_host = 'http://assets.example.com'
+  # config.asset_host = 'http://assets.example.com'
 
   # Specifies the header that your server uses for sending files.
   # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
@@ -38,12 +40,12 @@
   # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
   # config.force_ssl = true
 
-  # Use the lowest log level to ensure availability of diagnostic information
-  # when problems arise.
-  config.log_level = :debug
+  # Include generic and useful information about system operation, but avoid logging too much
+  # information to avoid inadvertent exposure of personally identifiable information (PII).
+  config.log_level = :info
 
   # Prepend all log lines with the following tags.
-  config.log_tags = [ :request_id ]
+  config.log_tags = [:request_id]
 
   # Use a different cache store in production.
   # config.cache_store = :mem_cache_store
@@ -65,17 +67,23 @@
   # Send deprecation notices to registered listeners.
   config.active_support.deprecation = :notify
 
+  # Log disallowed deprecations.
+  config.active_support.disallowed_deprecation = :log
+
+  # Tell Active Support which deprecation messages to disallow.
+  config.active_support.disallowed_deprecation_warnings = []
+
   # Use default logging formatter so that PID and timestamp are not suppressed.
   config.log_formatter = ::Logger::Formatter.new
 
   # Use a different logger for distributed setups.
-  # require 'syslog/logger'
+  # require "syslog/logger"
   # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
 
   if ENV["RAILS_LOG_TO_STDOUT"].present?
-    logger           = ActiveSupport::Logger.new(STDOUT)
+    logger = ActiveSupport::Logger.new(STDOUT)
     logger.formatter = config.log_formatter
-    config.logger    = ActiveSupport::TaggedLogging.new(logger)
+    config.logger = ActiveSupport::TaggedLogging.new(logger)
   end
 
   # Do not dump schema after migrations.
diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb
index 7ab16aaa37..f608dd3aa6 100644
--- a/spec/dummy/config/environments/test.rb
+++ b/spec/dummy/config/environments/test.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/integer/time"
+
 # The test environment is used exclusively to run your application's
 # test suite. You never need to work with it otherwise. Remember that
 # your test database is "scratch space" for the test suite and is wiped
@@ -40,8 +42,17 @@
   # Print deprecation notices to the stderr.
   config.active_support.deprecation = :stderr
 
+  # Raise exceptions for disallowed deprecations.
+  config.active_support.disallowed_deprecation = :raise
+
+  # Tell Active Support which deprecation messages to disallow.
+  config.active_support.disallowed_deprecation_warnings = []
+
   # Raises error for missing translations.
-  # config.action_view.raise_on_missing_translations = true
+  # config.i18n.raise_on_missing_translations = true
 
   config.active_job.queue_adapter = :test
+
+  # Annotate rendered view with file names.
+  # config.action_view.annotate_rendered_view_with_filenames = true
 end
diff --git a/spec/dummy/config/initializers/backtrace_silencers.rb b/spec/dummy/config/initializers/backtrace_silencers.rb
index 4b63f2893d..74f30e8875 100644
--- a/spec/dummy/config/initializers/backtrace_silencers.rb
+++ b/spec/dummy/config/initializers/backtrace_silencers.rb
@@ -3,7 +3,8 @@
 # Be sure to restart your server when you modify this file.
 
 # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
-# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) }
 
-# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
-# Rails.backtrace_cleaner.remove_silencers!
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
+# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
+Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]
diff --git a/spec/dummy/config/initializers/content_security_policy.rb b/spec/dummy/config/initializers/content_security_policy.rb
index 4a9aad6851..41c43016f1 100644
--- a/spec/dummy/config/initializers/content_security_policy.rb
+++ b/spec/dummy/config/initializers/content_security_policy.rb
@@ -4,20 +4,17 @@
 # For further information see the following documentation
 # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
 
-Rails.application.config.content_security_policy do |policy|
-  # policy.default_src :self, :https
-  # policy.font_src    :self, :https, :data
-  # policy.img_src     :self, :https, :data
-  # policy.object_src  :none
-  # policy.script_src  :self, :https
-  # policy.style_src   :self, :https
+# Rails.application.config.content_security_policy do |policy|
+#   policy.default_src :self, :https
+#   policy.font_src    :self, :https, :data
+#   policy.img_src     :self, :https, :data
+#   policy.object_src  :none
+#   policy.script_src  :self, :https
+#   policy.style_src   :self, :https
 
-  # Specify URI for violation reports
-  # policy.report_uri "/csp-violation-report-endpoint"
-  if Rails.env.development?
-    policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035"
-  end
-end
+#   # Specify URI for violation reports
+#   # policy.report_uri "/csp-violation-report-endpoint"
+# end
 
 # If you are using UJS then enable automatic nonce generation
 # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
diff --git a/spec/dummy/config/initializers/filter_parameter_logging.rb b/spec/dummy/config/initializers/filter_parameter_logging.rb
index 7a4f47b4c2..5118eb69cc 100644
--- a/spec/dummy/config/initializers/filter_parameter_logging.rb
+++ b/spec/dummy/config/initializers/filter_parameter_logging.rb
@@ -3,4 +3,6 @@
 # Be sure to restart your server when you modify this file.
 
 # Configure sensitive parameters which will be filtered from the log file.
-Rails.application.config.filter_parameters += [:password]
+Rails.application.config.filter_parameters += [
+  :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
+]
diff --git a/spec/dummy/config/initializers/permissions_policy.rb b/spec/dummy/config/initializers/permissions_policy.rb
new file mode 100644
index 0000000000..00f64d71b0
--- /dev/null
+++ b/spec/dummy/config/initializers/permissions_policy.rb
@@ -0,0 +1,11 @@
+# Define an application-wide HTTP permissions policy. For further
+# information see https://developers.google.com/web/updates/2018/06/feature-policy
+#
+# Rails.application.config.permissions_policy do |f|
+#   f.camera      :none
+#   f.gyroscope   :none
+#   f.microphone  :none
+#   f.usb         :none
+#   f.fullscreen  :self
+#   f.payment     :self, "https://secure.example.com"
+# end
diff --git a/spec/dummy/config/puma.rb b/spec/dummy/config/puma.rb
new file mode 100644
index 0000000000..d9b3e836cf
--- /dev/null
+++ b/spec/dummy/config/puma.rb
@@ -0,0 +1,43 @@
+# Puma can serve each request in a thread from an internal thread pool.
+# The `threads` method setting takes two numbers: a minimum and maximum.
+# Any libraries that use thread pools should be configured to match
+# the maximum value specified for Puma. Default is set to 5 threads for minimum
+# and maximum; this matches the default thread size of Active Record.
+#
+max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
+min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
+threads min_threads_count, max_threads_count
+
+# Specifies the `worker_timeout` threshold that Puma will use to wait before
+# terminating a worker in development environments.
+#
+worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
+
+# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
+#
+port ENV.fetch("PORT") { 3000 }
+
+# Specifies the `environment` that Puma will run in.
+#
+environment ENV.fetch("RAILS_ENV") { "development" }
+
+# Specifies the `pidfile` that Puma will use.
+pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
+
+# Specifies the number of `workers` to boot in clustered mode.
+# 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).
+#
+# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
+
+# Use the `preload_app!` method when specifying a `workers` number.
+# This directive tells Puma to first boot the application and load code
+# before forking the application. This takes advantage of Copy On Write
+# process behavior so workers use less memory.
+#
+# preload_app!
+
+# Allow puma to be restarted by `rails restart` command.
+plugin :tmp_restart

From 89f124f48efdbea0a0ddf946d23c518ac2388f49 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Sat, 28 Aug 2021 12:37:50 +0200
Subject: [PATCH 05/12] Include helpers in picture ingredient editor spec

Those helpers are not included by Rails anymore.
Since a view spec is a unit test we need to stub/include
everything we need on ourselves.
---
 spec/views/alchemy/ingredients/picture_editor_spec.rb | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/spec/views/alchemy/ingredients/picture_editor_spec.rb b/spec/views/alchemy/ingredients/picture_editor_spec.rb
index fab4eb42b1..82f7691dc4 100644
--- a/spec/views/alchemy/ingredients/picture_editor_spec.rb
+++ b/spec/views/alchemy/ingredients/picture_editor_spec.rb
@@ -24,6 +24,8 @@
   before do
     allow(element_editor).to receive(:ingredients) { [Alchemy::IngredientEditor.new(ingredient)] }
     allow(ingredient).to receive(:settings) { settings }
+    view.class.send :include, Alchemy::Admin::BaseHelper
+    view.class.send :include, Alchemy::Admin::IngredientsHelper
   end
 
   subject do

From 4a080c68db4a50b72c9132092c5478a06c46994e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robin=20Bo=CC=88ning?= <robin.boening@gmail.com>
Date: Fri, 12 Mar 2021 12:39:25 +0100
Subject: [PATCH 06/12] Fix element spec for Rails 6.1

First create elements with the page_version (the direct relation)
and not a page (an indirect join via the page_version).

Also reload element in nested_elements spec.
Somehow this is now necessary in Rails 6.1.
---
 spec/models/alchemy/element_spec.rb | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/spec/models/alchemy/element_spec.rb b/spec/models/alchemy/element_spec.rb
index 7375623410..f5a061c4e0 100644
--- a/spec/models/alchemy/element_spec.rb
+++ b/spec/models/alchemy/element_spec.rb
@@ -1014,21 +1014,22 @@ module Alchemy
       subject { element.nested_elements }
 
       context "with nestable_elements defined" do
-        let!(:page) { create(:alchemy_page) }
-        let!(:element) { create(:alchemy_element, page: page) }
-        let!(:nested_element) { create(:alchemy_element, parent_element: element, page: page) }
+        let!(:page_version) { create(:alchemy_page_version) }
+        let!(:element) { create(:alchemy_element, page_version: page_version) }
+        let!(:nested_element) { create(:alchemy_element, parent_element: element, page_version: page_version) }
 
         it "returns nested elements" do
-          expect(subject).to eq([nested_element])
+          expect(subject).to contain_exactly(nested_element)
         end
 
         context "with hidden nested elements" do
           let!(:hidden_nested_element) do
-            create(:alchemy_element, parent_element: element, page: page, public: false)
+            create(:alchemy_element, parent_element: element, page_version: page_version, public: false)
           end
 
           it "does not include them" do
-            expect(subject).to eq([nested_element])
+            element.reload # necessary since Rails 6.1
+            expect(subject).to contain_exactly(nested_element)
           end
         end
       end

From eb1b324862d35e85ea6835ebf68dbd9aa2289cd4 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Sat, 28 Aug 2021 17:37:48 +0200
Subject: [PATCH 07/12] Update dummy app schema to Rails 6.1

---
 spec/dummy/db/schema.rb | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb
index d4aab1aa76..2cdda97e4e 100644
--- a/spec/dummy/db/schema.rb
+++ b/spec/dummy/db/schema.rb
@@ -2,8 +2,8 @@
 # of editing this file, please use the migrations feature of Active Record to
 # incrementally modify your database, and then regenerate this schema definition.
 #
-# This file is the source Rails uses to define your schema when running `rails
-# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
 # be faster and is potentially less error prone than running all of your
 # migrations from scratch. Old migrations may fail to apply correctly if those
 # migrations use external dependencies or application code.
@@ -33,7 +33,7 @@
     t.integer "essence_id", null: false
     t.integer "element_id", null: false
     t.index ["element_id"], name: "index_alchemy_contents_on_element_id"
-    t.index ["essence_type", "essence_id"], name: "index_alchemy_contents_on_essence_type_and_essence_id", unique: true
+    t.index ["essence_type", "essence_id"], name: "index_alchemy_contents_on_essence", unique: true
   end
 
   create_table "alchemy_elements", force: :cascade do |t|
@@ -64,7 +64,7 @@
   end
 
   create_table "alchemy_essence_audios", force: :cascade do |t|
-    t.integer "attachment_id"
+    t.bigint "attachment_id"
     t.boolean "controls", default: true, null: false
     t.boolean "autoplay", default: false
     t.boolean "loop", default: false, null: false
@@ -158,7 +158,7 @@
   end
 
   create_table "alchemy_essence_videos", force: :cascade do |t|
-    t.integer "attachment_id"
+    t.bigint "attachment_id"
     t.string "width"
     t.string "height"
     t.boolean "allow_fullscreen", default: true, null: false
@@ -178,13 +178,13 @@
   end
 
   create_table "alchemy_ingredients", force: :cascade do |t|
-    t.integer "element_id", null: false
+    t.bigint "element_id", null: false
     t.string "type", null: false
     t.string "role", null: false
     t.text "value"
     t.json "data"
     t.string "related_object_type"
-    t.integer "related_object_id"
+    t.bigint "related_object_id"
     t.datetime "created_at", precision: 6, null: false
     t.datetime "updated_at", precision: 6, null: false
     t.index ["element_id", "role"], name: "index_alchemy_ingredients_on_element_id_and_role", unique: true

From abc5a05a1155047a07e9d138dedb0d4dddac6e93 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Thu, 2 Sep 2021 09:02:11 +0200
Subject: [PATCH 08/12] Stub configuration method in pages helper spec

Instead of globally including a module into the tet controller
we stub the one method the spec uses
---
 spec/helpers/alchemy/pages_helper_spec.rb | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/spec/helpers/alchemy/pages_helper_spec.rb b/spec/helpers/alchemy/pages_helper_spec.rb
index 9dde29b07c..a8b20f05c9 100644
--- a/spec/helpers/alchemy/pages_helper_spec.rb
+++ b/spec/helpers/alchemy/pages_helper_spec.rb
@@ -8,9 +8,10 @@ module Alchemy
     let(:public_page) { create(:alchemy_page, :public) }
     let(:klingon) { create(:alchemy_language, :klingon) }
     let(:klingon_language_root) { create(:alchemy_page, :language_root, language: klingon) }
+    let(:prefix_locale?) { false }
 
     before do
-      helper.controller.class_eval { include Alchemy::ConfigurationMethods }
+      allow(helper).to receive(:prefix_locale?) { prefix_locale? }
       @root_page = language_root # We need this instance variable in the helpers
     end
 
@@ -209,6 +210,8 @@ module Alchemy
           # Always create a language root page for klingon
           before { klingon_language_root }
 
+          let(:prefix_locale?) { true }
+
           it "should render two language links" do
             expect(helper.language_links).to have_selector("a", count: 2)
           end

From 371463561e133294efc8ed38e9e1552f0a42fb94 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Thu, 2 Sep 2021 09:03:01 +0200
Subject: [PATCH 09/12] Remove configuration methods include in url helper spec

It is not necessary. The specs pass without globally including
a module in the test controller
---
 spec/helpers/alchemy/url_helper_spec.rb | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/spec/helpers/alchemy/url_helper_spec.rb b/spec/helpers/alchemy/url_helper_spec.rb
index 393204518c..99bec8c912 100644
--- a/spec/helpers/alchemy/url_helper_spec.rb
+++ b/spec/helpers/alchemy/url_helper_spec.rb
@@ -8,10 +8,6 @@ module Alchemy
   describe UrlHelper do
     let(:page) { mock_model(Page, urlname: "testpage", language_code: "en") }
 
-    before do
-      helper.controller.class_eval { include Alchemy::ConfigurationMethods }
-    end
-
     context "page path helpers" do
       describe "#show_page_path_params" do
         subject(:show_page_path_params) { helper.show_page_path_params(page) }

From a09ff32d2aa233aa89261863567fe37224460342 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Thu, 2 Sep 2021 09:36:15 +0200
Subject: [PATCH 10/12] Expect page_version save to change page updated_at

Instead of expecting that rails calls a method on the receiver
we expect that the updated_at time has changed.
---
 spec/models/alchemy/page_version_spec.rb | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/spec/models/alchemy/page_version_spec.rb b/spec/models/alchemy/page_version_spec.rb
index 53f27f3ce4..45f7b3c4d8 100644
--- a/spec/models/alchemy/page_version_spec.rb
+++ b/spec/models/alchemy/page_version_spec.rb
@@ -75,8 +75,7 @@
     let(:page) { page_version.page }
 
     it "touches the page" do
-      expect(page).to receive(:touch)
-      page_version.save
+      expect { page_version.save }.to change(page, :updated_at)
     end
   end
 

From eda438af60e5201f29040d458ec64b5319ddefed Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Thu, 2 Sep 2021 09:59:48 +0200
Subject: [PATCH 11/12] Only set db host if variable is specified

Not everybody is using a db running on host but on a socket instead.
---
 spec/dummy/config/database.yml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/spec/dummy/config/database.yml b/spec/dummy/config/database.yml
index 51bea248d6..eb92ca6793 100644
--- a/spec/dummy/config/database.yml
+++ b/spec/dummy/config/database.yml
@@ -21,7 +21,9 @@ postgresql: &postgresql
 defaults: &defaults
   pool: 5
   timeout: 5000
-  host: <%= ENV['DB_HOST'] || "localhost" %>
+  <% if ENV['DB_HOST'] %>
+  host: <%= ENV['DB_HOST'] %>
+  <% end %>
   <<: *<%= ENV['DB'] || "sqlite" %>
 
 development:

From ac63b676eb2fc230d2b9cab24bd9c8e1a35e7616 Mon Sep 17 00:00:00 2001
From: Thomas von Deyen <thomas@vondeyen.com>
Date: Sun, 12 Sep 2021 21:22:22 +0200
Subject: [PATCH 12/12] Use latest Rubies on CI

---
 .github/workflows/ci.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5b22867759..c114994d46 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,9 +12,9 @@ jobs:
           - '6.0'
           - '6.1'
         ruby:
-          - '2.6.6'
-          - '2.7.2'
-          - '3.0.0'
+          - '2.6.8'
+          - '2.7.4'
+          - '3.0.2'
         database:
           - mysql
           - postgresql