add visible scope for user custom fields

This commit is contained in:
ulferts
2026-02-24 11:08:05 +01:00
parent 608cc40e68
commit 49eea966d8
5 changed files with 153 additions and 22 deletions
+15 -2
View File
@@ -34,8 +34,21 @@ module CustomFields::Scopes
class_methods do
def visible(user = User.current)
where(type: ProjectCustomField.name).and(ProjectCustomField.visible(user))
.or(where(type: WorkPackageCustomField.name).and(WorkPackageCustomField.visible(user)))
known_subclasses.inject(none) do |scope, klass|
scope.or(where(type: klass.name).and(klass.visible(user)))
end
end
def known_subclasses
# In dev/test without eager loading, subclasses might not be loaded.
if Rails.env.local?
CustomField
.group(:type)
.pluck(:type)
.map(&:safe_constantize)
end
CustomField.subclasses
end
end
end
+4
View File
@@ -29,6 +29,10 @@
#++
class UserCustomField < CustomField
includes Scopes::Scoped
scopes :visible
def type_name
:label_user_plural
end
@@ -0,0 +1,45 @@
# 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.
# ++
module UserCustomFields::Scopes
module Visible
extend ActiveSupport::Concern
class_methods do
def visible(user = User.current)
if user.admin?
all
else
where(admin_only: false)
end
end
end
end
end
@@ -33,9 +33,11 @@ require "spec_helper"
RSpec.describe CustomFields::Scopes::Visible do
shared_let(:project_cf) { create(:string_project_custom_field) }
shared_let(:work_package_cf) { create(:string_wp_custom_field) }
shared_let(:user_cf) { create(:user_custom_field) }
let(:project_cf_visible) { false }
let(:work_package_cf_visible) { false }
let(:user_cf_visible) { false }
# Since there would be very many tests here, we break the rule of testing
# the scope as a black box. Knowing that the scope relies on the individual visible scopes of each
@@ -46,14 +48,14 @@ RSpec.describe CustomFields::Scopes::Visible do
current_user { build_stubbed(:user) }
before do
allow(ProjectCustomField)
.to receive(:visible)
.with(current_user)
.and_return(project_cf_visible ? ProjectCustomField.all : ProjectCustomField.none)
allow(WorkPackageCustomField)
.to receive(:visible)
.with(current_user)
.and_return(work_package_cf_visible ? WorkPackageCustomField.all : WorkPackageCustomField.none)
{ ProjectCustomField => project_cf_visible,
WorkPackageCustomField => work_package_cf_visible,
UserCustomField => user_cf_visible }.each do |klass, visible|
allow(klass)
.to receive(:visible)
.with(current_user)
.and_return(visible ? klass.all : klass.none)
end
end
context "for a project custom field" do
@@ -63,12 +65,6 @@ RSpec.describe CustomFields::Scopes::Visible do
it "returns the project custom field" do
expect(subject).to contain_exactly(project_cf)
end
it "calls the visible scope of the project custom field" do
subject
expect(ProjectCustomField).to have_received(:visible).with(current_user)
end
end
context "if the fields are invisible" do
@@ -87,12 +83,6 @@ RSpec.describe CustomFields::Scopes::Visible do
it "returns the work package custom field" do
expect(subject).to contain_exactly(work_package_cf)
end
it "calls the visible scope of the work_package custom field" do
subject
expect(WorkPackageCustomField).to have_received(:visible).with(current_user)
end
end
context "if the fields are invisible" do
@@ -103,5 +93,23 @@ RSpec.describe CustomFields::Scopes::Visible do
end
end
end
context "for a user custom field" do
context "if the fields are visible" do
let(:user_cf_visible) { true }
it "returns the user custom field" do
expect(subject).to contain_exactly(user_cf)
end
end
context "if the fields are invisible" do
let(:user_cf_visible) { false }
it "does not return the user custom field" do
expect(subject).to be_empty
end
end
end
end
end
@@ -0,0 +1,61 @@
# 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 UserCustomFields::Scopes::Visible do
shared_let(:admin_only_user_cf) { create(:user_custom_field, admin_only: true) }
shared_let(:user_cf) { create(:user_custom_field, admin_only: false) }
shared_let(:admin) { create(:admin) }
shared_let(:user) { create(:user) }
describe ".visible" do
subject { UserCustomField.visible(current_user) }
current_user { build_stubbed(:user) }
context "for an admin" do
current_user { admin }
it "returns all custom fields" do
expect(subject).to contain_exactly(admin_only_user_cf, user_cf)
end
end
context "for a non admin" do
current_user { user }
it "returns only the non admin custom fields" do
expect(subject).to contain_exactly(user_cf)
end
end
end
end