From 608cc40e683eff1189714fee07e7505f5cc9041b Mon Sep 17 00:00:00 2001 From: ulferts Date: Tue, 24 Feb 2026 08:57:10 +0100 Subject: [PATCH] replace old visible methods on wp cf --- .../attribute_help_text/work_package.rb | 2 +- .../selects/custom_field_select.rb | 2 +- app/models/work_package_custom_field.rb | 20 ---- .../attribute_help_text/work_package_spec.rb | 1 + .../work_package_custom_field_spec.rb | 97 ------------------- .../selects/custom_field_select_spec.rb | 8 +- spec/models/query/results_spec.rb | 10 +- spec/models/query_spec.rb | 2 +- 8 files changed, 15 insertions(+), 127 deletions(-) delete mode 100644 spec/models/custom_field/work_package_custom_field_spec.rb diff --git a/app/models/attribute_help_text/work_package.rb b/app/models/attribute_help_text/work_package.rb index a81a3aa68f1..8415759d819 100644 --- a/app/models/attribute_help_text/work_package.rb +++ b/app/models/attribute_help_text/work_package.rb @@ -53,7 +53,7 @@ class AttributeHelpText::WorkPackage < AttributeHelpText def self.visible_condition(user) visible_cf_names = WorkPackageCustomField - .manageable_by_user(user) + .visible(user) .pluck(:id) .map { |id| "custom_field_#{id}" } diff --git a/app/models/queries/work_packages/selects/custom_field_select.rb b/app/models/queries/work_packages/selects/custom_field_select.rb index 8fc3c51df77..d6f20f60be3 100644 --- a/app/models/queries/work_packages/selects/custom_field_select.rb +++ b/app/models/queries/work_packages/selects/custom_field_select.rb @@ -63,7 +63,7 @@ class Queries::WorkPackages::Selects::CustomFieldSelect < Queries::WorkPackages: else WorkPackageCustomField.all end - .visible_by_user(User.current) + .on_visible_type_and_project(User.current) .reject { |cf| cf.field_format == "text" } .map { |cf| new(cf) } end diff --git a/app/models/work_package_custom_field.rb b/app/models/work_package_custom_field.rb index 4055fe5b29b..67c7f61afee 100644 --- a/app/models/work_package_custom_field.rb +++ b/app/models/work_package_custom_field.rb @@ -45,26 +45,6 @@ class WorkPackageCustomField < CustomField scopes :visible, :on_visible_type_and_project - scope :manageable_by_user, ->(user) { - if user.allowed_in_any_project?(:select_custom_fields) - all - else - visible_by_user(user) - end - } - - scope :visible_by_user, ->(user) { - # Prefer a subquery to a join to avoid the database query returning - # the cross product of projects, types and custom fields. - where(id: - unscoped - .where(projects: { id: Project.visible(user) }) - .where(types: { id: Type.enabled_in(Project.visible(user)) }) - .or(unscoped.where(is_for_all: true)) - .includes(:projects, :types) - .select(:id)) - } - scope :usable_as_custom_action, -> { where.not(field_format: %w[hierarchy weighted_item_list]) .order(:name) diff --git a/spec/models/attribute_help_text/work_package_spec.rb b/spec/models/attribute_help_text/work_package_spec.rb index c491c3ad8d7..b074adebddb 100644 --- a/spec/models/attribute_help_text/work_package_spec.rb +++ b/spec/models/attribute_help_text/work_package_spec.rb @@ -135,6 +135,7 @@ RSpec.describe AttributeHelpText::WorkPackage do end let(:cf_instance_for_all) do custom_field = create(:text_wp_custom_field, is_for_all: true) + type.custom_fields << custom_field create_cf_help_text(custom_field) end diff --git a/spec/models/custom_field/work_package_custom_field_spec.rb b/spec/models/custom_field/work_package_custom_field_spec.rb deleted file mode 100644 index e851c7a630d..00000000000 --- a/spec/models/custom_field/work_package_custom_field_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -require "spec_helper" - -RSpec.describe WorkPackageCustomField, :model, with_ee: [:custom_field_hierarchies] do - let(:feature) { create(:type_feature) } - let(:task) { create(:type_task) } - let(:project) { create(:project, types: [feature, task]) } - let(:project_without_user) { create(:project, types: [feature, task]) } - - describe "scopes" do - describe "manageable_by_user" do - let!(:bool_cf) { create(:boolean_wp_custom_field) } - let!(:text_cf) { create(:text_wp_custom_field) } - let!(:hierarchy_cf) { create(:hierarchy_wp_custom_field) } - - before do - project.work_package_custom_fields << text_cf - feature.custom_fields << text_cf - project_without_user.work_package_custom_fields << bool_cf - task.custom_fields << bool_cf - # hierarchy_cf is not enabled in any project - end - - context "if user has permission to select custom fields" do - let(:user) { create(:user, member_with_permissions: { project => [:select_custom_fields] }) } - - it "returns all custom fields" do - expect(described_class.manageable_by_user(user)).to contain_exactly(bool_cf, text_cf, hierarchy_cf) - end - end - - context "if user does not have permission to select custom fields" do - let(:user) { create(:user) } - let(:role) { create(:project_role, permissions: []) } - let(:project) { create(:project, members: { user => role }, types: [feature, task]) } - - it "returns only custom fields that are enabled in projects the user has access to" do - expect(described_class.manageable_by_user(user)).to contain_exactly(text_cf) - end - end - - it "returns custom fields that are usable as custom action" do - expect(described_class.usable_as_custom_action).to contain_exactly(bool_cf, text_cf) - end - end - end - - describe "visible_by_user" do - let(:user) { create(:user, member_with_permissions: { project => [] }) } - - it "returns an empty array" do - expect(described_class.visible_by_user(user)).to be_empty - end - - context "with custom fields and types added to the project" do - # User cannot see this field as its type is not enabled in the project: - let!(:text_cf) { create(:text_wp_custom_field, projects: [project, project_without_user], types: []) } - # User cannot see this field as they are not a member: - let!(:hierarchy_cf) { create(:hierarchy_wp_custom_field, projects: [project_without_user], types: [feature, task]) } - # User can see this field: - let!(:bool_cf) { create(:boolean_wp_custom_field, projects: [project], types: [feature]) } - - it "returns custom fields with types that are enabled in the project" do - expect(described_class.visible_by_user(user)).to contain_exactly(bool_cf) - end - end - end -end diff --git a/spec/models/queries/work_packages/selects/custom_field_select_spec.rb b/spec/models/queries/work_packages/selects/custom_field_select_spec.rb index 510593b3203..42bbeda860d 100644 --- a/spec/models/queries/work_packages/selects/custom_field_select_spec.rb +++ b/spec/models/queries/work_packages/selects/custom_field_select_spec.rb @@ -55,7 +55,7 @@ RSpec.describe Queries::WorkPackages::Selects::CustomFieldSelect do context "with a user that can see the custom field" do before do - allow(wp_relation).to receive(:visible_by_user) + allow(wp_relation).to receive(:on_visible_type_and_project) .with(user) .and_return([text_custom_field, list_custom_field]) end @@ -71,7 +71,7 @@ RSpec.describe Queries::WorkPackages::Selects::CustomFieldSelect do context "with a user that cannot see custom fields" do before do - allow(wp_relation).to receive(:visible_by_user) + allow(wp_relation).to receive(:on_visible_type_and_project) .with(user) .and_return([]) end @@ -91,7 +91,7 @@ RSpec.describe Queries::WorkPackages::Selects::CustomFieldSelect do context "with a user that can see the custom field" do before do - allow(wp_relation).to receive(:visible_by_user) + allow(wp_relation).to receive(:on_visible_type_and_project) .with(user) .and_return([text_custom_field, list_custom_field]) end @@ -107,7 +107,7 @@ RSpec.describe Queries::WorkPackages::Selects::CustomFieldSelect do context "with a user that cannot see custom fields" do before do - allow(wp_relation).to receive(:visible_by_user) + allow(wp_relation).to receive(:on_visible_type_and_project) .with(user) .and_return([]) end diff --git a/spec/models/query/results_spec.rb b/spec/models/query/results_spec.rb index c65f7b0d98c..0ec9a29a80c 100644 --- a/spec/models/query/results_spec.rb +++ b/spec/models/query/results_spec.rb @@ -74,10 +74,10 @@ RSpec.describe Query::Results do project: project1) end let(:type1) do - create(:type) + create(:type) { |t| project1.types << t } end let(:type2) do - create(:type) + create(:type) { |t| project1.types << t } end let(:work_package1) do create(:work_package, @@ -377,7 +377,11 @@ RSpec.describe Query::Results do project: project2) end - let!(:custom_field) { create(:work_package_custom_field, is_for_all: true) } + let!(:custom_field) do + create(:work_package_custom_field, is_for_all: true) do |cf| + cf.types = project2.types + end + end before do allow(User).to receive(:current).and_return(user2) diff --git a/spec/models/query_spec.rb b/spec/models/query_spec.rb index a6ed3ed5221..f0780b19a57 100644 --- a/spec/models/query_spec.rb +++ b/spec/models/query_spec.rb @@ -365,7 +365,7 @@ RSpec.describe Query, query.project = nil - empty_wp_relation = double(visible_by_user: []) # rubocop:disable RSpec/VerifiedDoubles + empty_wp_relation = double(on_visible_type_and_project: []) # We cannot simply return `WorkPackageCustomField.none` here, as that aliases to `all` and would trigger # its own expectation again. Hence, we must set up a double. allow(WorkPackageCustomField)