Merge pull request #23181 from opf/code-maintenance/74768-remove-calculated_value_project_attribute-feature-flag

[#74768] Remove calculated_value_project_attribute feature flag
This commit is contained in:
Jens Ulferts
2026-05-20 16:09:46 +02:00
committed by GitHub
36 changed files with 260 additions and 319 deletions
@@ -53,6 +53,10 @@ module CustomFields
validate :not_referenced
def validate_model?
false
end
def not_referenced
referencing = model.class.with_formula_referencing(model)
return if referencing.empty?
+5 -2
View File
@@ -123,10 +123,13 @@ class CustomField < ApplicationRecord
end
def validate_field_format_inclusion
available = OpenProject::CustomFieldFormat.available_formats
# When creating a new custom field, only the available formats are allowed.
# But you can edit and update existing custom fields, even if they have a field format that is disabled.
allowed = new_record? ? available : (available + OpenProject::CustomFieldFormat.disabled_formats).uniq
allowed = if new_record?
OpenProject::CustomFieldFormat.available_formats
else
OpenProject::CustomFieldFormat.registered_formats
end
unless allowed.include?(field_format)
errors.add(:field_format, :inclusion)
+71 -74
View File
@@ -28,83 +28,80 @@
# See COPYRIGHT and LICENSE files for more details.
#++
OpenProject::CustomFieldFormat.map do |fields|
fields.register OpenProject::CustomFieldFormat.new("string",
label: :label_string,
order: 1)
fields.register OpenProject::CustomFieldFormat.new("text",
label: :label_text,
order: 2,
formatter: "CustomValue::FormattableStrategy")
fields.register OpenProject::CustomFieldFormat.new("link",
label: :label_link_url,
only: %w(WorkPackage Project),
order: 3,
formatter: "CustomValue::LinkStrategy")
fields.register OpenProject::CustomFieldFormat.new("int",
label: :label_integer,
order: 4,
formatter: "CustomValue::IntStrategy")
fields.register OpenProject::CustomFieldFormat.new("float",
label: :label_float,
order: 5,
formatter: "CustomValue::FloatStrategy")
fields.register OpenProject::CustomFieldFormat.new("list",
label: :label_list,
order: 6,
multi_value_possible: true,
formatter: "CustomValue::ListStrategy")
fields.register OpenProject::CustomFieldFormat.new("date",
label: :label_date,
order: 7,
formatter: "CustomValue::DateStrategy")
fields.register OpenProject::CustomFieldFormat.new("bool",
label: :label_boolean,
order: 8,
formatter: "CustomValue::BoolStrategy")
fields.register OpenProject::CustomFieldFormat.new("user",
label: Proc.new { User.model_name.human },
only: %w(WorkPackage TimeEntry Version Project),
edit_as: "list",
order: 9,
multi_value_possible: true,
formatter: "CustomValue::UserStrategy")
fields.register OpenProject::CustomFieldFormat.new("version",
label: Proc.new { Version.model_name.human },
only: %w(WorkPackage TimeEntry Version Project),
edit_as: "list",
order: 10,
multi_value_possible: true,
formatter: "CustomValue::VersionStrategy")
OpenProject::CustomFieldFormat.tap do |formats|
formats.register("string",
label: :label_string,
order: 1)
formats.register("text",
label: :label_text,
order: 2,
formatter: "CustomValue::FormattableStrategy")
formats.register("link",
label: :label_link_url,
only: %w(WorkPackage Project),
order: 3,
formatter: "CustomValue::LinkStrategy")
formats.register("int",
label: :label_integer,
order: 4,
formatter: "CustomValue::IntStrategy")
formats.register("float",
label: :label_float,
order: 5,
formatter: "CustomValue::FloatStrategy")
formats.register("list",
label: :label_list,
order: 6,
multi_value_possible: true,
formatter: "CustomValue::ListStrategy")
formats.register("date",
label: :label_date,
order: 7,
formatter: "CustomValue::DateStrategy")
formats.register("bool",
label: :label_boolean,
order: 8,
formatter: "CustomValue::BoolStrategy")
formats.register("user",
label: Proc.new { User.model_name.human },
only: %w(WorkPackage TimeEntry Version Project),
edit_as: "list",
order: 9,
multi_value_possible: true,
formatter: "CustomValue::UserStrategy")
formats.register("version",
label: Proc.new { Version.model_name.human },
only: %w(WorkPackage TimeEntry Version Project),
edit_as: "list",
order: 10,
multi_value_possible: true,
formatter: "CustomValue::VersionStrategy")
# This is an internal formatter used as a fallback in case a value is not found.
# Setting the label to nil in order to avoid it becoming available for selection as a custom value format.
fields.register OpenProject::CustomFieldFormat.new("empty",
label: nil,
order: 11,
formatter: "CustomValue::EmptyStrategy")
formats.register("empty",
label: nil,
order: 11,
formatter: "CustomValue::EmptyStrategy")
fields.register OpenProject::CustomFieldFormat.new("hierarchy",
label: :label_hierarchy,
only: %w(Project WorkPackage),
order: 12,
multi_value_possible: true,
enterprise_feature: :custom_field_hierarchies,
formatter: "CustomValue::HierarchyStrategy")
formats.register("hierarchy",
label: :label_hierarchy,
only: %w(Project WorkPackage),
order: 12,
multi_value_possible: true,
enterprise_feature: :custom_field_hierarchies,
formatter: "CustomValue::HierarchyStrategy")
fields.register OpenProject::CustomFieldFormat.new("weighted_item_list",
label: :label_weighted_item_list,
only: %w(Project WorkPackage),
order: 13,
enterprise_feature: :weighted_item_lists,
formatter: "CustomValue::WeightedItemListStrategy")
formats.register("weighted_item_list",
label: :label_weighted_item_list,
only: %w(Project WorkPackage),
order: 13,
enterprise_feature: :weighted_item_lists,
formatter: "CustomValue::WeightedItemListStrategy")
fields.register OpenProject::CustomFieldFormat.new("calculated_value",
label: :label_calculated_value,
only: %w(Project),
order: 14,
enabled: lambda do
OpenProject::FeatureDecisions.calculated_value_project_attribute_active?
end,
enterprise_feature: :calculated_values,
formatter: "CustomValue::CalculatedValueStrategy")
formats.register("calculated_value",
label: :label_calculated_value,
only: %w(Project),
order: 14,
enterprise_feature: :calculated_values,
formatter: "CustomValue::CalculatedValueStrategy")
end
-4
View File
@@ -45,10 +45,6 @@ OpenProject::FeatureDecisions.add :built_in_oauth_applications,
description: "Allows the display and use of built-in OAuth applications.",
force_active: true
OpenProject::FeatureDecisions.add :calculated_value_project_attribute,
description: "Allows the use of calculated values as a project attribute.",
force_active: true
OpenProject::FeatureDecisions.add :minutes_styling_meeting_pdf,
description: "Allow exporting a meeting with FITKO styling. " \
"See #65124 for details."
+24 -31
View File
@@ -82,53 +82,46 @@ module OpenProject
end
def for_class_name?(class_name)
@class_names.nil? || @class_names.include?(class_name)
(@class_names.nil? || @class_names.include?(class_name)) && !label.nil?
end
class << self
def registered = registered_by_name.values
def register(name, **)
return if registered_by_name.has_key?(name)
def map(&)
yield self
end
# Registers a custom field format
def register(custom_field_format, _options = {})
return if registered_by_name.has_key?(custom_field_format.name)
registered_by_name[custom_field_format.name] = custom_field_format
end
def available
registered.select(&:available?)
end
def enabled
registered.select(&:enabled?)
end
def available_formats
available.map(&:name)
registered_by_name[name] = new(name, **)
@registered = nil
end
def find_by(name:)
registered_by_name[name.to_s]
end
def registered
@registered ||= registered_by_name.values.sort_by(&:order)
end
def available = registered.select(&:available?)
def enabled = registered.select(&:enabled?)
def disabled = registered.select(&:disabled?)
def registered_formats = registered.map(&:name)
def available_formats = available.map(&:name)
def enabled_formats = enabled.map(&:name)
def disabled_formats = disabled.map(&:name)
def enabled_for_class_name(class_name)
enabled
.select { |format| format.for_class_name?(class_name) && !format.label.nil? }
.sort_by(&:order)
filter_for_class_name(enabled, class_name)
end
def available_for_class_name(class_name)
available
.select { |format| format.for_class_name?(class_name) && !format.label.nil? }
.sort_by(&:order)
filter_for_class_name(available, class_name)
end
def disabled_formats
registered.select(&:disabled?).map(&:name)
private
def filter_for_class_name(list, class_name)
list.select { |format| format.for_class_name?(class_name) }
end
end
end
@@ -60,4 +60,11 @@ RSpec.describe CustomFields::DeleteContract do
include_examples "contract is invalid", base: :referenced_in_other_fields
end
end
describe "allows deleting a calculated_value field without an enterprise token" do
let(:current_user) { build_stubbed(:admin) }
let(:cf) { build_stubbed(:project_custom_field, field_format: "calculated_value") }
include_examples "contract is valid"
end
end
@@ -77,8 +77,7 @@ RSpec.shared_examples_for "custom_field contract" do
end
end
context "for a calculated field", with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "for a calculated field", with_ee: %i[calculated_values] do
let(:custom_field_field_format) { "calculated_value" }
let(:custom_field_is_required) { false }
let(:custom_field_formula) { "1 + 1" }
@@ -58,8 +58,7 @@ RSpec.describe CustomFields::UpdateContract do
subject(:contract) { described_class.new(custom_field, current_user) }
context "for a calculated field", with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "for a calculated field", with_ee: %i[calculated_values] do
let(:custom_field_field_format) { "calculated_value" }
let(:custom_field_formula) { "1 + 1" }
@@ -31,10 +31,7 @@
require "spec_helper"
require_relative "shared_context"
RSpec.describe "Edit project custom field calculated value",
:js,
with_ee: %i[calculated_values weighted_item_lists],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe "Edit project custom field calculated value", :js, with_ee: %i[calculated_values weighted_item_lists] do
include_context "with seeded project custom fields"
shared_let(:weighted_item_list_project_custom_field) do
@@ -128,40 +128,32 @@ RSpec.describe "Create project custom fields in sections", :js do
end
context "when trying to create calculated value field" do
context "without the feature flag", with_flag: { calculated_value_project_attribute: false } do
it "prevents creation" do
cf_index_page.expect_not_having_create_item "Calculated value"
before do
cf_index_page.click_to_create_new_custom_field "Calculated value"
end
context "without calculated_values enterprise feature" do
it do
expect(page)
.to have_enterprise_banner(:premium)
.and have_no_field("custom_field_name")
.and have_no_button("Save")
end
end
context "with the feature flag", with_flag: { calculated_value_project_attribute: true } do
before do
cf_index_page.click_to_create_new_custom_field "Calculated value"
end
context "with calculated_values enterprise feature", with_ee: %i[calculated_values] do
it "allows creation" do
fill_in("custom_field_name", with: "New calculated value custom field")
select(section_for_select_fields.name, from: "custom_field_custom_field_section_id")
find_field(id: "custom_field_formula", type: :hidden).set("1 + 1")
context "without calculated_values enterprise feature" do
it do
expect(page)
.to have_enterprise_banner(:premium)
.and have_no_field("custom_field_name")
.and have_no_button("Save")
end
end
click_on("Save")
context "with calculated_values enterprise feature", with_ee: %i[calculated_values] do
it "allows creation" do
fill_in("custom_field_name", with: "New calculated value custom field")
select(section_for_select_fields.name, from: "custom_field_custom_field_section_id")
find_field(id: "custom_field_formula", type: :hidden).set("1 + 1")
expect(page).to have_text("Successful creation")
click_on("Save")
expect(page).to have_text("Successful creation")
created = ProjectCustomField.find_by_name("New calculated value custom field")
expect(page).to have_current_path(admin_settings_project_custom_field_path(created))
expect(page).to have_text("New calculated value custom field")
end
created = ProjectCustomField.find_by_name("New calculated value custom field")
expect(page).to have_current_path(admin_settings_project_custom_field_path(created))
expect(page).to have_text("New calculated value custom field")
end
end
end
@@ -32,9 +32,7 @@ require "spec_helper"
require_relative "../format_field_expectations"
RSpec.describe "Project calculated value custom fields", :js do
context "with feature flag", with_flag: { calculated_value_project_attribute: true } do
context "with enterprise token", with_ee: %i[calculated_values] do
it_behaves_like "expected fields for the Project custom field's format", "Calculated value"
end
context "with enterprise token", with_ee: %i[calculated_values] do
it_behaves_like "expected fields for the Project custom field's format", "Calculated value"
end
end
@@ -157,7 +157,7 @@ RSpec.describe "List project custom fields", :js do
end
describe "managing project custom fields" do
context "with calculated value feature flag active", with_flag: { calculated_value_project_attribute: true } do
context "with calculated value type" do
it "offers the type for creation with enterprise icon" do
cf_index_page.expect_having_create_item(I18n.t("label_calculated_value"), enterprise_icon: true)
end
@@ -188,28 +188,6 @@ RSpec.describe "List project custom fields", :js do
expect(containers.last.text).to include(calculated_value_project_custom_field.name)
end
end
it "lists calculated values even if the feature flag is deactivated later" do
# This spec tests that calculated values are still shown after the feature flag is deactivated.
# First, a custom field of type calculated value is created. This must be done while the feature flag is active,
# or else the model validation will fail.
# Next, we simulate that the feature flag is off:
allow(OpenProject::FeatureDecisions).to receive(:calculated_value_project_attribute_active?).and_return(false)
# Revisit the page and check that the field is still listed:
cf_index_page.visit!
within_project_custom_field_section_container(section_for_input_fields) do
containers = page.all(".op-project-custom-field-container")
expect(containers.last.text).to include(calculated_value_project_custom_field.name)
end
end
end
end
context "without calculated value feature flag active" do
it "does not offer the type for creation" do
cf_index_page.expect_not_having_create_item("Calculated value")
end
end
@@ -31,10 +31,7 @@
require "spec_helper"
require_relative "shared_context"
RSpec.describe "Weighted item lists and calculated values",
:js,
with_ee: %i[calculated_values weighted_item_lists],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe "Weighted item lists and calculated values", :js, with_ee: %i[calculated_values weighted_item_lists] do
current_user { create(:admin) }
let!(:project) { create(:project) }
+1 -3
View File
@@ -397,9 +397,7 @@ RSpec.describe "Projects lists columns", :js, with_settings: { login_required?:
end
end
context "with calculated value columns",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "with calculated value columns", with_ee: %i[calculated_values] do
let!(:static_calculated_value) do
create(:calculated_value_project_custom_field,
name: "Calculated value field",
+1 -3
View File
@@ -734,9 +734,7 @@ RSpec.describe "Projects list filters", :js, with_settings: { login_required?: f
end
end
context "when filtering via calculated values",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "when filtering via calculated values", with_ee: %i[calculated_values] do
let(:projects_with_calculated_value) do
[project, public_project]
end
+1 -3
View File
@@ -273,9 +273,7 @@ RSpec.describe "Projects lists ordering", :js, with_settings: { login_required?:
projects_page.expect_project_at_place(project, 1)
end
context "when sorting calculated value custom fields",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "when sorting calculated value custom fields", with_ee: %i[calculated_values] do
let(:projects_with_calculated_value) do
[project, development_project, public_project, child_project_m, child_project_a]
end
@@ -521,9 +521,7 @@ RSpec.describe "Projects custom fields mapping via project settings", :js do
end
end
describe "calculated value fields",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated value fields", with_ee: %i[calculated_values] do
let!(:admin) do
create(:admin)
end
@@ -30,10 +30,7 @@
require "spec_helper"
RSpec.describe CustomFields::Inputs::CalculatedValue,
type: :forms,
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe CustomFields::Inputs::CalculatedValue, type: :forms, with_ee: %i[calculated_values] do
include_context "with rendered custom field input form"
let(:custom_field) { create(:calculated_value_project_custom_field, name: "Calculated value field", formula: "1 + 1") }
@@ -30,10 +30,7 @@
#
require "spec_helper"
RSpec.describe Projects::Settings::CustomFieldsForm,
type: :forms,
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe Projects::Settings::CustomFieldsForm, type: :forms, with_ee: %i[calculated_values] do
let(:string_project_custom_field) do
create(:string_project_custom_field, name: "String field", is_required: true, is_for_all: true)
end
@@ -36,23 +36,22 @@ RSpec.describe OpenProject::CustomFieldFormat do
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)
expect(formats.map(&:name)).to eq(expected_formats)
end
end
context "for a 'Project' class" do
context "with some enterprise addons",
with_ee: %i[calculated_values weighted_item_lists custom_field_hierarchies],
with_flag: { calculated_value_project_attribute: true } do
with_ee: %i[calculated_values weighted_item_lists custom_field_hierarchies] do
it_behaves_like "custom field formats",
"Project",
%w[bool calculated_value date float hierarchy int link list string text user version weighted_item_list]
%w[string text link int float list date bool user version hierarchy weighted_item_list calculated_value]
end
context "without enterprise addons" do
it_behaves_like "custom field formats",
"Project",
%w[bool date float int link list string text user version]
%w[string text link int float list date bool user version]
end
end
@@ -60,73 +59,38 @@ RSpec.describe OpenProject::CustomFieldFormat do
context "with some enterprise addons", with_ee: %i[weighted_item_lists custom_field_hierarchies] do
it_behaves_like "custom field formats",
"WorkPackage",
%w[bool date float hierarchy int link list weighted_item_list string text user version]
%w[string text link int float list date bool user version hierarchy weighted_item_list]
end
context "without enterprise addons" do
it_behaves_like "custom field formats",
"WorkPackage",
%w[bool date float int link list string text user version]
%w[string text link int float list date bool user version]
end
end
context "for a 'Version' class" do
it_behaves_like "custom field formats",
"Version",
%w[bool date float int list string text user version]
%w[string text int float list date bool user version]
end
context "for a 'TimeEntry' class" do
it_behaves_like "custom field formats",
"TimeEntry",
%w[bool date float int list string text user version]
%w[string text int float list date bool user version]
end
context "for a 'User' class" do
it_behaves_like "custom field formats",
"User",
%w[bool date float int list string text]
%w[string text int float list date bool]
end
context "for a 'Group' class" do
it_behaves_like "custom field formats",
"Group",
%w[bool date float int list string text]
end
end
describe ".available_formats" do
shared_examples_for "available custom field formats" do |suffix, expected_formats|
it "returns all custom field formats #{suffix}", :aggregate_failures do
formats = described_class.available_formats
expect(formats).to match_array(expected_formats)
end
end
context "with a custom_field_hierarchies ee", with_ee: [:custom_field_hierarchies] do
it_behaves_like "available custom field formats",
"including hierarchy",
%w[bool date float hierarchy int link list string text user version empty]
end
context "with a weighted item lists ee", with_ee: [:weighted_item_lists] do
it_behaves_like "available custom field formats",
"including hierarchy",
%w[bool date float int link list string text user version weighted_item_list empty]
end
context "without a custom_field_hierarchies ee" do
it_behaves_like "available custom field formats",
"excluding hierarchy",
%w[bool date float int link list string text user version empty]
context "with a calculated values ee",
with_ee: [:calculated_values],
with_flag: { calculated_value_project_attribute: true } do
it_behaves_like "available custom field formats",
"including calculated values",
%w[bool calculated_value date float int link list string text user version empty]
end
%w[string text int float list date bool]
end
end
@@ -135,36 +99,103 @@ RSpec.describe OpenProject::CustomFieldFormat do
it "returns all custom field formats for the '#{class_name}' class", :aggregate_failures do
formats = described_class.enabled_for_class_name(class_name)
expect(formats).to all(be_a described_class)
expect(formats.map(&:name)).to match_array(expected_formats)
expect(formats.map(&:name)).to eq(expected_formats)
end
end
context "for a 'Project' class" do
context "with feature flags enabled", with_flag: { calculated_value_project_attribute: true } do
it_behaves_like "custom field formats",
"Project",
%w[bool calculated_value date float hierarchy int link list string text user version weighted_item_list]
end
it_behaves_like "custom field formats",
"Project",
%w[string text link int float list date bool user version hierarchy weighted_item_list calculated_value]
end
context "with no feature flags enabled", with_flag: {} do
it_behaves_like "custom field formats",
"Project",
%w[bool date float hierarchy int link list string text user version weighted_item_list]
context "for a 'WorkPackage' class" do
it_behaves_like "custom field formats",
"WorkPackage",
%w[string text link int float list date bool user version hierarchy weighted_item_list]
end
context "for a 'Version' class" do
it_behaves_like "custom field formats",
"Version",
%w[string text int float list date bool user version]
end
context "for a 'TimeEntry' class" do
it_behaves_like "custom field formats",
"TimeEntry",
%w[string text int float list date bool user version]
end
context "for a 'User' class" do
it_behaves_like "custom field formats",
"User",
%w[string text int float list date bool]
end
context "for a 'Group' class" do
it_behaves_like "custom field formats",
"Group",
%w[string text int float list date bool]
end
end
describe ".registered_formats" do
it "returns all formats" do
expect(described_class.registered_formats)
.to eq(%w[string text link int float list date bool user version empty hierarchy weighted_item_list calculated_value])
end
end
describe ".available_formats" do
shared_examples_for "available custom field formats" do |suffix, expected_formats|
it "returns all custom field formats #{suffix}", :aggregate_failures do
expect(described_class.available_formats).to eq(expected_formats)
end
end
context "without any ee" do
it_behaves_like "available custom field formats",
"not requiring an ee",
%w[string text link int float list date bool user version empty]
end
context "with a custom_field_hierarchies ee", with_ee: [:custom_field_hierarchies] do
it_behaves_like "available custom field formats",
"including hierarchy",
%w[string text link int float list date bool user version empty hierarchy]
end
context "with a weighted_item_lists ee", with_ee: [:weighted_item_lists] do
it_behaves_like "available custom field formats",
"including hierarchy",
%w[string text link int float list date bool user version empty weighted_item_list]
end
context "with a calculated_values ee", with_ee: [:calculated_values] do
it_behaves_like "available custom field formats",
"including calculated values",
%w[string text link int float list date bool user version empty calculated_value]
end
context "with all ees", with_ee: %i[custom_field_hierarchies weighted_item_lists calculated_values] do
it_behaves_like "available custom field formats",
"including hierarchy",
%w[string text link int float list date bool user version empty hierarchy weighted_item_list
calculated_value]
end
end
describe ".enabled_formats" do
it "returns all formats" do
expect(described_class.enabled_formats)
.to eq(%w[string text link int float list date bool user version empty hierarchy weighted_item_list calculated_value])
end
end
describe ".disabled_formats" do
it "returns disabled formats" do
formats = described_class.disabled_formats
expect(formats).to match_array(%w[calculated_value])
end
context "with feature flags enabled", with_flag: { calculated_value_project_attribute: true } do
it "returns no disabled formats" do
formats = described_class.disabled_formats
expect(formats).to be_empty
end
it "returns no disabled formats" do
expect(described_class.disabled_formats).to be_empty
end
end
end
@@ -31,9 +31,7 @@
require "spec_helper"
require Rails.root.join("db/migrate/20251211160744_set_is_for_all_and_unset_required")
RSpec.describe SetIsForAllAndUnsetRequired, type: :model,
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe SetIsForAllAndUnsetRequired, type: :model, with_ee: %i[calculated_values] do
# Project custom fields to be migrated
shared_let(:required_project_cf) { create(:project_custom_field, :integer, is_required: true, is_for_all: false) }
shared_let(:optional_project_cf) { create(:project_custom_field, :integer, is_required: false, is_for_all: false) }
@@ -30,9 +30,7 @@
require "spec_helper"
RSpec.describe ActsAsCustomizable::CalculatedValue,
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe ActsAsCustomizable::CalculatedValue, with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
include CalculatedValues::ErrorsHelper
@@ -30,9 +30,7 @@
require "spec_helper"
RSpec.describe CustomField::CalculatedValue,
with_ee: %i[calculated_values weighted_item_lists],
with_flag: { calculated_value_project_attribute: true } do
RSpec.describe CustomField::CalculatedValue, with_ee: %i[calculated_values weighted_item_lists] do
using CustomFieldFormulaReferencing
subject(:custom_field) { create(:calculated_value_project_custom_field, formula: "1 + 1") }
+2 -6
View File
@@ -204,9 +204,7 @@ RSpec.describe Project, "customizable" do
.to contain_exactly(text_custom_field, bool_custom_field)
end
describe "#valid?",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "#valid?", with_ee: %i[calculated_values] do
let(:another_section) { create(:project_custom_field_section) }
let(:project) do
build(:project, custom_field_values: {
@@ -377,9 +375,7 @@ RSpec.describe Project, "customizable" do
.to eq("bar")
end
describe "#valid?",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "#valid?", with_ee: %i[calculated_values] do
let!(:project) do
create(:project, custom_field_values: {
text_custom_field.id => "foo",
@@ -62,9 +62,7 @@ RSpec.describe CustomFields::CreateService, type: :model do
subject(:instance_call) { instance.call(attributes) }
describe "calculated value custom field",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated value custom field", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
shared_let(:project_custom_field_section) { create(:project_custom_field_section) }
@@ -430,9 +430,7 @@ RSpec.describe CustomFields::Hierarchy::HierarchicalItemService, with_ee: [:cust
end
end
context "with weighted item list and calculated values",
with_ee: %i[calculated_values weighted_item_lists],
with_flag: { calculated_value_project_attribute: true } do
context "with weighted item list and calculated values", with_ee: %i[calculated_values weighted_item_lists] do
current_user { create(:admin) }
let!(:project_using_one) { create(:project) }
@@ -65,9 +65,7 @@ RSpec.describe CustomFields::UpdateService, type: :model do
end
end
describe "calculated value custom field",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated value custom field", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
context "when updating not a calculated value" do
@@ -41,9 +41,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::BulkCreateService do
let(:required_permission) { :select_project_custom_fields }
end
describe "calculated values",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated values", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
shared_let(:user) { create(:admin) }
@@ -190,9 +190,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::BulkUpdateService do
end
end
describe "calculated values",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated values", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
shared_let(:user) { create(:admin) }
@@ -39,9 +39,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::DeleteService do
end
end
describe "calculated values",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated values", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
shared_let(:user) { create(:admin) }
@@ -246,9 +246,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do
end
end
describe "calculated values",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated values", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
shared_let(:user) { create(:admin) }
@@ -267,9 +267,7 @@ RSpec.describe(
end
end
context "with calculated custom fields",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "with calculated custom fields", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
let(:integer_custom_field) { create(:integer_project_custom_field, projects: [source]) }
let(:calculated_custom_field) do
@@ -315,9 +313,7 @@ RSpec.describe(
expect(calculated_cv.value).to eq "16"
end
context "with calculation errors",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "with calculation errors", with_ee: %i[calculated_values] do
let(:calculated_custom_field) do
create(:calculated_value_project_custom_field, :skip_validations,
projects: [source],
@@ -169,9 +169,7 @@ RSpec.describe Projects::CreateService, type: :model do
end
end
context "with for_all custom fields",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
context "with for_all custom fields", with_ee: %i[calculated_values] do
let!(:calculated_custom_field) do
create(:calculated_value_project_custom_field,
project_custom_field_section: section)
@@ -230,9 +228,7 @@ RSpec.describe Projects::CreateService, type: :model do
end
end
describe "calculated custom fields",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated custom fields", with_ee: %i[calculated_values] do
shared_let(:cf_static) { create(:integer_project_custom_field, is_for_all: true) }
let(:project) { create(:project) }
let!(:model_instance) { project }
@@ -82,9 +82,7 @@ RSpec.describe Projects::UpdateService, type: :model do
end
end
describe "calculated custom fields",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "calculated custom fields", with_ee: %i[calculated_values] do
let(:project) { create(:project) }
let!(:model_instance) { project }
# Remove the set_attributes_service mocking to use the real service.
+1 -1
View File
@@ -24,7 +24,7 @@ module Flash
def expect_no_flash(type: :success, message: nil, exact_message: nil, wait: 10)
if type.nil?
expect(page).not_to have_test_selector("op-primer-flash-message")
expect(page).to have_no_test_selector("op-primer-flash-message")
else
expected_css = expected_flash_css(type)
expect(page).to have_no_css(expected_css, wait:, **{ text: message, exact_text: exact_message }.compact)
@@ -31,9 +31,7 @@
require "spec_helper"
RSpec.describe CustomFields::RecalculateValuesJob, type: :model do
describe "#perform",
with_ee: %i[calculated_values],
with_flag: { calculated_value_project_attribute: true } do
describe "#perform", with_ee: %i[calculated_values] do
using CustomFieldFormulaReferencing
shared_let(:user) { create(:admin) }