diff --git a/app/components/settings/project_custom_fields/header_component.html.erb b/app/components/settings/project_custom_fields/header_component.html.erb index bc0a43f64e3..cd7fd782258 100644 --- a/app/components/settings/project_custom_fields/header_component.html.erb +++ b/app/components/settings/project_custom_fields/header_component.html.erb @@ -29,7 +29,7 @@ ) menu.with_sub_menu_item(label: t("settings.project_attributes.label_new_attribute")) do |sub_menu| - OpenProject::CustomFieldFormat.all_for_class_name("Project") + OpenProject::CustomFieldFormat.available_for_class_name("Project") .sort_by(&:name) .map do |format| sub_menu.with_item( diff --git a/app/helpers/custom_fields_helper.rb b/app/helpers/custom_fields_helper.rb index e07dc0d3550..172f224d1ea 100644 --- a/app/helpers/custom_fields_helper.rb +++ b/app/helpers/custom_fields_helper.rb @@ -133,24 +133,11 @@ module CustomFieldsHelper CustomValue.new(custom_field:, value:).formatted_value end - # Return an array of custom field formats which can be used in select_tag - def custom_field_formats_for_select(custom_field) - OpenProject::CustomFieldFormat.all_for_field(custom_field) - .map do |custom_field_format| - [label_for_custom_field_format(custom_field_format.name), custom_field_format.name] - end - end - def label_for_custom_field_format(format_string) format = OpenProject::CustomFieldFormat.find_by(name: format_string) return "" if format.nil? - label = format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label) - - show_enterprise_text = format_string == "hierarchy" && !EnterpriseToken.allows_to?(:custom_field_hierarchies) - suffix = show_enterprise_text ? " (#{I18n.t(:"ee.upsell.title")})" : "" - - "#{label}#{suffix}" + format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label) end def options_for_list(custom_field, project) diff --git a/app/views/custom_fields/index.html.erb b/app/views/custom_fields/index.html.erb index 1938c80f811..2a8f63abdf1 100644 --- a/app/views/custom_fields/index.html.erb +++ b/app/views/custom_fields/index.html.erb @@ -43,7 +43,7 @@ See COPYRIGHT and LICENSE files for more details. aria: { label: I18n.t(:label_custom_field_new) } } ) do |menu| - OpenProject::CustomFieldFormat.all_for_class_name(@tab.delete_suffix("CustomField")) + OpenProject::CustomFieldFormat.available_for_class_name(@tab.delete_suffix("CustomField")) .sort_by(&:name) .map do |format| menu.with_item( diff --git a/config/initializers/custom_field_format.rb b/config/initializers/custom_field_format.rb index 12470f70b51..2d773b3950e 100644 --- a/config/initializers/custom_field_format.rb +++ b/config/initializers/custom_field_format.rb @@ -86,5 +86,6 @@ OpenProject::CustomFieldFormat.map do |fields| only: %w(WorkPackage), order: 12, multi_value_possible: true, + enterprise_feature: :custom_field_hierarchies, formatter: "CustomValue::HierarchyStrategy") end diff --git a/lib/open_project/custom_field_format.rb b/lib/open_project/custom_field_format.rb index 90c55a6488c..3130617ba15 100644 --- a/lib/open_project/custom_field_format.rb +++ b/lib/open_project/custom_field_format.rb @@ -30,10 +30,9 @@ module OpenProject class CustomFieldFormat include Redmine::I18n - cattr_reader :available - @@available = {} + class_attribute :registered, default: {} - attr_reader :name, :order, :label, :edit_as, :class_names + attr_reader :name, :order, :label, :edit_as, :class_names, :enterprise_feature def initialize(name, label:, @@ -41,6 +40,7 @@ module OpenProject edit_as: name, only: nil, multi_value_possible: false, + enterprise_feature: nil, formatter: "CustomValue::StringStrategy") @name = name @label = label @@ -48,6 +48,7 @@ module OpenProject @edit_as = edit_as @class_names = only @multi_value_possible = multi_value_possible + @enterprise_feature = enterprise_feature @formatter = formatter end @@ -67,23 +68,23 @@ module OpenProject # Registers a custom field format def register(custom_field_format, _options = {}) - @@available[custom_field_format.name] = custom_field_format unless @@available.include?(custom_field_format.name) + registered[custom_field_format.name] = custom_field_format unless registered.include?(custom_field_format.name) + end + + def available + registered + .select { |_, format| !format.enterprise_feature || EnterpriseToken.allows_to?(format.enterprise_feature) } end def available_formats - @@available.keys + available.keys end def find_by(name:) - @@available[name.to_s] + registered[name.to_s] end - def all_for_field(custom_field) - class_name = custom_field.class.customized_class.name - all_for_class_name(class_name) - end - - def all_for_class_name(class_name) + def available_for_class_name(class_name) available .values .select { |field| field.class_names.nil? || field.class_names.include?(class_name) } diff --git a/spec/contracts/custom_fields/hierarchy/generate_root_contract_spec.rb b/spec/contracts/custom_fields/hierarchy/generate_root_contract_spec.rb index 6089fe29742..733575a5006 100644 --- a/spec/contracts/custom_fields/hierarchy/generate_root_contract_spec.rb +++ b/spec/contracts/custom_fields/hierarchy/generate_root_contract_spec.rb @@ -30,12 +30,12 @@ require "rails_helper" -RSpec.describe CustomFields::Hierarchy::GenerateRootContract do +RSpec.describe CustomFields::Hierarchy::GenerateRootContract, with_ee: [:custom_field_hierarchies] do subject { described_class.new } describe "#call" do context "when hierarchy_root is nil" do - let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } + let(:custom_field) { create(:hierarchy_wp_custom_field, hierarchy_root: nil) } it "is valid" do result = subject.call(custom_field:) @@ -45,7 +45,7 @@ RSpec.describe CustomFields::Hierarchy::GenerateRootContract do context "when hierarchy_root is not nil" do let(:hierarchy_root) { create(:hierarchy_item) } - let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root:) } + let(:custom_field) { create(:hierarchy_wp_custom_field, hierarchy_root:) } it "is invalid" do result = subject.call(custom_field:) @@ -55,7 +55,7 @@ RSpec.describe CustomFields::Hierarchy::GenerateRootContract do end context "when inputs are valid" do - let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } + let(:custom_field) { create(:hierarchy_wp_custom_field, hierarchy_root: nil) } it "creates a success result" do expect(subject.call(custom_field:)).to be_success diff --git a/spec/controllers/admin/custom_fields/hierarchy/items_controller_spec.rb b/spec/controllers/admin/custom_fields/hierarchy/items_controller_spec.rb index a8a94ee69a8..aef9b12d7cc 100644 --- a/spec/controllers/admin/custom_fields/hierarchy/items_controller_spec.rb +++ b/spec/controllers/admin/custom_fields/hierarchy/items_controller_spec.rb @@ -31,7 +31,7 @@ require "spec_helper" -RSpec.describe Admin::CustomFields::Hierarchy::ItemsController do +RSpec.describe Admin::CustomFields::Hierarchy::ItemsController, with_ee: [:custom_field_hierarchies] do let(:user) { create(:admin) } let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } diff --git a/spec/features/admin/custom_fields/shared_custom_field_expectations.rb b/spec/features/admin/custom_fields/shared_custom_field_expectations.rb index fb81fa3f198..949a69c2e80 100644 --- a/spec/features/admin/custom_fields/shared_custom_field_expectations.rb +++ b/spec/features/admin/custom_fields/shared_custom_field_expectations.rb @@ -107,20 +107,23 @@ RSpec.shared_examples_for "hierarchy custom fields on index page" do |type| end context "with an active enterprise token with custom_field_hierarchies feature", with_ee: [:custom_field_hierarchies] do - it "does not show the enterprise upsell banner" do + it "does not show the enterprise upsell banner and has the 'Hierarchy' option for creation" do expect(page).to have_no_text(I18n.t("ee.upsell.custom_field_hierarchies.description")) + cf_page.expect_having_create_item "Hierarchy" end end context "with an active enterprise token without custom_field_hierarchies feature", with_ee: [:another_feature] do - it "shows the enterprise upsell banner" do + it "shows the enterprise upsell banner and lacks the 'Hierarchy' option for creation" do expect(page).to have_text(I18n.t("ee.upsell.custom_field_hierarchies.description")) + cf_page.expect_not_having_create_item "Hierarchy" end end context "with a trial enterprise token", :with_ee_trial, with_ee: [:custom_field_hierarchies] do - it "shows the enterprise upsell banner and can save" do + it "shows the enterprise upsell banner and has the 'Hierarchy' option for creation" do expect(page).to have_text(I18n.t("ee.upsell.custom_field_hierarchies.description")) + cf_page.expect_having_create_item "Hierarchy" end end end diff --git a/spec/features/work_packages/table/queries/hierarchy_cf_filter_spec.rb b/spec/features/work_packages/table/queries/hierarchy_cf_filter_spec.rb index 88044025517..da088f80558 100644 --- a/spec/features/work_packages/table/queries/hierarchy_cf_filter_spec.rb +++ b/spec/features/work_packages/table/queries/hierarchy_cf_filter_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe "Work package filtering by hierarchy custom field", :js do +RSpec.describe "Work package filtering by hierarchy custom field", :js, with_ee: [:custom_field_hierarchies] do let(:project) { create(:project) } let(:type) { project.types.first } let(:wp_table) { Pages::WorkPackagesTable.new(project) } diff --git a/spec/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer_rendering_spec.rb b/spec/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer_rendering_spec.rb index 4a33d86b16e..151a6553174 100644 --- a/spec/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer_rendering_spec.rb +++ b/spec/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer_rendering_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe API::V3::CustomFields::Hierarchy::HierarchyItemRepresenter, "rendering" do +RSpec.describe API::V3::CustomFields::Hierarchy::HierarchyItemRepresenter, "rendering", with_ee: [:custom_field_hierarchies] do include API::V3::Utilities::PathHelper let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } diff --git a/spec/lib/open_project/custom_field_format_spec.rb b/spec/lib/open_project/custom_field_format_spec.rb new file mode 100644 index 00000000000..b1e45393c1b --- /dev/null +++ b/spec/lib/open_project/custom_field_format_spec.rb @@ -0,0 +1,107 @@ +# 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 OpenProject::CustomFieldFormat do + describe ".available_for_class_name" do + shared_examples_for "custom field formats" do |class_name, expected_formats| + it "returns all custom field formats for the '#{class_name}' class", :aggregate_failures do + formats = described_class.available_for_class_name(class_name) + expect(formats).to all(be_a described_class) + expect(formats.map(&:name)).to match_array(expected_formats) + end + end + + context "for a 'Project' class" do + it_behaves_like "custom field formats", + "Project", + ["bool", "date", "float", "int", "link", "list", "string", "text", "user", "version"] + end + + context "for a 'WorkPackage' class" do + context "with a custom_field_hierarchies ee", with_ee: [:custom_field_hierarchies] do + it_behaves_like "custom field formats", + "WorkPackage", + ["bool", "date", "float", "int", "link", "list", "string", "text", "user", "version", "hierarchy"] + end + + context "without a custom_field_hierarchies ee" do + it_behaves_like "custom field formats", + "WorkPackage", + ["bool", "date", "float", "int", "link", "list", "string", "text", "user", "version"] + end + end + + context "for a 'Version' class" do + it_behaves_like "custom field formats", + "Version", + ["bool", "date", "float", "int", "list", "string", "text", "user", "version"] + end + + context "for a 'TimeEntry' class" do + it_behaves_like "custom field formats", + "TimeEntry", + ["bool", "date", "float", "int", "list", "string", "text", "user", "version"] + end + + context "for a 'User' class" do + it_behaves_like "custom field formats", + "User", + ["bool", "date", "float", "int", "list", "string", "text"] + end + + context "for a 'Group' class" do + it_behaves_like "custom field formats", + "Group", + ["bool", "date", "float", "int", "list", "string", "text"] + end + end + + describe ".available_formats" do + context "with a custom_field_hierarchies ee", with_ee: [:custom_field_hierarchies] do + it "returns all custom field formats including hierarchy" do + formats = described_class.available_formats + expect(formats) + .to contain_exactly("bool", "date", "float", "int", "link", "list", "string", "text", "user", + "version", "hierarchy", "empty") + end + end + + context "without a custom_field_hierarchies ee" do + it "returns all custom field formats excluding hierarchy" do + formats = described_class.available_formats + expect(formats) + .to contain_exactly("bool", "date", "float", "int", "link", "list", "string", "text", "user", + "version", "empty") + end + end + end +end diff --git a/spec/lib/open_project/journal_formatter/custom_field_spec.rb b/spec/lib/open_project/journal_formatter/custom_field_spec.rb index 8ef99904038..474bdfbff00 100644 --- a/spec/lib/open_project/journal_formatter/custom_field_spec.rb +++ b/spec/lib/open_project/journal_formatter/custom_field_spec.rb @@ -398,12 +398,13 @@ RSpec.describe OpenProject::JournalFormatter::CustomField do end end - context "for hierarchy custom field" do - shared_let(:custom_field) { create(:hierarchy_wp_custom_field) } - shared_let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } - shared_let(:root) { custom_field.hierarchy_root } - shared_let(:luke) { service.insert_item(parent: root, label: "luke", short: "LS").value! } - shared_let(:mara) { service.insert_item(parent: luke, label: "mara").value! } + context "for hierarchy custom field", with_ee: [:custom_field_hierarchies] do + let!(:custom_field) { build_stubbed(:hierarchy_wp_custom_field) } + + let!(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } + let!(:root) { custom_field.hierarchy_root } + let!(:luke) { service.insert_item(parent: root, label: "luke", short: "LS").value! } + let!(:mara) { service.insert_item(parent: luke, label: "mara").value! } describe "first value being nil and second value a string" do let(:values) { [nil, mara.id.to_s] } diff --git a/spec/migrations/adds_position_cache_to_hierarchy_items_spec.rb b/spec/migrations/adds_position_cache_to_hierarchy_items_spec.rb index ab01a3c63a4..05e0277e77d 100644 --- a/spec/migrations/adds_position_cache_to_hierarchy_items_spec.rb +++ b/spec/migrations/adds_position_cache_to_hierarchy_items_spec.rb @@ -31,7 +31,7 @@ require "spec_helper" require Rails.root.join("db/migrate/20250102161733_adds_position_cache_to_hierarchy_items.rb") -RSpec.describe AddsPositionCacheToHierarchyItems, type: :model do +RSpec.describe AddsPositionCacheToHierarchyItems, type: :model, with_ee: [:custom_field_hierarchies] do let(:custom_field) { create(:hierarchy_wp_custom_field, hierarchy_root: nil) } let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } diff --git a/spec/models/custom_field/hierarchy/item_spec.rb b/spec/models/custom_field/hierarchy/item_spec.rb index 0706cb6cdbc..17c8965e86e 100644 --- a/spec/models/custom_field/hierarchy/item_spec.rb +++ b/spec/models/custom_field/hierarchy/item_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe CustomField::Hierarchy::Item, :model do +RSpec.describe CustomField::Hierarchy::Item, :model, with_ee: [:custom_field_hierarchies] do let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } diff --git a/spec/models/custom_field/order_statements_spec.rb b/spec/models/custom_field/order_statements_spec.rb index 5ac5600e0f0..a8ad8c7b62a 100644 --- a/spec/models/custom_field/order_statements_spec.rb +++ b/spec/models/custom_field/order_statements_spec.rb @@ -32,7 +32,7 @@ require "spec_helper" RSpec.describe CustomField::OrderStatements do # integration tests at spec/models/query/results_cf_sorting_integration_spec.rb - context "when hierarchy" do + context "when hierarchy", with_ee: [:custom_field_hierarchies] do let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } let(:item) { custom_field.hierarchy_root } diff --git a/spec/models/custom_field/work_package_custom_field_spec.rb b/spec/models/custom_field/work_package_custom_field_spec.rb index 545816419b3..e851c7a630d 100644 --- a/spec/models/custom_field/work_package_custom_field_spec.rb +++ b/spec/models/custom_field/work_package_custom_field_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe WorkPackageCustomField, :model do +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]) } diff --git a/spec/models/queries/operators/custom_fields/hierarchies/equals_with_descendants_spec.rb b/spec/models/queries/operators/custom_fields/hierarchies/equals_with_descendants_spec.rb index 91a983eee29..8b339a6fddb 100644 --- a/spec/models/queries/operators/custom_fields/hierarchies/equals_with_descendants_spec.rb +++ b/spec/models/queries/operators/custom_fields/hierarchies/equals_with_descendants_spec.rb @@ -30,10 +30,10 @@ require "spec_helper" -RSpec.describe Queries::Operators::CustomFields::Hierarchies::EqualsWithDescendants do +RSpec.describe Queries::Operators::CustomFields::Hierarchies::EqualsWithDescendants, with_ee: [:custom_field_hierarchies] do subject(:sql) { described_class.sql_for_field(values, db_table, db_field) } - let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } + let(:custom_field) { create(:hierarchy_wp_custom_field, hierarchy_root: nil) } let!(:root) { service.generate_root(custom_field).value! } let!(:germany) { service.insert_item(parent: root, label: "Germany", short: "DE").value! } let!(:berlin) { service.insert_item(parent: germany, label: "Berlin").value! } diff --git a/spec/models/query/results_cf_sorting_integration_spec.rb b/spec/models/query/results_cf_sorting_integration_spec.rb index e19939558ea..3fa511ff5ed 100644 --- a/spec/models/query/results_cf_sorting_integration_spec.rb +++ b/spec/models/query/results_cf_sorting_integration_spec.rb @@ -182,7 +182,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do context "for list format" do let(:possible_values) { %w[100 3 20] } - let(:id_by_value) { custom_field.possible_values.to_h { [_1.value, _1.id] } } + let(:id_by_value) { custom_field.possible_values.to_h { [it.value, it.id] } } context "if not allowing multi select" do include_examples "it sorts" do @@ -194,7 +194,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do # sorting is done by position, and not by value wp_with_cf_value(id_by_value.fetch("100")), wp_with_cf_value(id_by_value.fetch("3")), - wp_with_cf_value(id_by_value.fetch("20")), + wp_with_cf_value(id_by_value.fetch("20")) ] end end @@ -218,7 +218,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do wp_with_cf_value(id_by_value.fetch_values("20", "100")), # 100, 20 wp_with_cf_value(id_by_value.fetch_values("3")), # 3 wp_with_cf_value(id_by_value.fetch_values("3", "20")), # 3, 20 - wp_with_cf_value(id_by_value.fetch_values("20")), # 20 + wp_with_cf_value(id_by_value.fetch_values("20")) # 20 ] end @@ -241,7 +241,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do create(:user, lastname: "A", firstname: "X", login: "ax", mail: "ax@o.p") ] end - shared_let(:id_by_login) { users.to_h { [_1.login, _1.id] } } + shared_let(:id_by_login) { users.to_h { [it.login, it.id] } } shared_let(:role) { create(:project_role) } @@ -261,7 +261,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do wp_with_cf_value(id_by_login.fetch("ax")), wp_with_cf_value(id_by_login.fetch("ba")), wp_with_cf_value(id_by_login.fetch("bb1")), - wp_with_cf_value(id_by_login.fetch("bb2")), + wp_with_cf_value(id_by_login.fetch("bb2")) ] end end @@ -279,7 +279,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do wp_with_cf_value(id_by_login.fetch_values("ax", "bb1")), # ax, bb1 wp_with_cf_value(id_by_login.fetch_values("ba")), # ba wp_with_cf_value(id_by_login.fetch_values("bb1", "ba")), # ba, bb1 - wp_with_cf_value(id_by_login.fetch_values("ba", "bb2")), # ba, bb2 + wp_with_cf_value(id_by_login.fetch_values("ba", "bb2")) # ba, bb2 ] end @@ -302,7 +302,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do create(:version, project:, sharing: "system", name: "9") ] end - let(:id_by_name) { versions.to_h { [_1.name, _1.id] } } + let(:id_by_name) { versions.to_h { [it.name, it.id] } } context "if not allowing multi select" do include_examples "it sorts" do @@ -332,7 +332,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do wp_with_cf_value(id_by_name.fetch_values("9", "10.10.10")), # 9, 10.10.10 wp_with_cf_value(id_by_name.fetch_values("10.2", "10.10.2")), # 10.2, 10.10.2 wp_with_cf_value(id_by_name.fetch_values("10.10.2")), # 10.10.2 - wp_with_cf_value(id_by_name.fetch_values("10.10.10")), # 10.10.10 + wp_with_cf_value(id_by_name.fetch_values("10.10.10")) # 10.10.10 ] end @@ -346,7 +346,7 @@ RSpec.describe Query::Results, "Sorting by custom field" do end end - context "for hierarchy format" do + context "for hierarchy format", with_ee: [:custom_field_hierarchies] do include_examples "it sorts" do let(:custom_field) { create(:hierarchy_wp_custom_field, hierarchy_root: nil) } let(:root) { service.generate_root(custom_field).value! } diff --git a/spec/requests/api/v3/custom_fields/hierarchy/item_api_spec.rb b/spec/requests/api/v3/custom_fields/hierarchy/item_api_spec.rb index 78912d7cb3b..82b33b407e4 100644 --- a/spec/requests/api/v3/custom_fields/hierarchy/item_api_spec.rb +++ b/spec/requests/api/v3/custom_fields/hierarchy/item_api_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe "API v3 custom field items", :webmock, content_type: :json do +RSpec.describe "API v3 custom field items", :webmock, content_type: :json, with_ee: [:custom_field_hierarchies] do include API::V3::Utilities::PathHelper let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } diff --git a/spec/requests/api/v3/custom_fields/hierarchy/items_api_spec.rb b/spec/requests/api/v3/custom_fields/hierarchy/items_api_spec.rb index 335a90d3102..2fddc122eee 100644 --- a/spec/requests/api/v3/custom_fields/hierarchy/items_api_spec.rb +++ b/spec/requests/api/v3/custom_fields/hierarchy/items_api_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe "API v3 custom field hierarchy items", :webmock, content_type: :json do +RSpec.describe "API v3 custom field hierarchy items", :webmock, content_type: :json, with_ee: [:custom_field_hierarchies] do include API::V3::Utilities::PathHelper describe "GET /api/v3/custom_fields/:id/items" do diff --git a/spec/services/custom_fields/hierarchy/hierarchical_item_service_spec.rb b/spec/services/custom_fields/hierarchy/hierarchical_item_service_spec.rb index 36abb4b82eb..f096bc43cea 100644 --- a/spec/services/custom_fields/hierarchy/hierarchical_item_service_spec.rb +++ b/spec/services/custom_fields/hierarchy/hierarchical_item_service_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe CustomFields::Hierarchy::HierarchicalItemService do +RSpec.describe CustomFields::Hierarchy::HierarchicalItemService, with_ee: [:custom_field_hierarchies] do let!(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } let!(:invalid_custom_field) { create(:custom_field, field_format: "text", hierarchy_root: nil) } diff --git a/spec/support/custom_fields_helpers.rb b/spec/support/custom_fields_helpers.rb index 8c67d7dcba0..4c57c097da3 100644 --- a/spec/support/custom_fields_helpers.rb +++ b/spec/support/custom_fields_helpers.rb @@ -31,7 +31,7 @@ module CustomFieldsHelpers def factory_bot_custom_field_traits_for(class_name) OpenProject::CustomFieldFormat - .all_for_class_name(class_name) + .available_for_class_name(class_name) .flat_map do |format| trait_name = trait_name(format.name) [ diff --git a/spec/support/pages/custom_fields/index_page.rb b/spec/support/pages/custom_fields/index_page.rb index f5154b2fecd..54bfebb2b24 100644 --- a/spec/support/pages/custom_fields/index_page.rb +++ b/spec/support/pages/custom_fields/index_page.rb @@ -68,6 +68,22 @@ module Pages click_on type end + def expect_having_create_item(type) + wait_for_network_idle + + click_button "New custom field" + + expect(page).to have_link(type) + end + + def expect_not_having_create_item(type) + wait_for_network_idle + + click_button "New custom field" + + expect(page).to have_no_link(type) + end + def expect_none_listed expect(page).to have_text("There are currently no custom fields.") end