Commit 14e71137 authored by Mark Chao's avatar Mark Chao

Merge branch 'issue_300964-add_model_validation' into 'master'

Prevent projects with same slug from having same service desk project key

See merge request gitlab-org/gitlab!62240
parents 22c2ff1a 85177b67
......@@ -6,9 +6,12 @@ class ServiceDeskSetting < ApplicationRecord
belongs_to :project
validates :project_id, presence: true
validate :valid_issue_template
validate :valid_project_key
validates :outgoing_name, length: { maximum: 255 }, allow_blank: true
validates :project_key, length: { maximum: 255 }, allow_blank: true, format: { with: /\A[a-z0-9_]+\z/ }
scope :with_project_key, ->(key) { where(project_key: key) }
def issue_template_content
strong_memoize(:issue_template_content) do
next unless issue_template_key.present?
......@@ -27,4 +30,23 @@ class ServiceDeskSetting < ApplicationRecord
errors.add(:issue_template_key, 'is empty or does not exist')
end
end
def valid_project_key
if projects_with_same_slug_and_key_exists?
errors.add(:project_key, 'already in use for another service desk address.')
end
end
private
def projects_with_same_slug_and_key_exists?
return false unless project_key
settings = self.class.with_project_key(project_key).preload(:project)
project_slug = self.project.full_path_slug
settings.any? do |setting|
setting.project.full_path_slug == project_slug
end
end
end
......@@ -31,6 +31,37 @@ RSpec.describe ServiceDeskSetting do
end
end
describe '.valid_project_key' do
# Creates two projects with same full path slug
# group1/test/one and group1/test-one will both have 'group-test-one' slug
let_it_be(:group) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: group, name: 'test') }
let_it_be(:project1) { create(:project, name: 'test-one', group: group) }
let_it_be(:project2) { create(:project, name: 'one', group: subgroup) }
let_it_be(:project_key) { 'key' }
before_all do
create(:service_desk_setting, project: project1, project_key: project_key)
end
context 'when project_key is unique for every project slug' do
it 'does not add error' do
settings = build(:service_desk_setting, project: project2, project_key: 'otherkey')
expect(settings).to be_valid
end
end
context 'when project with same slug and settings project_key exists' do
it 'adds error' do
settings = build(:service_desk_setting, project: project2, project_key: project_key)
expect(settings).to be_invalid
expect(settings.errors[:project_key].first).to eq('already in use for another service desk address.')
end
end
end
describe 'associations' do
it { is_expected.to belong_to(:project) }
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment