Validate if project label title does not exist at group level

parent cfedd42b
......@@ -24,13 +24,14 @@ class Label < ActiveRecord::Base
# Don't allow ',' for label titles
validates :title, presence: true, format: { with: /\A[^,]+\z/ }
validates :title, uniqueness: true, unless: :template?
validates :title, uniqueness: { scope: [:group_id, :project_id] }
before_save :nullify_priority
default_scope { order(title: :asc) }
scope :templates, -> { where(template: true) }
scope :with_title, ->(title) { where(title: title) }
def self.prioritized
where.not(priority: nil).reorder(:priority, :title)
......
......@@ -2,4 +2,18 @@ class ProjectLabel < Label
belongs_to :project
validates :project, presence: true
validate :title_must_not_exist_at_group_level
delegate :group, to: :project, allow_nil: true
private
def title_must_not_exist_at_group_level
return unless group.present?
if group.labels.with_title(self.title).exists?
errors.add(:title, :label_already_exists_at_group_level, group: group.name)
end
end
end
......@@ -5,6 +5,7 @@ en:
hello: "Hello world"
errors:
messages:
label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one."
wrong_size: "is the wrong size (should be %{file_size})"
size_too_small: "is too small (should be at least %{file_size})"
size_too_big: "is too big (should be at most %{file_size})"
......
......@@ -4,4 +4,10 @@ FactoryGirl.define do
color "#990000"
project
end
factory :group_label, class: GroupLabel do
sequence(:title) { |n| "label#{n}" }
color "#990000"
group
end
end
......@@ -13,7 +13,7 @@ describe Label, models: true do
end
describe 'validation' do
it { is_expected.to validate_uniqueness_of(:title) }
it { is_expected.to validate_uniqueness_of(:title).scoped_to([:group_id, :project_id]) }
it 'validates color code' do
is_expected.not_to allow_value('G-ITLAB').for(:color)
......
......@@ -7,5 +7,39 @@ describe ProjectLabel, models: true do
describe 'validations' do
it { is_expected.to validate_presence_of(:project) }
context 'validates if title must not exist at group level' do
let(:group) { create(:group, name: 'gitlab-org') }
let(:project) { create(:empty_project, group: group) }
before do
create(:group_label, group: group, title: 'Bug')
end
it 'returns error if title already exists at group level' do
label = described_class.new(project: project, title: 'Bug')
label.valid?
expect(label.errors[:title]).to include 'already exists at group level for gitlab-org. Please choose another one.'
end
it 'does not returns error if title does not exist at group level' do
label = described_class.new(project: project, title: 'Security')
label.valid?
expect(label.errors[:title]).to be_empty
end
it 'does not returns error if project does not belong to group' do
another_project = create(:empty_project)
label = described_class.new(project: another_project, title: 'Bug')
label.valid?
expect(label.errors[:title]).to be_empty
end
end
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