From 10ef01b2cbd83caa54f348795f567ec73a330780 Mon Sep 17 00:00:00 2001 From: Tobias Dillmann Date: Tue, 9 Dec 2025 08:18:43 +0100 Subject: [PATCH] [#69399] Additional specs --- spec/models/project_custom_field_spec.rb | 20 ++++++++- .../v3/workspaces/update_resource_examples.rb | 38 ++++++++++++++++ .../bulk_update_service_spec.rb | 10 +++++ .../toggle_service_spec.rb | 44 +++++++++++++++---- 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/spec/models/project_custom_field_spec.rb b/spec/models/project_custom_field_spec.rb index 391e26008e8..f5609a6b466 100644 --- a/spec/models/project_custom_field_spec.rb +++ b/spec/models/project_custom_field_spec.rb @@ -36,7 +36,7 @@ RSpec.describe ProjectCustomField do let!(:project) { create(:project) } let!(:another_project) { create(:project) } - it "activates the required project custom fields in all projects" do + it "activates the project custom fields in all projects" do project_custom_field = create(:project_custom_field, is_for_all: true) expect(ProjectCustomFieldProjectMapping).to exist(custom_field_id: project_custom_field.id, @@ -46,6 +46,24 @@ RSpec.describe ProjectCustomField do end end + context "when creating a new project custom field" do + let!(:project) { create(:project) } + let!(:another_project) { create(:project) } + + it "activates the custom field in projects it is assigned to" do + # Same activation rules apply for optional and required custom fields: + optional_cf = create(:project_custom_field, projects: [project]) + required_cf = create(:project_custom_field, is_required: true, projects: [project]) + + [optional_cf, required_cf].each do |cf| + expect(ProjectCustomFieldProjectMapping).to exist(custom_field_id: cf.id, + project_id: project.id) + expect(ProjectCustomFieldProjectMapping).not_to exist(custom_field_id: cf.id, + project_id: another_project.id) + end + end + end + context "when setting an existing project custom field to is_for_all" do let!(:project_custom_field) { create(:string_project_custom_field) } # optional now let!(:project) do diff --git a/spec/requests/api/v3/workspaces/update_resource_examples.rb b/spec/requests/api/v3/workspaces/update_resource_examples.rb index e13cf70d01d..f2d9a99c9f4 100644 --- a/spec/requests/api/v3/workspaces/update_resource_examples.rb +++ b/spec/requests/api/v3/workspaces/update_resource_examples.rb @@ -196,6 +196,19 @@ RSpec.shared_examples_for "APIv3 workspace update" do expect(workspace.project_custom_fields) .to contain_exactly(custom_field) end + + context "when the field is for_all, but not required" do + let!(:for_all_custom_field) do + create(:text_project_custom_field, + name: "Department", + is_for_all: true) + end + + it "automatically activates the cf for workspace even if no value was provided" do + expect(workspace.project_custom_fields) + .to contain_exactly(for_all_custom_field, custom_field) + end + end end context "with an admin only custom field" do @@ -278,6 +291,31 @@ RSpec.shared_examples_for "APIv3 workspace update" do .to be_empty end end + + context "and when the custom field is forced active (is_for_all)" do + let(:admin_only_custom_field) do + create(:text_project_custom_field, admin_only: true, is_for_all: true) + end + let(:body) do + { + name: "Updated workspace name" + } + end + + it "responds with 200 OK" do + expect(last_response).to have_http_status(:ok) + end + + it "does not set the cf value" do + expect(workspace.reload.typed_custom_value_for(admin_only_custom_field)) + .to be_nil + end + + it "does activate the cf for workspace" do + expect(workspace.reload.project_custom_fields) + .to contain_exactly(admin_only_custom_field) + end + end end end end diff --git a/spec/services/project_custom_field_project_mappings/bulk_update_service_spec.rb b/spec/services/project_custom_field_project_mappings/bulk_update_service_spec.rb index 13c0f789b36..05e2d029ccf 100644 --- a/spec/services/project_custom_field_project_mappings/bulk_update_service_spec.rb +++ b/spec/services/project_custom_field_project_mappings/bulk_update_service_spec.rb @@ -44,6 +44,14 @@ RSpec.describe ProjectCustomFieldProjectMappings::BulkUpdateService do project_custom_field_section:) end + shared_let(:visible_required_project_custom_field) do + create(:project_custom_field, + name: "Visible required field", + admin_only: false, + is_required: true, + project_custom_field_section:) + end + shared_let(:visible_activated_project_custom_field) do create(:project_custom_field, name: "Visible activated field", @@ -69,6 +77,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::BulkUpdateService do expected = [ visible_activated_project_custom_field, + visible_required_project_custom_field, visible_project_custom_field, invisible_project_custom_field ] @@ -102,6 +111,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::BulkUpdateService do expected = [ visible_activated_project_custom_field, + visible_required_project_custom_field, visible_project_custom_field ] expect(project.reload.project_custom_fields).to match_array(expected) diff --git a/spec/services/project_custom_field_project_mappings/toggle_service_spec.rb b/spec/services/project_custom_field_project_mappings/toggle_service_spec.rb index 941d5ab4e23..cfe3745fda5 100644 --- a/spec/services/project_custom_field_project_mappings/toggle_service_spec.rb +++ b/spec/services/project_custom_field_project_mappings/toggle_service_spec.rb @@ -44,9 +44,17 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do project_custom_field_section:) end + shared_let(:required_custom_field) do + create(:project_custom_field, + name: "Required field", + admin_only: false, + is_required: true, + project_custom_field_section:) + end + shared_let(:forced_active_custom_field) do create(:project_custom_field, - name: "Visible required field", + name: "Visible forced-active field", admin_only: false, is_for_all: true, project_custom_field_section:) @@ -60,13 +68,14 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do end let(:visible_custom_field_params) { { project_id: project.id, custom_field_id: visible_custom_field.id } } + let(:required_custom_field_params) { { project_id: project.id, custom_field_id: required_custom_field.id } } let(:forced_active_custom_field_params) { { project_id: project.id, custom_field_id: forced_active_custom_field.id } } let(:invisible_custom_field_params) { { project_id: project.id, custom_field_id: invisible_custom_field.id } } context "with admin permissions" do shared_let(:user) { create(:admin) } - it "toggles visible, non-required fields" do + it "toggles visible, non-is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) 2.times do @@ -83,7 +92,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do end end - it "toggles invisible, non-required fields" do + it "toggles invisible, non-is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) 2.times do @@ -100,7 +109,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do end end - it "does not toggle required fields" do + it "does not toggle is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) expect(instance.call(**forced_active_custom_field_params, value: "1")).to be_failure @@ -111,6 +120,23 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do expect(project.reload.project_custom_fields).to contain_exactly(forced_active_custom_field) end + + it "does toggle required fields" do + expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) + + 2.times do + expect(instance.call(**required_custom_field_params, value: "1")).to be_success + + expected = [forced_active_custom_field, required_custom_field] + expect(project.reload.project_custom_fields).to match_array(expected) + end + + 2.times do + expect(instance.call(**required_custom_field_params, value: "0")).to be_success + + expect(project.reload.project_custom_fields).to contain_exactly(forced_active_custom_field) + end + end end context "with non-admin but sufficient permissions" do @@ -127,7 +153,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do }) end - it "toggles visible, non-required fields" do + it "toggles visible, non-is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) 2.times do @@ -156,7 +182,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do expect(project.reload.project_custom_fields).to contain_exactly(forced_active_custom_field) end - it "does not toggle required fields" do + it "does not toggle is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) expect(instance.call(**forced_active_custom_field_params, value: "1")).to be_failure @@ -182,7 +208,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do }) end - it "does not toggle visible, non-required fields" do + it "does not toggle visible, non-is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) expect(instance.call(**visible_custom_field_params, value: "1")).to be_failure @@ -194,7 +220,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do expect(project.reload.project_custom_fields).to contain_exactly(forced_active_custom_field) end - it "does not toggle invisible, non-required fields" do + it "does not toggle invisible, non-is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) expect(instance.call(**invisible_custom_field_params, value: "1")).to be_failure @@ -206,7 +232,7 @@ RSpec.describe ProjectCustomFieldProjectMappings::ToggleService do expect(project.reload.project_custom_fields).to contain_exactly(forced_active_custom_field) end - it "does not toggle required fields" do + it "does not toggle is_for_all fields" do expect(project.project_custom_fields).to contain_exactly(forced_active_custom_field) expect(instance.call(**forced_active_custom_field_params, value: "1")).to be_failure