From e7263fcedbfca05bcaee9836e4cbbd6b246c8ac1 Mon Sep 17 00:00:00 2001 From: ulferts Date: Mon, 2 Sep 2019 16:14:43 +0200 Subject: [PATCH] migrate to rails 6.0.0 --- .codeclimate.yml | 4 +- Gemfile | 13 +- Gemfile.lock | 222 ++++++++++-------- app/controllers/highlighting_controller.rb | 2 +- app/controllers/projects_controller.rb | 23 +- app/models/auth_source.rb | 9 +- app/models/category.rb | 6 +- app/models/enabled_module.rb | 5 +- app/models/menu_item.rb | 10 +- app/models/project.rb | 16 +- app/models/role.rb | 7 +- app/models/status.rb | 8 +- app/models/type.rb | 14 +- app/models/version.rb | 7 +- app/services/authorization/abstract_query.rb | 3 +- config/application.rb | 7 + config/cable.yml | 10 + lib/open_project/plugins/module_handler.rb | 1 + .../lib/acts_as_watchable.rb | 18 +- modules/bcf/openproject-bcf.gemspec | 1 - .../app/controllers/api/v3/grids/grids_api.rb | 4 +- .../reporting/openproject-reporting.gemspec | 2 +- modules/webhooks/spec/lib/hook_spec.rb | 1 - .../projects/shared_contract_examples.rb | 2 +- spec/lib/open_project/configuration_spec.rb | 4 +- spec/models/application_record_spec.rb | 2 +- spec/support/shared/with_settings.rb | 2 +- spec_legacy/unit/lib/redmine/hook_spec.rb | 2 +- spec_legacy/unit/project_spec.rb | 6 +- 29 files changed, 233 insertions(+), 178 deletions(-) create mode 100644 config/cable.yml diff --git a/.codeclimate.yml b/.codeclimate.yml index f4141a75489..b05573788b1 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -27,8 +27,10 @@ checks: plugins: rubocop: enabled: true + # Codeclimate uses brakeman 4.3.1 which does not support rails 6 + # Check https://docs.codeclimate.com/docs/brakeman for updates. brakeman: - enabled: true + enabled: false # as long as bundler-audit does not support bundler 2.0 we disable it bundler-audit: enabled: false diff --git a/Gemfile b/Gemfile index 5afacf76d4c..629a0e1c5bc 100644 --- a/Gemfile +++ b/Gemfile @@ -34,8 +34,8 @@ gem 'actionpack-xml_parser', '~> 2.0.0' gem 'activemodel-serializers-xml', '~> 1.0.1' gem 'activerecord-import', '~> 0.28.1' gem 'activerecord-session_store', '~> 1.1.0' -gem 'rails', '~> 5.2.2.1' -gem 'responders', '~> 2.4' +gem 'rails', git: 'https://github.com/rails/rails', ref: '6-0-stable' +gem 'responders', '~> 3.0' gem 'rdoc', '>= 2.4.2' @@ -50,7 +50,8 @@ gem 'warden-basic_auth', '~> 0.2.1' gem 'will_paginate', '~> 3.1.7' -gem 'friendly_id', '~> 5.2.1' +# Replace once friendly_id release supports rails 6 +gem 'friendly_id', git: 'https://github.com/norman/friendly_id', ref: '67422c04e1bfed4207b2a04826bc67ec0e231ce7' gem 'acts_as_list', '~> 0.9.9' gem 'acts_as_tree', '~> 2.8.0' @@ -107,7 +108,7 @@ gem 'multi_json', '~> 1.13.1' gem 'oj', '~> 3.7.0' gem 'daemons' -gem 'delayed_job_active_record', '~> 4.1.1' +gem 'delayed_job_active_record', '~> 4.1.4' gem 'rack-protection', '~> 2.0.0' @@ -177,7 +178,7 @@ gem 'aws-sdk-core', '~> 3.46.0' # File upload via fog + screenshots on travis gem 'aws-sdk-s3', '~> 1.30.1' -gem 'openproject-token', '~> 1.0.1' +gem 'openproject-token', '~> 1.0.2' gem 'plaintext', '~> 0.3.2' @@ -202,7 +203,7 @@ group :test do gem 'test-prof', '~> 0.7.3' gem 'cucumber', '~> 3.1.0' - gem 'cucumber-rails', '~> 1.6.0', require: false + gem 'cucumber-rails', '~> 1.8.0', require: false gem 'database_cleaner', '~> 1.6' gem 'rack_session_access' gem 'rspec', '~> 3.8.0' diff --git a/Gemfile.lock b/Gemfile.lock index 0b6b36697ff..f73e4294c51 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,6 +47,14 @@ GIT capybara rspec +GIT + remote: https://github.com/norman/friendly_id + revision: 67422c04e1bfed4207b2a04826bc67ec0e231ce7 + ref: 67422c04e1bfed4207b2a04826bc67ec0e231ce7 + specs: + friendly_id (5.2.5) + activerecord (>= 4.0.0) + GIT remote: https://github.com/opf/omniauth revision: fe862f986b2e846e291784d2caa3d90a658c67f0 @@ -73,6 +81,88 @@ GIT specs: dalli (2.7.9) +GIT + remote: https://github.com/rails/rails + revision: d46534f46b197fe76f97a2613e68dae80ba298f8 + ref: 6-0-stable + specs: + actioncable (6.0.0) + actionpack (= 6.0.0) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailbox (6.0.0) + actionpack (= 6.0.0) + activejob (= 6.0.0) + activerecord (= 6.0.0) + activestorage (= 6.0.0) + activesupport (= 6.0.0) + mail (>= 2.7.1) + actionmailer (6.0.0) + actionpack (= 6.0.0) + actionview (= 6.0.0) + activejob (= 6.0.0) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (6.0.0) + actionview (= 6.0.0) + activesupport (= 6.0.0) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.0.0) + actionpack (= 6.0.0) + activerecord (= 6.0.0) + activestorage (= 6.0.0) + activesupport (= 6.0.0) + nokogiri (>= 1.8.5) + actionview (6.0.0) + activesupport (= 6.0.0) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + activejob (6.0.0) + activesupport (= 6.0.0) + globalid (>= 0.3.6) + activemodel (6.0.0) + activesupport (= 6.0.0) + activerecord (6.0.0) + activemodel (= 6.0.0) + activesupport (= 6.0.0) + activestorage (6.0.0) + actionpack (= 6.0.0) + activejob (= 6.0.0) + activerecord (= 6.0.0) + marcel (~> 0.3.1) + activesupport (6.0.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.1, >= 2.1.8) + rails (6.0.0) + actioncable (= 6.0.0) + actionmailbox (= 6.0.0) + actionmailer (= 6.0.0) + actionpack (= 6.0.0) + actiontext (= 6.0.0) + actionview (= 6.0.0) + activejob (= 6.0.0) + activemodel (= 6.0.0) + activerecord (= 6.0.0) + activestorage (= 6.0.0) + activesupport (= 6.0.0) + bundler (>= 1.3.0) + railties (= 6.0.0) + sprockets-rails (>= 2.0.0) + railties (6.0.0) + actionpack (= 6.0.0) + activesupport (= 6.0.0) + method_source + rake (>= 0.8.7) + thor (>= 0.20.3, < 2.0) + GIT remote: https://github.com/rspec/rspec-activemodel-mocks revision: 6136a778f8b21f4f45f6b4ad5c2e2533e6d4ddc6 @@ -121,7 +211,6 @@ PATH specs: openproject-bcf (1.0.0) activerecord-import - rails (~> 5) rubyzip (~> 1.2) PATH @@ -221,7 +310,7 @@ PATH remote: modules/reporting specs: openproject-reporting (1.0.0) - jquery-tablesorter (~> 1.25.5) + jquery-tablesorter (~> 1.27.0) openproject-costs reporting_engine @@ -248,45 +337,13 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (1.0.3) - actioncable (5.2.2.1) - actionpack (= 5.2.2.1) - nio4r (~> 2.0) - websocket-driver (>= 0.6.1) - actionmailer (5.2.2.1) - actionpack (= 5.2.2.1) - actionview (= 5.2.2.1) - activejob (= 5.2.2.1) - mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 2.0) - actionpack (5.2.2.1) - actionview (= 5.2.2.1) - activesupport (= 5.2.2.1) - rack (~> 2.0) - rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) actionpack-xml_parser (2.0.1) actionpack (>= 5.0) railties (>= 5.0) - actionview (5.2.2.1) - activesupport (= 5.2.2.1) - builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.2.1) - activesupport (= 5.2.2.1) - globalid (>= 0.3.6) - activemodel (5.2.2.1) - activesupport (= 5.2.2.1) activemodel-serializers-xml (1.0.2) activemodel (> 5.x) activesupport (> 5.x) builder (~> 3.1) - activerecord (5.2.2.1) - activemodel (= 5.2.2.1) - activesupport (= 5.2.2.1) - arel (>= 9.0) activerecord-import (0.28.1) activerecord (>= 3.2) activerecord-nulldb-adapter (0.3.9) @@ -297,15 +354,6 @@ GEM multi_json (~> 1.11, >= 1.11.2) rack (>= 1.5.2, < 3) railties (>= 4.0) - activestorage (5.2.2.1) - actionpack (= 5.2.2.1) - activerecord (= 5.2.2.1) - marcel (~> 0.3.1) - activesupport (5.2.2.1) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) acts_as_list (0.9.19) activerecord (>= 3.0) acts_as_tree (2.8.0) @@ -318,7 +366,6 @@ GEM airbrake-ruby (~> 3.0) airbrake-ruby (3.1.0) tdigest (= 0.1.1) - arel (9.0.0) ast (2.4.0) attr_required (1.0.1) autoprefixer-rails (9.4.7) @@ -347,7 +394,7 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) - backports (3.11.4) + backports (3.15.0) bcrypt (3.1.12) bindata (2.4.4) binding_of_caller (0.8.0) @@ -419,12 +466,12 @@ GEM cucumber-tag_expressions (~> 1.1.0) gherkin (~> 5.0) cucumber-expressions (6.0.1) - cucumber-rails (1.6.0) - capybara (>= 1.1.2, < 4) + cucumber-rails (1.8.0) + capybara (>= 2.12, < 4) cucumber (>= 3.0.2, < 4) - mime-types (>= 1.17, < 4) + mime-types (>= 2.0, < 4) nokogiri (~> 1.8) - railties (>= 4, < 6) + railties (>= 4.2, < 7) cucumber-tag_expressions (1.1.1) cucumber-wire (0.0.1) daemons (1.3.1) @@ -457,10 +504,10 @@ GEM declarative-builder (0.1.0) declarative-option (< 0.2.0) declarative-option (0.1.0) - delayed_job (4.1.5) - activesupport (>= 3.0, < 5.3) - delayed_job_active_record (4.1.3) - activerecord (>= 3.0, < 5.3) + delayed_job (4.1.8) + activesupport (>= 3.0, < 6.1) + delayed_job_active_record (4.1.4) + activerecord (>= 3.0, < 6.1) delayed_job (>= 3.0, < 5) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -515,8 +562,6 @@ GEM fog-core nokogiri (>= 1.5.11, < 2.0.0) formatador (0.2.5) - friendly_id (5.2.5) - activerecord (>= 4.0.0) fuubar (2.3.2) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) @@ -560,8 +605,8 @@ GEM iso8601 (0.12.1) jaro_winkler (1.5.2) jmespath (1.4.0) - jquery-tablesorter (1.25.5) - railties (>= 3.2, < 6) + jquery-tablesorter (1.27.0) + railties (~> 6.0.0, >= 3.2) json (1.8.6) json-jwt (1.10.0) activesupport (>= 4.2) @@ -606,11 +651,11 @@ GEM meta-tags (2.11.1) actionpack (>= 3.2.0, < 6.1) method_source (0.9.2) - mime-types (3.2.2) + mime-types (3.3) mime-types-data (~> 3.2015) - mime-types-data (3.2018.0812) + mime-types-data (3.2019.0904) mimemagic (0.3.3) - mini_mime (1.0.1) + mini_mime (1.0.2) mini_portile2 (2.4.0) minisyntax (0.2.5) minitest (5.11.3) @@ -626,7 +671,7 @@ GEM net-ldap (0.16.1) netrc (0.11.0) newrelic_rpm (6.0.0.351) - nio4r (2.3.1) + nio4r (2.5.1) no_proxy_fix (0.1.2) nokogiri (1.10.4) mini_portile2 (~> 2.4.0) @@ -650,8 +695,7 @@ GEM validate_email validate_url webfinger (>= 1.0.1) - openproject-token (1.0.1) - activemodel (~> 5.0) + openproject-token (1.0.2) parallel (1.13.0) parallel_tests (2.27.1) parallel @@ -695,10 +739,10 @@ GEM pry-stack_explorer (0.4.9.3) binding_of_caller (>= 0.7) pry (>= 0.9.11) - public_suffix (3.0.3) + public_suffix (3.1.1) puma (4.0.0) nio4r (~> 2.0) - rack (2.0.6) + rack (2.0.7) rack-accept (0.4.5) rack (>= 0.4) rack-attack (5.4.2) @@ -718,19 +762,6 @@ GEM rack_session_access (0.2.0) builder (>= 2.0.0) rack (>= 1.0.0) - rails (5.2.2.1) - actioncable (= 5.2.2.1) - actionmailer (= 5.2.2.1) - actionpack (= 5.2.2.1) - actionview (= 5.2.2.1) - activejob (= 5.2.2.1) - activemodel (= 5.2.2.1) - activerecord (= 5.2.2.1) - activestorage (= 5.2.2.1) - activesupport (= 5.2.2.1) - bundler (>= 1.3.0) - railties (= 5.2.2.1) - sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.4) actionpack (>= 5.0.1.x) actionview (>= 5.0.1.x) @@ -738,22 +769,16 @@ GEM rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.0.4) + rails-html-sanitizer (1.2.0) loofah (~> 2.2, >= 2.2.2) rails_12factor (0.0.3) rails_serve_static_assets rails_stdout_logging rails_serve_static_assets (0.0.5) rails_stdout_logging (0.0.5) - railties (5.2.2.1) - actionpack (= 5.2.2.1) - activesupport (= 5.2.2.1) - method_source - rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) rainbow (3.0.0) raindrops (0.19.0) - rake (12.3.2) + rake (12.3.3) rbtree (0.4.2) rdoc (6.1.1) recaptcha (5.1.0) @@ -765,16 +790,16 @@ GEM reform-rails (0.1.7) activemodel (>= 3.2) reform (>= 2.2.0) - regexp_parser (1.3.0) + regexp_parser (1.6.0) representable (3.0.4) declarative (< 0.1.0) declarative-option (< 0.2.0) uber (< 0.2.0) request_store (1.4.1) rack (>= 1.4) - responders (2.4.1) - actionpack (>= 4.2.0, < 6.0) - railties (>= 4.2.0, < 6.0) + responders (3.0.0) + actionpack (>= 5.0) + railties (>= 5.0) rest-client (2.0.2) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) @@ -941,12 +966,13 @@ GEM addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - websocket-driver (0.7.0) + websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.3) + websocket-extensions (0.1.4) will_paginate (3.1.7) xpath (3.2.0) nokogiri (~> 1.8) + zeitwerk (2.1.10) PLATFORMS ruby @@ -978,7 +1004,7 @@ DEPENDENCIES cells-rails (~> 0.0.9) commonmarker (~> 0.20.1) cucumber (~> 3.1.0) - cucumber-rails (~> 1.6.0) + cucumber-rails (~> 1.8.0) daemons dalli! danger (~> 6.0.9) @@ -987,7 +1013,7 @@ DEPENDENCIES database_cleaner (~> 1.6) date_validator (~> 0.9.0) deckar01-task_list (= 2.2.0) - delayed_job_active_record (~> 4.1.1) + delayed_job_active_record (~> 4.1.4) doorkeeper! equivalent-xml (~> 0.6) escape_utils (~> 1.0) @@ -996,7 +1022,7 @@ DEPENDENCIES faker flamegraph fog-aws - friendly_id (~> 5.2.1) + friendly_id! fuubar (~> 2.3.2) gon (~> 6.2.1) grape (~> 1.2.3) @@ -1039,7 +1065,7 @@ DEPENDENCIES openproject-pdf_export! openproject-recaptcha! openproject-reporting! - openproject-token (~> 1.0.1) + openproject-token (~> 1.0.2) openproject-translations! openproject-two_factor_authentication! openproject-webhooks! @@ -1062,7 +1088,7 @@ DEPENDENCIES rack-protection (~> 2.0.0) rack-test (~> 1.1.0) rack_session_access - rails (~> 5.2.2.1) + rails! rails-controller-testing (~> 1.0.2) rails_12factor rdoc (>= 2.4.2) @@ -1070,7 +1096,7 @@ DEPENDENCIES reform-rails (~> 0.1.7) reporting_engine! request_store (~> 1.4.1) - responders (~> 2.4) + responders (~> 3.0) rest-client (~> 2.0) retriable (~> 3.1.1) rinku (~> 2.0.4) diff --git a/app/controllers/highlighting_controller.rb b/app/controllers/highlighting_controller.rb index 74e5beb05b2..a2494b2cc33 100644 --- a/app/controllers/highlighting_controller.rb +++ b/app/controllers/highlighting_controller.rb @@ -46,7 +46,7 @@ class HighlightingController < ApplicationController private def determine_freshness - @max_updated_at = helpers.highlight_css_updated_at || Time.now.iso8601 + @max_updated_at = helpers.highlight_css_updated_at.to_s || Time.now.iso8601 @highlight_version_tag = helpers.highlight_css_version_tag(@max_updated_at) end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index c23e4f28164..a760e325ead 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -242,14 +242,10 @@ class ProjectsController < ApplicationController @query = ParamsToQueryService.new(Project, current_user).call(params) # Set default filter on status no filter is provided. - if !params[:filters] - @query.where('status', '=', Project::STATUS_ACTIVE.to_s) - end + @query.where('status', '=', Project::STATUS_ACTIVE.to_s) unless params[:filters] # Order lft if no order is provided. - if !params[:sortBy] - @query.order(lft: :asc) - end + @query.order(lft: :asc) unless params[:sortBy] @query end @@ -283,21 +279,18 @@ class ProjectsController < ApplicationController end def load_projects(query) - projects = query - .results - .with_required_storage - .with_latest_activity - .includes(:custom_values, :enabled_modules) - .page(page_param) - .per_page(per_page_param) - - filter_projects_by_permission projects + filter_projects_by_permission(query.results) + .with_required_storage + .with_latest_activity + .includes(:custom_values, :enabled_modules) + .paginate(page: page_param, per_page: per_page_param) end # Validates parent_id param according to user's permissions # TODO: move it to Project model in a validation that depends on User.current def validate_parent_id return true if User.current.admin? + parent_id = permitted_params.project && params[:project][:parent_id] if parent_id || @project.new_record? parent = parent_id.blank? ? nil : Project.find_by(id: parent_id.to_i) diff --git a/app/models/auth_source.rb b/app/models/auth_source.rb index 03b2df35879..9290d74b68b 100644 --- a/app/models/auth_source.rb +++ b/app/models/auth_source.rb @@ -32,17 +32,16 @@ class AuthSource < ActiveRecord::Base has_many :users - validates_presence_of :name - validates_uniqueness_of :name - validates_length_of :name, maximum: 60 + validates :name, + uniqueness: { case_sensitive: false }, + length: { maximum: 60 } def self.unique_attribute :name end prepend ::Mixins::UniqueFinder - def authenticate(_login, _password) - end + def authenticate(_login, _password); end def find_user(_login) raise "subclass repsonsiblity" diff --git a/app/models/category.rb b/app/models/category.rb index 98534256b24..c09088eac72 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -32,9 +32,9 @@ class Category < ActiveRecord::Base belongs_to :assigned_to, class_name: 'Principal', foreign_key: 'assigned_to_id' has_many :work_packages, foreign_key: 'category_id', dependent: :nullify - validates_presence_of :name - validates_uniqueness_of :name, scope: [:project_id] - validates_length_of :name, maximum: 255 + validates :name, + uniqueness: { scope: [:project_id], case_sensitive: true }, + length: { maximum: 255 } # validates that assignee is member of the issue category's project validates_each :assigned_to_id do |record, attr, value| diff --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb index dbbdb82a0bb..6736f81df99 100644 --- a/app/models/enabled_module.rb +++ b/app/models/enabled_module.rb @@ -30,8 +30,9 @@ class EnabledModule < ActiveRecord::Base belongs_to :project - validates_presence_of :name - validates_uniqueness_of :name, scope: :project_id + validates :name, + presence: true, + uniqueness: { scope: :project_id, case_sensitive: true } after_create :module_enabled diff --git a/app/models/menu_item.rb b/app/models/menu_item.rb index 3d005cd26b3..67b419ba62b 100644 --- a/app/models/menu_item.rb +++ b/app/models/menu_item.rb @@ -35,11 +35,13 @@ class MenuItem < ActiveRecord::Base serialize :options, Hash - validates_presence_of :title - validates_uniqueness_of :title, scope: [:navigatable_id, :type] + validates :title, + presence: true, + uniqueness: { scope: %i[navigatable_id type], case_sensitive: true } - validates_presence_of :name - validates_uniqueness_of :name, scope: [:navigatable_id, :parent_id] + validates :name, + presence: true, + uniqueness: { scope: %i[navigatable_id parent_id], case_sensitive: true } def setting if new_record? diff --git a/app/models/project.rb b/app/models/project.rb index 939524f0de4..30a9f6be250 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -153,21 +153,25 @@ class Project < ActiveRecord::Base author: nil, datetime: :created_on - validates_presence_of :name, :identifier + validates :name, + presence: true, + length: { maximum: 255 } # TODO: we temporarily disable this validation because it leads to failed tests # it implicitly assumes a db:seed-created standard type to be present and currently # neither development nor deployment setups are prepared for this # validates_presence_of :types - validates_uniqueness_of :identifier + validates :identifier, + presence: true, + uniqueness: { case_sensitive: true }, + length: { maximum: IDENTIFIER_MAX_LENGTH }, + exclusion: RESERVED_IDENTIFIERS + validates_associated :repository, :wiki - validates_length_of :name, maximum: 255 - validates_length_of :identifier, in: 1..IDENTIFIER_MAX_LENGTH # starts with lower-case letter, a-z, 0-9, dashes and underscores afterwards validates :identifier, format: { with: /\A[a-z][a-z0-9\-_]*\z/ }, if: ->(p) { p.identifier_changed? } # reserved words - validates_exclusion_of :identifier, in: RESERVED_IDENTIFIERS friendly_id :identifier, use: :finders @@ -178,7 +182,7 @@ class Project < ActiveRecord::Base where(["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s]) } scope :public_projects, -> { where(is_public: true) } - scope :visible, ->(user = User.current) { Project.visible_by(user) } + scope :visible, ->(user = User.current) { merge(Project.visible_by(user)) } scope :newest, -> { order(created_on: :desc) } def visible?(user = User.current) diff --git a/app/models/role.rb b/app/models/role.rb index 9a3cd6b9f0e..10c56ea7832 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -58,9 +58,10 @@ class Role < ActiveRecord::Base acts_as_list - validates_presence_of :name - validates_uniqueness_of :name - validates_length_of :name, maximum: 30 + validates :name, + presence: true, + length: { maximum: 30 }, + uniqueness: { case_sensitive: true } def self.givable where(builtin: NON_BUILTIN) diff --git a/app/models/status.rb b/app/models/status.rb index d89f82078d1..2c433908a50 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -40,9 +40,11 @@ class Status < ActiveRecord::Base before_destroy :delete_workflows - validates_presence_of :name - validates_uniqueness_of :name - validates_length_of :name, maximum: 30 + validates :name, + presence: true, + uniqueness: { case_sensitive: false }, + length: { maximum: 30 } + validates_inclusion_of :default_done_ratio, in: 0..100, allow_nil: true after_save :unmark_old_default_value, if: :is_default? diff --git a/app/models/type.rb b/app/models/type.rb index ece2677f52f..95f23fa014f 100644 --- a/app/models/type.rb +++ b/app/models/type.rb @@ -51,16 +51,16 @@ class ::Type < ActiveRecord::Base join_table: "#{table_name_prefix}custom_fields_types#{table_name_suffix}", association_foreign_key: 'custom_field_id' - belongs_to :color, class_name: 'Color', - foreign_key: 'color_id' + belongs_to :color, + class_name: 'Color', + foreign_key: 'color_id' acts_as_list - validates_presence_of :name - validates_uniqueness_of :name - validates_length_of :name, - maximum: 255, - unless: lambda { |e| e.name.blank? } + validates :name, + presence: true, + uniqueness: { case_sensitive: true }, + length: { maximum: 255 } validates_inclusion_of :is_default, :is_milestone, in: [true, false] diff --git a/app/models/version.rb b/app/models/version.rb index 919ca5196dd..de2b780716b 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -39,9 +39,10 @@ class Version < ActiveRecord::Base VERSION_STATUSES = %w(open locked closed).freeze VERSION_SHARINGS = %w(none descendants hierarchy tree system).freeze - validates_presence_of :name - validates_uniqueness_of :name, scope: [:project_id] - validates_length_of :name, maximum: 60 + validates :name, + presence: true, + uniqueness: { scope: [:project_id], case_sensitive: true } + validates_format_of :effective_date, with: /\A\d{4}-\d{2}-\d{2}\z/, message: :not_a_date, allow_nil: true validates_format_of :start_date, with: /\A\d{4}-\d{2}-\d{2}\z/, message: :not_a_date, allow_nil: true validates_inclusion_of :status, in: VERSION_STATUSES diff --git a/app/services/authorization/abstract_query.rb b/app/services/authorization/abstract_query.rb index 7437306ac24..f3b61b0ae39 100644 --- a/app/services/authorization/abstract_query.rb +++ b/app/services/authorization/abstract_query.rb @@ -34,7 +34,8 @@ class Authorization::AbstractQuery def self.query(*args) arel = transformed_query(*args) - model.joins(joins(arel)) + model.unscoped + .joins(joins(arel)) .where(wheres(arel)) .distinct end diff --git a/config/application.rb b/config/application.rb index 9e96300de05..e41dc316bb8 100644 --- a/config/application.rb +++ b/config/application.rb @@ -150,6 +150,10 @@ module OpenProject # Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. Rails.application.config.active_support.use_sha1_digests = true + # This option is not backwards compatible with earlier Rails versions. + # It's best enabled when your entire app is migrated and stable on 6.0. + Rails.application.config.action_dispatch.use_cookies_with_metadata = true + # Make `form_with` generate id attributes for any generated HTML tags. # Rails.application.config.action_view.form_with_generates_ids = true @@ -177,6 +181,9 @@ module OpenProject config.action_controller.asset_host = OpenProject::Configuration::AssetHost.value + # Return false instead of self when enqueuing is aborted from a callback. + # Rails.application.config.active_job.return_false_on_aborted_enqueue = true + config.log_level = OpenProject::Configuration['log_level'].to_sym def self.root_url diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 00000000000..5b987904838 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: test + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: open_project_production diff --git a/lib/open_project/plugins/module_handler.rb b/lib/open_project/plugins/module_handler.rb index 6bd363868c2..c254d6e3b95 100644 --- a/lib/open_project/plugins/module_handler.rb +++ b/lib/open_project/plugins/module_handler.rb @@ -1,4 +1,5 @@ #-- encoding: UTF-8 + #-- copyright # OpenProject is a project management system. # Copyright (C) 2012-2018 the OpenProject Foundation (OPF) diff --git a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb index 67fc56cb310..606f81256b4 100644 --- a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb +++ b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -109,14 +109,18 @@ module Redmine # because while they have the right to be added as watchers having # them pop up in every project would be weird. def possible_watcher_users - users = User - .active_or_registered + # In rails 6, for reasons I did not look into, a different sql is produced + # when issuing + # User.active_or_registered.allowed_members(self.class.acts_as_watchable_permission, project) + # compared to + # User.allowed_members(self.class.acts_as_watchable_permission, project).active_or_registered + scope = if project.is_public? + User.allowed(self.class.acts_as_watchable_permission, project) + else + User.allowed_members(self.class.acts_as_watchable_permission, project) + end - if project.is_public? - users.allowed(self.class.acts_as_watchable_permission, project) - else - users.allowed_members(self.class.acts_as_watchable_permission, project) - end + scope.active_or_registered end # Returns an array of users that are proposed as watchers diff --git a/modules/bcf/openproject-bcf.gemspec b/modules/bcf/openproject-bcf.gemspec index ad057916166..b423cae5aea 100644 --- a/modules/bcf/openproject-bcf.gemspec +++ b/modules/bcf/openproject-bcf.gemspec @@ -14,6 +14,5 @@ Gem::Specification.new do |s| s.test_files = Dir["spec/**/*"] s.add_dependency 'activerecord-import' - s.add_dependency 'rails', '~> 5' s.add_dependency 'rubyzip', '~> 1.2' end diff --git a/modules/grids/app/controllers/api/v3/grids/grids_api.rb b/modules/grids/app/controllers/api/v3/grids/grids_api.rb index 4cf4c9795b5..c39fcd59f1b 100644 --- a/modules/grids/app/controllers/api/v3/grids/grids_api.rb +++ b/modules/grids/app/controllers/api/v3/grids/grids_api.rb @@ -54,7 +54,7 @@ module API post &::API::V3::Utilities::Endpoints::Create.new(model: ::Grids::Grid).mount - mount CreateFormAPI + mount ::API::V3::Grids::CreateFormAPI mount ::API::V3::Grids::Schemas::GridSchemaAPI route_param :id, type: Integer, desc: 'Grid ID' do @@ -105,7 +105,7 @@ module API .mount delete &::API::V3::Utilities::Endpoints::Delete.new(model: ::Grids::Grid).mount - mount UpdateFormAPI + mount ::API::V3::Grids::UpdateFormAPI end end end diff --git a/modules/reporting/openproject-reporting.gemspec b/modules/reporting/openproject-reporting.gemspec index 29a00e2b573..eddda6cdc8c 100644 --- a/modules/reporting/openproject-reporting.gemspec +++ b/modules/reporting/openproject-reporting.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |s| s.add_dependency "reporting_engine" s.add_dependency "openproject-costs" - s.add_dependency 'jquery-tablesorter', '~> 1.25.5' + s.add_dependency 'jquery-tablesorter', '~> 1.27.0' s.add_development_dependency "factory_girl_rails", "~> 4.0" end diff --git a/modules/webhooks/spec/lib/hook_spec.rb b/modules/webhooks/spec/lib/hook_spec.rb index 98640de50eb..e8468817a52 100644 --- a/modules/webhooks/spec/lib/hook_spec.rb +++ b/modules/webhooks/spec/lib/hook_spec.rb @@ -14,7 +14,6 @@ require File.expand_path('../../spec_helper', __FILE__) - describe OpenProject::Webhooks::Hook do describe '#relative_url' do let(:hook) { OpenProject::Webhooks::Hook.new('myhook')} diff --git a/spec/contracts/projects/shared_contract_examples.rb b/spec/contracts/projects/shared_contract_examples.rb index 826f0da0ce9..55826445a0a 100644 --- a/spec/contracts/projects/shared_contract_examples.rb +++ b/spec/contracts/projects/shared_contract_examples.rb @@ -79,7 +79,7 @@ shared_examples_for 'project contract' do let(:project_identifier) { nil } it 'is invalid' do - expect_valid(false, identifier: %i(blank too_short)) + expect_valid(false, identifier: %i(blank)) end end diff --git a/spec/lib/open_project/configuration_spec.rb b/spec/lib/open_project/configuration_spec.rb index 9fb9862b85f..2cb1d209690 100644 --- a/spec/lib/open_project/configuration_spec.rb +++ b/spec/lib/open_project/configuration_spec.rb @@ -415,7 +415,9 @@ describe OpenProject::Configuration do end describe '.configure_cache' do - let(:application_config) { Rails::Application::Configuration.new } + let(:application_config) do + Rails::Application::Configuration.new Rails.root + end after do # reload configuration to isolate specs diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb index 603615b3ef4..4fffbcad06c 100644 --- a/spec/models/application_record_spec.rb +++ b/spec/models/application_record_spec.rb @@ -18,7 +18,7 @@ describe ApplicationRecord, type: :model do def expect_matched_date(postgres_time, rails_time) # Rails uses timestamp without timezone for timestamp columns - postgres_utc_iso8601 = Time.zone.parse(postgres_time).iso8601 + postgres_utc_iso8601 = Time.zone.parse(postgres_time.to_s).iso8601 rails_utc_iso8601 = rails_time.iso8601 expect(postgres_utc_iso8601).to eq(rails_utc_iso8601) diff --git a/spec/support/shared/with_settings.rb b/spec/support/shared/with_settings.rb index 311e578dc86..112d64581bb 100644 --- a/spec/support/shared/with_settings.rb +++ b/spec/support/shared/with_settings.rb @@ -31,7 +31,7 @@ def aggregate_mocked_settings(example, settings) # We have to manually check parent groups for with_settings:, # since they are being ignored otherwise - example.example_group.parents.each do |parent| + example.example_group.module_parents.each do |parent| if parent.respond_to?(:metadata) && parent.metadata[:with_settings] settings.reverse_merge!(parent.metadata[:with_settings]) end diff --git a/spec_legacy/unit/lib/redmine/hook_spec.rb b/spec_legacy/unit/lib/redmine/hook_spec.rb index 659f41eff29..c7d05fbfcb4 100644 --- a/spec_legacy/unit/lib/redmine/hook_spec.rb +++ b/spec_legacy/unit/lib/redmine/hook_spec.rb @@ -176,6 +176,6 @@ describe 'Redmine::Hook::Manager' do # FIXME: naming (RSpec-port) end def view_hook_helper - @view_hook_helper ||= TestHookHelperView.new(Rails.root.to_s + '/app/views') + @view_hook_helper ||= TestHookHelperView.new(ActionView::LookupContext.new(Rails.root.to_s + '/app/views')) end end diff --git a/spec_legacy/unit/project_spec.rb b/spec_legacy/unit/project_spec.rb index 7a96b6f2359..b521b254f6b 100644 --- a/spec_legacy/unit/project_spec.rb +++ b/spec_legacy/unit/project_spec.rb @@ -131,7 +131,7 @@ describe Project, type: :model do it 'should members should be active users' do Project.all.each do |project| - assert_nil project.members.detect { |m| !(m.user.is_a?(User) && m.user.active?) } + assert_nil project.members.detect { |m| !(m.principal.is_a?(User) && m.principal.active?) } end end @@ -142,7 +142,7 @@ describe Project, type: :model do end it 'should archive' do - user = @ecookbook.members.first.user + user = @ecookbook.members.first.principal @ecookbook.archive @ecookbook.reload @@ -166,7 +166,7 @@ describe Project, type: :model do end it 'should unarchive' do - user = @ecookbook.members.first.user + user = @ecookbook.members.first.principal @ecookbook.archive # A subproject of an archived project can not be unarchived assert !@ecookbook_sub1.unarchive