Commit 85177b67 authored by Felipe Artur's avatar Felipe Artur

Prevent projects with same slug from having same project key

Adds service desk setting project_key uniqueness validation.

Changelog: changed
parent 4b88d6a1
...@@ -6,9 +6,12 @@ class ServiceDeskSetting < ApplicationRecord ...@@ -6,9 +6,12 @@ class ServiceDeskSetting < ApplicationRecord
belongs_to :project belongs_to :project
validates :project_id, presence: true validates :project_id, presence: true
validate :valid_issue_template validate :valid_issue_template
validate :valid_project_key
validates :outgoing_name, length: { maximum: 255 }, allow_blank: true 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/ } 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 def issue_template_content
strong_memoize(:issue_template_content) do strong_memoize(:issue_template_content) do
next unless issue_template_key.present? next unless issue_template_key.present?
...@@ -27,4 +30,23 @@ class ServiceDeskSetting < ApplicationRecord ...@@ -27,4 +30,23 @@ class ServiceDeskSetting < ApplicationRecord
errors.add(:issue_template_key, 'is empty or does not exist') errors.add(:issue_template_key, 'is empty or does not exist')
end end
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 end
...@@ -31,6 +31,37 @@ RSpec.describe ServiceDeskSetting do ...@@ -31,6 +31,37 @@ RSpec.describe ServiceDeskSetting do
end end
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 describe 'associations' do
it { is_expected.to belong_to(:project) } it { is_expected.to belong_to(:project) }
end 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