From 4c06f598eab3dddb12e530bb03bc0946c53fe690 Mon Sep 17 00:00:00 2001
From: Takashi Kato <tohosaku@users.osdn.me>
Date: Thu, 14 Sep 2023 14:27:09 +0000
Subject: [PATCH] Upgrade to rails-7.1 beta1

---
 Gemfile                                       |  8 +-
 app/controllers/attachments_controller.rb     |  2 +-
 app/helpers/application_helper.rb             |  4 +-
 app/models/attachment.rb                      | 10 +--
 app/models/query.rb                           |  8 +-
 app/models/role.rb                            |  2 +-
 .../_visibility_by_project_selector.html.erb  |  2 +-
 config/application.rb                         |  7 +-
 config/environments/test.rb                   |  2 +-
 config/initializers/10-patches.rb             | 50 ++++++-----
 config/initializers/zeitwerk.rb               |  3 -
 lib/redmine/plugin.rb                         | 10 +--
 test/fixtures/issues.yml                      | 84 +++++++++----------
 test/fixtures/journals.yml                    | 20 ++---
 test/fixtures/messages.yml                    | 12 +--
 test/fixtures/versions.yml                    |  2 +-
 test/integration/layout_test.rb               |  4 +-
 test/unit/query_test.rb                       |  8 +-
 test/unit/user_query_test.rb                  |  2 +-
 19 files changed, 125 insertions(+), 115 deletions(-)

diff --git a/Gemfile b/Gemfile
index 0bd66a589..739c8e5e7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,10 +2,10 @@ source 'https://rubygems.org'
 
 ruby '>= 2.7.0', '< 3.3.0'
 
-gem 'rails', '6.1.7.6'
+gem 'rails', github: 'rails/rails', tag: 'v7.1.0.beta1'
 gem 'rouge', '~> 4.1.0'
 gem 'mini_mime', '~> 1.1.0'
-gem "actionpack-xml_parser"
+gem "actionpack-xml_parser", '~> 2.0.1'
 gem 'roadie-rails', '~> 3.0.0'
 gem 'marcel'
 gem 'mail', '~> 2.8.1'
@@ -86,6 +86,10 @@ else
   warn("Please configure your config/database.yml first")
 end
 
+group :development, :test do
+  gem 'debug'
+end
+
 group :development do
   gem 'listen', '~> 3.3'
   gem "yard"
diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb
index 414ecfde0..bc64f01b9 100644
--- a/app/controllers/attachments_controller.rb
+++ b/app/controllers/attachments_controller.rb
@@ -100,7 +100,7 @@ class AttachmentsController < ApplicationController
   def upload
     # Make sure that API users get used to set this content type
     # as it won't trigger Rails' automatic parsing of the request body for parameters
-    unless request.content_type == 'application/octet-stream'
+    unless request.media_type == 'application/octet-stream'
       head 406
       return
     end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 3177d0eb7..9fb62c92f 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -259,7 +259,7 @@ module ApplicationHelper
     when Array
       formatted_objects = object.map {|o| format_object(o, html)}
       html ? safe_join(formatted_objects, ', ') : formatted_objects.join(', ')
-    when Time
+    when Time, ActiveSupport::TimeWithZone
       format_time(object)
     when Date
       format_date(object)
@@ -634,7 +634,7 @@ module ApplicationHelper
                  'span', nil,
                  :class => "name icon icon-#{principal.class.name.downcase}"
                )
-            ) + principal
+            ) + principal.to_s
         )
     end
     s.html_safe
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 86382054d..97dea32bd 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -345,14 +345,14 @@ class Attachment < ActiveRecord::Base
   #   })
   #
   def self.update_attachments(attachments, params)
-    params = params.transform_keys {|key| key.to_i}
-
+    converted = {}
+    params.each {|key, val| converted[key.to_i] = val}
     saved = true
     transaction do
       attachments.each do |attachment|
-        if p = params[attachment.id]
-          attachment.filename = p[:filename] if p.key?(:filename)
-          attachment.description = p[:description] if p.key?(:description)
+        if file = converted[attachment.id]
+          attachment.filename = file[:filename] if file.key?(:filename)
+          attachment.description = file[:description] if file.key?(:description)
           saved &&= attachment.save
         end
       end
diff --git a/app/models/query.rb b/app/models/query.rb
index 5630f95c7..3208dc535 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -257,8 +257,8 @@ class Query < ActiveRecord::Base
   has_and_belongs_to_many :roles, :join_table => "#{table_name_prefix}queries_roles#{table_name_suffix}", :foreign_key => "query_id"
   serialize :filters
   serialize :column_names
-  serialize :sort_criteria, Array
-  serialize :options, Hash
+  serialize :sort_criteria, type: Array
+  serialize :options, type: Hash
 
   validates_presence_of :name
   validates_length_of :name, :maximum => 255
@@ -1631,7 +1631,7 @@ class Query < ActiveRecord::Base
       else
         from = from - 1 # second
       end
-      if self.class.default_timezone == :utc
+      if ActiveRecord.default_timezone == :utc
         from = from.utc
       end
       s << ("#{table}.#{field} > '%s'" % [quoted_time(from, is_custom_filter)])
@@ -1640,7 +1640,7 @@ class Query < ActiveRecord::Base
       if to.is_a?(Date)
         to = date_for_user_time_zone(to.year, to.month, to.day).end_of_day
       end
-      if self.class.default_timezone == :utc
+      if ActiveRecord.default_timezone == :utc
         to = to.utc
       end
       s << ("#{table}.#{field} <= '%s'" % [quoted_time(to, is_custom_filter)])
diff --git a/app/models/role.rb b/app/models/role.rb
index 078419c60..1665d7982 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -76,7 +76,7 @@ class Role < ActiveRecord::Base
   has_many :members, :through => :member_roles
   acts_as_positioned :scope => :builtin
 
-  serialize :permissions, ::Role::PermissionsAttributeCoder
+  serialize :permissions, coder: ::Role::PermissionsAttributeCoder
   store :settings, :accessors => [:permissions_all_trackers, :permissions_tracker_ids]
 
   validates_presence_of :name
diff --git a/app/views/custom_fields/_visibility_by_project_selector.html.erb b/app/views/custom_fields/_visibility_by_project_selector.html.erb
index d92e5cdab..25fd4978b 100644
--- a/app/views/custom_fields/_visibility_by_project_selector.html.erb
+++ b/app/views/custom_fields/_visibility_by_project_selector.html.erb
@@ -4,7 +4,7 @@
   <div id="custom_field_project_ids">
     <% project_ids = @custom_field.project_ids.to_a %>
     <%= render_project_nested_lists(Project.all) do |p|
-      content_tag('label', check_box_tag('custom_field[project_ids][]', p.id, project_ids.include?(p.id), :id => nil) + ' ' + p)
+      content_tag('label', check_box_tag('custom_field[project_ids][]', p.id, project_ids.include?(p.id), :id => nil) + ' ' + p.to_s)
     end %>
     <%= hidden_field_tag('custom_field[project_ids][]', '', :id => nil) %>
   </div>
diff --git a/config/application.rb b/config/application.rb
index 5e93df122..48e855c9b 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -23,13 +23,16 @@ module RedmineApp
     # Application configuration should go into files in config/initializers
     # -- all .rb files in that directory are automatically loaded.
 
-    # Custom directories with classes and modules you want to be autoloadable.
-    config.autoloader = :zeitwerk
+    # Adds `lib` to `config.autoload_paths` and `config.eager_load_paths`.
+    config.autoload_lib(ignore: %w(tasks generators plugins))
 
     # Only load the plugins named here, in the order given (default is alphabetical).
     # :all can be used as a placeholder for all plugins not explicitly named.
     # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
 
+    config.active_support.remove_deprecated_time_with_zone_name = true
+    config.active_support.cache_format_version = 7.0
+
     config.active_record.store_full_sti_class = true
     config.active_record.default_timezone = :local
     config.active_record.yaml_column_permitted_classes = [
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 34056df74..199f1bb27 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -30,7 +30,7 @@ Rails.application.configure do
   config.cache_store = :null_store
 
   # Raise exceptions instead of rendering exception templates.
-  config.action_dispatch.show_exceptions = true
+  config.action_dispatch.show_exceptions = :all
 
   # Disable request forgery protection in test environment.
   config.action_controller.allow_forgery_protection = false
diff --git a/config/initializers/10-patches.rb b/config/initializers/10-patches.rb
index 4bca5edf4..adac86583 100644
--- a/config/initializers/10-patches.rb
+++ b/config/initializers/10-patches.rb
@@ -47,20 +47,6 @@ module ActionView
       end
     end
   end
-
-  class Resolver
-    def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
-      locals = locals.map(&:to_s).sort!.freeze
-
-      cached(key, [name, prefix, partial], details, locals) do
-        if (details[:formats] & [:xml, :json]).any?
-          details = details.dup
-          details[:formats] = details[:formats].dup + [:api]
-        end
-        _find_all(name, prefix, partial, details, key, locals)
-      end
-    end
-  end
 end
 
 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || ''.html_safe }
@@ -69,17 +55,14 @@ ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || '
 module ActionView
   module Helpers
     module Tags
-      class Base
-        private
-        alias :add_options_without_non_empty_blank_option :add_options
+      SelectRenderer.prepend(Module.new do
         def add_options(option_tags, options, value = nil)
-          if options[:include_blank] == true
-            options = options.dup
-            options[:include_blank] = '&nbsp;'.html_safe
+          if options.delete(:include_blank)
+            options[:prompt] = '&nbsp;'.html_safe
           end
-          add_options_without_non_empty_blank_option(option_tags, options, value)
+          super
         end
-      end
+      end)
     end
 
     module FormHelper
@@ -156,6 +139,29 @@ module ActionController
   end
 end
 
+module ActionView
+  LookupContext.prepend(Module.new do
+    def formats=(values)
+      if (Array(values) & [:xml, :json]).any?
+        values << :api
+      end
+      super values
+    end
+  end)
+
+  Rendering.prepend(Module.new do
+    def rendered_format
+      if lookup_context.formats.first == :api
+        return request.format
+      end
+
+      super
+    end
+  end)
+end
+
+Mime::SET << 'api'
+
 # Adds asset_id parameters to assets like Rails 3 to invalidate caches in browser
 module ActionView
   module Helpers
diff --git a/config/initializers/zeitwerk.rb b/config/initializers/zeitwerk.rb
index ab86b28e2..c9f7286d6 100644
--- a/config/initializers/zeitwerk.rb
+++ b/config/initializers/zeitwerk.rb
@@ -1,9 +1,6 @@
 # frozen_string_literal: true
 
 lib = Rails.root.join('lib/redmine')
-Rails.autoloaders.main.push_dir lib, namespace: Redmine
-Rails.application.config.watchable_dirs[lib] = [:rb]
-
 IGNORE_LIST = [
   'wiki_formatting/textile/redcloth3.rb',
   'core_ext.rb',
diff --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb
index 79e310f31..85e20f383 100644
--- a/lib/redmine/plugin.rb
+++ b/lib/redmine/plugin.rb
@@ -467,7 +467,7 @@ module Redmine
           else
             migrations
           end
-        Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
+        Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
       end
 
       def down(target_version = nil)
@@ -477,15 +477,15 @@ module Redmine
           else
             migrations
           end
-        Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
+        Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
       end
 
       def run(direction, target_version)
-        Migrator.new(direction, migrations, schema_migration, target_version).run
+        Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
       end
 
       def open
-        Migrator.new(:up, migrations, schema_migration)
+        Migrator.new(:up, migrations, schema_migration, internal_metadata)
       end
 
       def current_version
@@ -510,7 +510,7 @@ module Redmine
           # Delete migrations that don't match .. to_i will work because the number comes first
           @all_versions ||= {}
           @all_versions[plugin.id.to_s] ||= begin
-            sm_table = ::ActiveRecord::SchemaMigration.table_name
+            sm_table = ::ActiveRecord::Base.connection.schema_migration.table_name
             migration_versions  = ActiveRecord::Base.connection.select_values("SELECT version FROM #{sm_table}")
             versions_by_plugins = migration_versions.group_by {|version| version.match(/-(.*)$/).try(:[], 1)}
             @all_versions       = versions_by_plugins.transform_values! {|versions| versions.map!(&:to_i).sort!}
diff --git a/test/fixtures/issues.yml b/test/fixtures/issues.yml
index 1c2c37fa5..7092c176a 100644
--- a/test/fixtures/issues.yml
+++ b/test/fixtures/issues.yml
@@ -1,8 +1,8 @@
 ---
 issues_001:
-  created_on: <%= 3.days.ago.to_s(:db) %>
+  created_on: <%= 3.days.ago.to_fs(:db) %>
   project_id: 1
-  updated_on: <%= 1.day.ago.to_s(:db) %>
+  updated_on: <%= 1.day.ago.to_fs(:db) %>
   priority_id: 4
   subject: Cannot print recipes
   id: 1
@@ -13,8 +13,8 @@ issues_001:
   assigned_to_id:
   author_id: 2
   status_id: 1
-  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
-  due_date: <%= 10.day.from_now.to_date.to_s(:db) %>
+  start_date: <%= 1.day.ago.to_date.to_fs(:db) %>
+  due_date: <%= 10.day.from_now.to_date.to_fs(:db) %>
   estimated_hours: 200.0
   root_id: 1
   lft: 1
@@ -34,7 +34,7 @@ issues_002:
   assigned_to_id: 3
   author_id: 2
   status_id: 2
-  start_date: <%= 2.day.ago.to_date.to_s(:db) %>
+  start_date: <%= 2.day.ago.to_date.to_fs(:db) %>
   due_date:
   estimated_hours: 0.5
   root_id: 2
@@ -56,16 +56,16 @@ issues_003:
   assigned_to_id: 3
   author_id: 2
   status_id: 1
-  start_date: <%= 15.day.ago.to_date.to_s(:db) %>
-  due_date: <%= 5.day.ago.to_date.to_s(:db) %>
+  start_date: <%= 15.day.ago.to_date.to_fs(:db) %>
+  due_date: <%= 5.day.ago.to_date.to_fs(:db) %>
   estimated_hours: 1.0
   root_id: 3
   lft: 1
   rgt: 2
 issues_004:
-  created_on: <%= 5.days.ago.to_s(:db) %>
+  created_on: <%= 5.days.ago.to_fs(:db) %>
   project_id: 2
-  updated_on: <%= 2.days.ago.to_s(:db) %>
+  updated_on: <%= 2.days.ago.to_fs(:db) %>
   priority_id: 4
   subject: Issue on project 2
   id: 4
@@ -80,9 +80,9 @@ issues_004:
   lft: 1
   rgt: 2
 issues_005:
-  created_on: <%= 5.days.ago.to_s(:db) %>
+  created_on: <%= 5.days.ago.to_fs(:db) %>
   project_id: 3
-  updated_on: <%= 2.days.ago.to_s(:db) %>
+  updated_on: <%= 2.days.ago.to_fs(:db) %>
   priority_id: 4
   subject: Subproject issue
   id: 5
@@ -98,9 +98,9 @@ issues_005:
   lft: 1
   rgt: 2
 issues_006:
-  created_on: <%= 1.minute.ago.to_s(:db) %>
+  created_on: <%= 1.minute.ago.to_fs(:db) %>
   project_id: 5
-  updated_on: <%= 1.minute.ago.to_s(:db) %>
+  updated_on: <%= 1.minute.ago.to_fs(:db) %>
   priority_id: 4
   subject: Issue of a private subproject
   id: 6
@@ -111,15 +111,15 @@ issues_006:
   assigned_to_id:
   author_id: 2
   status_id: 1
-  start_date: <%= Date.today.to_s(:db) %>
-  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+  start_date: <%= Date.today.to_fs(:db) %>
+  due_date: <%= 1.days.from_now.to_date.to_fs(:db) %>
   root_id: 6
   lft: 1
   rgt: 2
 issues_007:
-  created_on: <%= 10.days.ago.to_s(:db) %>
+  created_on: <%= 10.days.ago.to_fs(:db) %>
   project_id: 1
-  updated_on: <%= 10.days.ago.to_s(:db) %>
+  updated_on: <%= 10.days.ago.to_fs(:db) %>
   priority_id: 5
   subject: Issue due today
   id: 7
@@ -130,16 +130,16 @@ issues_007:
   assigned_to_id:
   author_id: 2
   status_id: 1
-  start_date: <%= 10.days.ago.to_s(:db) %>
-  due_date: <%= Date.today.to_s(:db) %>
+  start_date: <%= 10.days.ago.to_fs(:db) %>
+  due_date: <%= Date.today.to_fs(:db) %>
   lock_version: 0
   root_id: 7
   lft: 1
   rgt: 2
 issues_008:
-  created_on: <%= 10.days.ago.to_s(:db) %>
+  created_on: <%= 10.days.ago.to_fs(:db) %>
   project_id: 1
-  updated_on: <%= 10.days.ago.to_s(:db) %>
+  updated_on: <%= 10.days.ago.to_fs(:db) %>
   priority_id: 5
   subject: Closed issue
   id: 8
@@ -156,11 +156,11 @@ issues_008:
   root_id: 8
   lft: 1
   rgt: 2
-  closed_on: <%= 3.days.ago.to_s(:db) %>
+  closed_on: <%= 3.days.ago.to_fs(:db) %>
 issues_009:
-  created_on: <%= 1.minute.ago.to_s(:db) %>
+  created_on: <%= 1.minute.ago.to_fs(:db) %>
   project_id: 5
-  updated_on: <%= 1.minute.ago.to_s(:db) %>
+  updated_on: <%= 1.minute.ago.to_fs(:db) %>
   priority_id: 5
   subject: Blocked Issue
   id: 9
@@ -171,15 +171,15 @@ issues_009:
   assigned_to_id:
   author_id: 2
   status_id: 1
-  start_date: <%= Date.today.to_s(:db) %>
-  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+  start_date: <%= Date.today.to_fs(:db) %>
+  due_date: <%= 1.days.from_now.to_date.to_fs(:db) %>
   root_id: 9
   lft: 1
   rgt: 2
 issues_010:
-  created_on: <%= 1.minute.ago.to_s(:db) %>
+  created_on: <%= 1.minute.ago.to_fs(:db) %>
   project_id: 5
-  updated_on: <%= 1.minute.ago.to_s(:db) %>
+  updated_on: <%= 1.minute.ago.to_fs(:db) %>
   priority_id: 5
   subject: Issue Doing the Blocking
   id: 10
@@ -190,15 +190,15 @@ issues_010:
   assigned_to_id:
   author_id: 2
   status_id: 1
-  start_date: <%= Date.today.to_s(:db) %>
-  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+  start_date: <%= Date.today.to_fs(:db) %>
+  due_date: <%= 1.days.from_now.to_date.to_fs(:db) %>
   root_id: 10
   lft: 1
   rgt: 2
 issues_011:
-  created_on: <%= 3.days.ago.to_s(:db) %>
+  created_on: <%= 3.days.ago.to_fs(:db) %>
   project_id: 1
-  updated_on: <%= 1.day.ago.to_s(:db) %>
+  updated_on: <%= 1.day.ago.to_fs(:db) %>
   priority_id: 5
   subject: Closed issue on a closed version
   id: 11
@@ -209,16 +209,16 @@ issues_011:
   assigned_to_id:
   author_id: 2
   status_id: 5
-  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
+  start_date: <%= 1.day.ago.to_date.to_fs(:db) %>
   due_date:
   root_id: 11
   lft: 1
   rgt: 2
-  closed_on: <%= 1.day.ago.to_s(:db) %>
+  closed_on: <%= 1.day.ago.to_fs(:db) %>
 issues_012:
-  created_on: <%= 3.days.ago.to_s(:db) %>
+  created_on: <%= 3.days.ago.to_fs(:db) %>
   project_id: 1
-  updated_on: <%= 1.day.ago.to_s(:db) %>
+  updated_on: <%= 1.day.ago.to_fs(:db) %>
   priority_id: 5
   subject: Closed issue on a locked version
   id: 12
@@ -229,16 +229,16 @@ issues_012:
   assigned_to_id:
   author_id: 3
   status_id: 5
-  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
+  start_date: <%= 1.day.ago.to_date.to_fs(:db) %>
   due_date:
   root_id: 12
   lft: 1
   rgt: 2
-  closed_on: <%= 1.day.ago.to_s(:db) %>
+  closed_on: <%= 1.day.ago.to_fs(:db) %>
 issues_013:
-  created_on: <%= 5.days.ago.to_s(:db) %>
+  created_on: <%= 5.days.ago.to_fs(:db) %>
   project_id: 3
-  updated_on: <%= 2.days.ago.to_s(:db) %>
+  updated_on: <%= 2.days.ago.to_fs(:db) %>
   priority_id: 4
   subject: Subproject issue two
   id: 13
@@ -254,9 +254,9 @@ issues_013:
   rgt: 2
 issues_014:
   id: 14
-  created_on: <%= 15.days.ago.to_s(:db) %>
+  created_on: <%= 15.days.ago.to_fs(:db) %>
   project_id: 3
-  updated_on: <%= 15.days.ago.to_s(:db) %>
+  updated_on: <%= 15.days.ago.to_fs(:db) %>
   priority_id: 5
   subject: Private issue on public project
   fixed_version_id:
diff --git a/test/fixtures/journals.yml b/test/fixtures/journals.yml
index e6cbd95cf..0950e01fd 100644
--- a/test/fixtures/journals.yml
+++ b/test/fixtures/journals.yml
@@ -1,7 +1,7 @@
 ---
 journals_001:
-  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 2.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
   notes: "Journal notes"
   id: 1
   journalized_type: Issue
@@ -9,24 +9,24 @@ journals_001:
   journalized_id: 1
   updated_by_id: 1
 journals_002:
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
   notes: "Some notes with Redmine links: #2, r2."
   id: 2
   journalized_type: Issue
   user_id: 2
   journalized_id: 1
 journals_003:
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
   notes: "A comment with inline image: !picture.jpg! and a reference to #1 and r2."
   id: 3
   journalized_type: Issue
   user_id: 2
   journalized_id: 2
 journals_004:
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
   notes: "A comment with a private version."
   id: 4
   journalized_type: Issue
@@ -34,8 +34,8 @@ journals_004:
   journalized_id: 6
 journals_005:
   id: 5
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
   notes: "A comment on a private issue."
   user_id: 2
   journalized_type: Issue
diff --git a/test/fixtures/messages.yml b/test/fixtures/messages.yml
index b193599d5..5b5fbed35 100644
--- a/test/fixtures/messages.yml
+++ b/test/fixtures/messages.yml
@@ -45,8 +45,8 @@ messages_004:
   parent_id: 
   board_id: 1
 messages_005: 
-  created_on: <%= 3.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 3.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 3.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 3.days.ago.to_date.to_fs(:db) %>
   subject: 'RE: post 2'
   id: 5
   replies_count: 0
@@ -56,8 +56,8 @@ messages_005:
   parent_id: 4
   board_id: 1
 messages_006: 
-  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 2.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 2.days.ago.to_date.to_fs(:db) %>
   subject: 'RE: post 2'
   id: 6
   replies_count: 0
@@ -67,8 +67,8 @@ messages_006:
   parent_id: 4
   board_id: 1
 messages_007: 
-  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
+  created_on: <%= 2.days.ago.to_date.to_fs(:db) %>
+  updated_on: <%= 2.days.ago.to_date.to_fs(:db) %>
   subject: 'Message on a private project'
   id: 7
   replies_count: 0
diff --git a/test/fixtures/versions.yml b/test/fixtures/versions.yml
index 8312666e4..c0c733702 100644
--- a/test/fixtures/versions.yml
+++ b/test/fixtures/versions.yml
@@ -16,7 +16,7 @@ versions_002:
   updated_on: 2006-07-19 21:00:33 +02:00
   id: 2
   description: Stable release
-  effective_date: <%= 20.day.from_now.to_date.to_s(:db) %>
+  effective_date: <%= 20.day.from_now.to_date.to_fs(:db) %>
   status: locked
   sharing: 'none'
   wiki_page_title: ECookBookV1
diff --git a/test/integration/layout_test.rb b/test/integration/layout_test.rb
index 6918b11f9..662ca55ca 100644
--- a/test/integration/layout_test.rb
+++ b/test/integration/layout_test.rb
@@ -48,8 +48,8 @@ class LayoutTest < Redmine::IntegrationTest
   def test_top_menu_and_search_not_visible_when_login_required
     with_settings :login_required => '1' do
       get '/'
-      assert_select "#top-menu > ul", 0
-      assert_select "#quick-search", 0
+
+      assert_equal response.status, 302
     end
   end
 
diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb
index bb3eecb04..f6172dea7 100644
--- a/test/unit/query_test.rb
+++ b/test/unit/query_test.rb
@@ -1549,13 +1549,13 @@ class QueryTest < ActiveSupport::TestCase
     query = IssueQuery.new(:name => '_')
     filter_name = "fixed_version.due_date"
     assert_include filter_name, query.available_filters.keys
-    query.filters = {filter_name => {:operator => '=', :values => [20.day.from_now.to_date.to_s(:db)]}}
+    query.filters = {filter_name => {:operator => '=', :values => [20.day.from_now.to_date.to_fs(:db)]}}
     issues = find_issues_with_query(query)
     assert_equal [2], issues.map(&:fixed_version_id).uniq.sort
     assert_equal [2, 12], issues.map(&:id).sort
 
     query = IssueQuery.new(:name => '_')
-    query.filters = {filter_name => {:operator => '>=', :values => [21.day.from_now.to_date.to_s(:db)]}}
+    query.filters = {filter_name => {:operator => '>=', :values => [21.day.from_now.to_date.to_fs(:db)]}}
     assert_equal 0, find_issues_with_query(query).size
   end
 
@@ -2962,7 +2962,7 @@ class QueryTest < ActiveSupport::TestCase
     User.current.pref.update_attribute :time_zone, 'Hawaii'
 
     # assume timestamps are stored as utc
-    ActiveRecord::Base.default_timezone = :utc
+    ActiveRecord.default_timezone = :utc
 
     from = Date.parse '2016-03-20'
     to = Date.parse '2016-03-22'
@@ -2973,7 +2973,7 @@ class QueryTest < ActiveSupport::TestCase
     t = Time.new(2016, 3, 23, 9, 59, 59, 0).end_of_hour
     assert_equal "table.field > '#{Query.connection.quoted_date f}' AND table.field <= '#{Query.connection.quoted_date t}'", c
   ensure
-    ActiveRecord::Base.default_timezone = :local # restore Redmine default
+    ActiveRecord.default_timezone = :local # restore Redmine default
   end
 
   def test_project_statement_with_closed_subprojects
diff --git a/test/unit/user_query_test.rb b/test/unit/user_query_test.rb
index 9bb9c816d..d7c4b5f29 100644
--- a/test/unit/user_query_test.rb
+++ b/test/unit/user_query_test.rb
@@ -186,7 +186,7 @@ class UserQueryTest < ActiveSupport::TestCase
     users = q.results_scope
 
     assert_equal 2, users.size
-    assert_equal [2, 1], users.ids
+    assert_equal [2, 1], users.pluck(:id)
   end
 
   def find_users_with_query(query)
-- 
2.39.2

