mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
prevent sprint sharing on contract level
This commit is contained in:
@@ -36,6 +36,7 @@ module Projects
|
||||
validate :validate_global_sprint_sharer_uniqueness
|
||||
validates :sprint_sharing, presence: true
|
||||
validates :sprint_sharing, inclusion: { in: Project::SPRINT_SHARING_MODES }, allow_blank: true
|
||||
validate :validate_sprint_sharing_in_ee_token
|
||||
|
||||
def validate_model? = false
|
||||
|
||||
@@ -59,5 +60,19 @@ module Projects
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def validate_sprint_sharing_in_ee_token
|
||||
if !model.not_sharing_sprints? &&
|
||||
!EnterpriseToken.allows_to?(:sprint_sharing) &&
|
||||
sprint_sharing_changed?
|
||||
errors.add :sprint_sharing,
|
||||
:enterprise_plan_required,
|
||||
plan_name: I18n.t("ee.upsell.plan_name", plan: OpenProject::Token.lowest_plan_for(:sprint_sharing))
|
||||
end
|
||||
end
|
||||
|
||||
def sprint_sharing_changed?
|
||||
model.settings_change&.any? { it.key?("sprint_sharing") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
require "spec_helper"
|
||||
require "contracts/shared/model_contract_shared_context"
|
||||
|
||||
RSpec.describe Projects::BacklogSettingsContract, type: :model do
|
||||
RSpec.describe Projects::BacklogSettingsContract, type: :model, with_ee: %i[sprint_sharing] do
|
||||
include_context "ModelContract shared context"
|
||||
|
||||
let(:current_user) { build_stubbed(:user) }
|
||||
let(:project) { create(:project) }
|
||||
let(:project) { build_stubbed(:project) }
|
||||
let(:permissions) { %i(share_sprint) }
|
||||
|
||||
subject(:contract) { described_class.new(project, current_user) }
|
||||
@@ -35,7 +35,7 @@ RSpec.describe Projects::BacklogSettingsContract, type: :model do
|
||||
|
||||
# This spec of explicitly setting sprint_sharing to empty is required because the
|
||||
# simple presence validation spec is not sufficient to catch certain corner cases.
|
||||
# For example, when the sprint_sharing getter is overriden to provide a default value,
|
||||
# For example, when the sprint_sharing getter is overridden to provide a default value,
|
||||
# and the user submits an empty value, the contract should be invalid.
|
||||
context "when sprint_sharing is empty" do
|
||||
before { project.sprint_sharing = "" }
|
||||
@@ -57,6 +57,62 @@ RSpec.describe Projects::BacklogSettingsContract, type: :model do
|
||||
end
|
||||
end
|
||||
|
||||
context "when the `sprint_sharing` is not part of the current EE token", with_ee: [] do
|
||||
context "when sprint sharing is set to 'no_sharing'" do
|
||||
before { project.sprint_sharing = Project::NO_SHARING }
|
||||
|
||||
it_behaves_like "contract is valid"
|
||||
end
|
||||
|
||||
context "when sprint sharing is set to 'share_all_projects'" do
|
||||
before { project.sprint_sharing = Project::SHARE_ALL_PROJECTS }
|
||||
|
||||
it_behaves_like "contract is invalid",
|
||||
sprint_sharing: { error: :enterprise_plan_required, plan_name: "corporate enterprise plan" }
|
||||
end
|
||||
|
||||
context "when sprint sharing is set to 'share_subprojects'" do
|
||||
before { project.sprint_sharing = Project::SHARE_SUBPROJECTS }
|
||||
|
||||
it_behaves_like "contract is invalid",
|
||||
sprint_sharing: { error: :enterprise_plan_required, plan_name: "corporate enterprise plan" }
|
||||
end
|
||||
|
||||
context "when sprint sharing is set to 'receive_shared'" do
|
||||
before { project.sprint_sharing = Project::RECEIVE_SHARED }
|
||||
|
||||
it_behaves_like "contract is invalid",
|
||||
sprint_sharing: { error: :enterprise_plan_required, plan_name: "corporate enterprise plan" }
|
||||
end
|
||||
|
||||
context "when sprint sharing remains on 'share_all_projects'" do
|
||||
before do
|
||||
project.sprint_sharing = Project::SHARE_ALL_PROJECTS
|
||||
project.clear_changes_information
|
||||
end
|
||||
|
||||
it_behaves_like "contract is valid"
|
||||
end
|
||||
|
||||
context "when sprint sharing remains on 'share_subprojects'" do
|
||||
before do
|
||||
project.sprint_sharing = Project::SHARE_SUBPROJECTS
|
||||
project.clear_changes_information
|
||||
end
|
||||
|
||||
it_behaves_like "contract is valid"
|
||||
end
|
||||
|
||||
context "when sprint sharing remains on 'receive_shared'" do
|
||||
before do
|
||||
project.sprint_sharing = Project::RECEIVE_SHARED
|
||||
project.clear_changes_information
|
||||
end
|
||||
|
||||
it_behaves_like "contract is valid"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#validate_global_sprint_sharer_uniqueness" do
|
||||
before do
|
||||
project.sprint_sharing = "share_all_projects"
|
||||
|
||||
@@ -48,7 +48,11 @@ RSpec.shared_context "ModelContract shared context" do # rubocop:disable RSpec/C
|
||||
[error_symbols]
|
||||
end
|
||||
end
|
||||
contract_errors = errors.keys.index_with { |key| contract.errors.symbols_for(key) }
|
||||
|
||||
contract_errors = errors.keys.index_with do |key|
|
||||
errors[key].is_a?(Hash) ? contract.errors.details[key] : contract.errors.symbols_for(key)
|
||||
end
|
||||
|
||||
expect(contract_errors).to match(expected_errors)
|
||||
if RSpec.current_example.metadata[:check_errors_i18n]
|
||||
# ensure no I18n::MissingTranslationData is raised because of missing attributes and/or errors translations
|
||||
|
||||
Reference in New Issue
Block a user