diff --git a/spec/models/acts_as_customizable/calculated_value_spec.rb b/spec/models/acts_as_customizable/calculated_value_spec.rb index eca2566922c..cf8a7cb5c31 100644 --- a/spec/models/acts_as_customizable/calculated_value_spec.rb +++ b/spec/models/acts_as_customizable/calculated_value_spec.rb @@ -31,6 +31,8 @@ require "spec_helper" RSpec.describe ActsAsCustomizable::CalculatedValue, with_flag: { calculated_value_project_attribute: true } do + using CustomFieldFormulaReferencing + let(:model_class) do Class.new do include ActsAsCustomizable::CalculatedValue @@ -47,8 +49,6 @@ RSpec.describe ActsAsCustomizable::CalculatedValue, with_flag: { calculated_valu allow(instance).to receive(:custom_field_values=) end - def ref(custom_field) = "{{cf_#{custom_field.id}}}" - describe "#calculate_custom_fields" do context "when calling with empty array" do let(:custom_field_values) { [:foo] } @@ -143,8 +143,8 @@ RSpec.describe ActsAsCustomizable::CalculatedValue, with_flag: { calculated_valu let(:cf_a) { build_stubbed(:integer_project_custom_field) } let(:cf_b) { build_stubbed(:integer_project_custom_field) } - let(:cf1) { build_stubbed(:calculated_value_project_custom_field, formula: "#{ref cf_a} + #{ref cf_b}") } - let(:cf2) { build_stubbed(:calculated_value_project_custom_field, formula: "#{ref cf_a} * #{ref cf_b}") } + let(:cf1) { build_stubbed(:calculated_value_project_custom_field, formula: "#{cf_a} + #{cf_b}") } + let(:cf2) { build_stubbed(:calculated_value_project_custom_field, formula: "#{cf_a} * #{cf_b}") } let(:custom_field_values) do { @@ -168,7 +168,7 @@ RSpec.describe ActsAsCustomizable::CalculatedValue, with_flag: { calculated_valu context "when calling with custom fields referencing other calculated fields" do let(:cf1) { build_stubbed(:calculated_value_project_custom_field, formula: "1 + 1") } let(:cf2) { build_stubbed(:calculated_value_project_custom_field, formula: "1 + 2") } - let(:cf3) { build_stubbed(:calculated_value_project_custom_field, formula: "#{ref cf1} * #{ref cf2}") } + let(:cf3) { build_stubbed(:calculated_value_project_custom_field, formula: "#{cf1} * #{cf2}") } let(:custom_field_values) do { @@ -206,8 +206,8 @@ RSpec.describe ActsAsCustomizable::CalculatedValue, with_flag: { calculated_valu let(:cf_missing) { build_stubbed(:integer_project_custom_field) } let(:cf_unavailable) { build_stubbed(:integer_project_custom_field) } - let(:cf_using_missing) { build_stubbed(:calculated_value_project_custom_field, formula: "1 + #{ref cf_missing}") } - let(:cf_using_unavailable) { build_stubbed(:calculated_value_project_custom_field, formula: "2 + #{ref cf_unavailable}") } + let(:cf_using_missing) { build_stubbed(:calculated_value_project_custom_field, formula: "1 + #{cf_missing}") } + let(:cf_using_unavailable) { build_stubbed(:calculated_value_project_custom_field, formula: "2 + #{cf_unavailable}") } let(:cf_other) { build_stubbed(:calculated_value_project_custom_field, formula: "1 + 2") } let(:custom_field_values) do @@ -252,10 +252,10 @@ RSpec.describe ActsAsCustomizable::CalculatedValue, with_flag: { calculated_valu before do { - cf1 => "#{ref cf_a} * #{ref cf2}", - cf2 => "#{ref cf_b} * #{ref cf3}", - cf3 => "#{ref cf1} * #{ref cf4}", - cf4 => "#{ref cf_c} * #{ref cf_d}" + cf1 => "#{cf_a} * #{cf2}", + cf2 => "#{cf_b} * #{cf3}", + cf3 => "#{cf1} * #{cf4}", + cf4 => "#{cf_c} * #{cf_d}" }.each do |cf, formula| cf.formula = formula end diff --git a/spec/models/custom_field/calculated_value_spec.rb b/spec/models/custom_field/calculated_value_spec.rb index e9d73806944..d92541a9433 100644 --- a/spec/models/custom_field/calculated_value_spec.rb +++ b/spec/models/custom_field/calculated_value_spec.rb @@ -31,17 +31,17 @@ require "spec_helper" RSpec.describe CustomField::CalculatedValue, with_flag: { calculated_value_project_attribute: true } do - subject(:custom_field) { create(:calculated_value_project_custom_field, formula: "1 + 1") } + using CustomFieldFormulaReferencing - def ref(custom_field) = "{{cf_#{custom_field.id}}}" + subject(:custom_field) { create(:calculated_value_project_custom_field, formula: "1 + 1") } describe ".with_formula_referencing", :aggregate_failures do shared_let(:cf_a) { create(:integer_project_custom_field, default_value: 1) } shared_let(:cf_b) { create(:integer_project_custom_field, default_value: 2) } shared_let(:cf_c) { create(:integer_project_custom_field, default_value: 3) } - shared_let(:cf1) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_a} + #{ref cf_b}") } - shared_let(:cf2) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_b} + #{ref cf1}") } + shared_let(:cf1) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_a} + #{cf_b}") } + shared_let(:cf2) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_b} + #{cf1}") } let(:scope) { CustomField } @@ -70,10 +70,10 @@ RSpec.describe CustomField::CalculatedValue, with_flag: { calculated_value_proje shared_let(:cf_b) { create(:integer_project_custom_field, default_value: 2) } shared_let(:cf_c) { create(:integer_project_custom_field, default_value: 3) } shared_let(:cf_d) { create(:integer_project_custom_field, default_value: 4) } - shared_let(:cf1) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_a} * 2") } - shared_let(:cf2) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_a} + #{ref cf_b}") } - shared_let(:cf3) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_b} * 2") } - shared_let(:cf4) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_c} * 2") } + shared_let(:cf1) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_a} * 2") } + shared_let(:cf2) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_a} + #{cf_b}") } + shared_let(:cf3) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_b} * 2") } + shared_let(:cf4) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_c} * 2") } it "returns an empty array if argument is empty" do expect(scope.affected_calculated_fields([])).to eq([]) @@ -141,9 +141,9 @@ RSpec.describe CustomField::CalculatedValue, with_flag: { calculated_value_proje shared_let(:cf_c) { create(:integer_project_custom_field, default_value: 3) } shared_let(:cf_d) { create(:integer_project_custom_field, default_value: 4) } - shared_let(:cf1) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf_a} + #{ref cf_b}") } - shared_let(:cf2) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf1} * #{ref cf_c}") } - shared_let(:cf3) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{ref cf2} * #{ref cf_d}") } + shared_let(:cf1) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf_a} + #{cf_b}") } + shared_let(:cf2) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf1} * #{cf_c}") } + shared_let(:cf3) { create(:calculated_value_project_custom_field, :skip_validations, formula: "#{cf2} * #{cf_d}") } it "returns referencing fields when passing referenced constant field ids" do expect(scope.affected_calculated_fields([cf_a.id])).to contain_exactly(cf1, cf2, cf3) @@ -193,9 +193,9 @@ RSpec.describe CustomField::CalculatedValue, with_flag: { calculated_value_proje before do { - cf1 => "#{ref cf_a} + #{ref cf2}", - cf2 => "#{ref cf_b} + #{ref cf3}", - cf3 => "#{ref cf_c} + #{ref cf1}" + cf1 => "#{cf_a} + #{cf2}", + cf2 => "#{cf_b} + #{cf3}", + cf3 => "#{cf_c} + #{cf1}" }.each do |cf, formula| cf.formula = formula cf.save!(validate: false) diff --git a/spec/services/projects/set_attributes_service_spec.rb b/spec/services/projects/set_attributes_service_spec.rb index df07cb5be9f..b85b17c4c78 100644 --- a/spec/services/projects/set_attributes_service_spec.rb +++ b/spec/services/projects/set_attributes_service_spec.rb @@ -322,7 +322,7 @@ RSpec.describe Projects::SetAttributesService, type: :model do end end - def ref(custom_field) = "{{cf_#{custom_field.id}}}" + using CustomFieldFormulaReferencing context "when trying to explicitly set values of calculated custom fields" do let!(:cf_static) { create(:integer_project_custom_field, projects: [project]) } @@ -355,12 +355,12 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_calculated1) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_static} * 7") + formula: "#{cf_static} * 7") end let!(:cf_calculated2) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_calculated1} * 11") + formula: "#{cf_calculated1} * 11") end let(:call_attributes) do @@ -391,12 +391,12 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_calculated1) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_static} * 7") + formula: "#{cf_static} * 7") end let!(:cf_calculated2) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_calculated1} * 11") + formula: "#{cf_calculated1} * 11") end let(:call_attributes) do @@ -428,15 +428,15 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_c) { create(:integer_project_custom_field, projects: [project]) } let!(:cf_calculated1) do create(:calculated_value_project_custom_field, :skip_validations, - projects: [project], formula: "#{ref cf_a} * 7") + projects: [project], formula: "#{cf_a} * 7") end let!(:cf_calculated2) do create(:calculated_value_project_custom_field, :skip_validations, - projects: [project], formula: "#{ref cf_b} * 11") + projects: [project], formula: "#{cf_b} * 11") end let!(:cf_calculated3) do create(:calculated_value_project_custom_field, :skip_validations, - projects: [project], formula: "#{ref cf_c} * 13") + projects: [project], formula: "#{cf_c} * 13") end let(:call_attributes) do @@ -474,16 +474,16 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_calculated1) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_static} * 7") + formula: "#{cf_static} * 7") end let!(:cf_calculated2) do create(:calculated_value_project_custom_field, :skip_validations, - formula: "#{ref cf_calculated1} * 11") + formula: "#{cf_calculated1} * 11") end let!(:cf_calculated3) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_calculated2} * 13") + formula: "#{cf_calculated2} * 13") end let(:call_attributes) do @@ -522,17 +522,17 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_calculated1) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_static} * 7") + formula: "#{cf_static} * 7") end let!(:cf_calculated2) do create(:calculated_value_project_custom_field, :skip_validations, :admin_only, projects: [project], - formula: "#{ref cf_calculated1} * 11") + formula: "#{cf_calculated1} * 11") end let!(:cf_calculated3) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_calculated2} * 13") + formula: "#{cf_calculated2} * 13") end let(:call_attributes) do @@ -565,7 +565,7 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_calculated) do create(:calculated_value_project_custom_field, :skip_validations, projects: [project], - formula: "#{ref cf_static} * #{ref cf_referenced}") + formula: "#{cf_static} * #{cf_referenced}") end let(:call_attributes) do @@ -632,7 +632,7 @@ RSpec.describe Projects::SetAttributesService, type: :model do let!(:cf_referenced) do create(:calculated_value_project_custom_field, :skip_validations, :admin_only, projects: [project], - formula: "21 * #{ref cf_referenced1}") + formula: "21 * #{cf_referenced1}") end before do diff --git a/spec/support/custom_field_formula_referencing.rb b/spec/support/custom_field_formula_referencing.rb new file mode 100644 index 00000000000..216a5d24634 --- /dev/null +++ b/spec/support/custom_field_formula_referencing.rb @@ -0,0 +1,42 @@ +# 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. +#++ + +# Allows cleaner building of calculated value formulas in specs: +# +# using CustomFieldFormulaReferencing +# +# create(:calculated_value_project_custom_field, formula: "#{cf_1} * #{cf_2} + #{cf_3}") +module CustomFieldFormulaReferencing + refine CustomField do + def to_s + "{{cf_#{id}}}" + end + end +end