Commit f7d1ffb9 authored by Jan Provaznik's avatar Jan Provaznik

Validate project namespace's parent

parent 4c04855e
...@@ -530,17 +530,27 @@ class Namespace < ApplicationRecord ...@@ -530,17 +530,27 @@ class Namespace < ApplicationRecord
def nesting_level_allowed def nesting_level_allowed
if ancestors.count > Group::NUMBER_OF_ANCESTORS_ALLOWED if ancestors.count > Group::NUMBER_OF_ANCESTORS_ALLOWED
errors.add(:parent_id, 'has too deep level of nesting') errors.add(:parent_id, _('has too deep level of nesting'))
end end
end end
def validate_parent_type def validate_parent_type
return unless has_parent? unless has_parent?
if project?
errors.add(:parent_id, _('must be set for a project namespace'))
end
return
end
if parent.project?
errors.add(:parent_id, _('project namespace cannot be the parent of another namespace'))
end
if user? if user?
errors.add(:parent_id, 'a user namespace cannot have a parent') errors.add(:parent_id, _('cannot not be used for user namespace'))
elsif group? elsif group?
errors.add(:parent_id, 'a group cannot have a user namespace as its parent') if parent.user? errors.add(:parent_id, _('user namespace cannot be the parent of another namespace')) if parent.user?
end end
end end
......
...@@ -39445,6 +39445,9 @@ msgstr "" ...@@ -39445,6 +39445,9 @@ msgstr ""
msgid "cannot merge" msgid "cannot merge"
msgstr "" msgstr ""
msgid "cannot not be used for user namespace"
msgstr ""
msgid "ciReport|%{degradedNum} degraded" msgid "ciReport|%{degradedNum} degraded"
msgstr "" msgstr ""
...@@ -39955,6 +39958,9 @@ msgstr "" ...@@ -39955,6 +39958,9 @@ msgstr ""
msgid "has been completed." msgid "has been completed."
msgstr "" msgstr ""
msgid "has too deep level of nesting"
msgstr ""
msgid "help" msgid "help"
msgstr "" msgstr ""
...@@ -40503,6 +40509,9 @@ msgstr "" ...@@ -40503,6 +40509,9 @@ msgstr ""
msgid "must be less than the limit of %{tag_limit} tags" msgid "must be less than the limit of %{tag_limit} tags"
msgstr "" msgstr ""
msgid "must be set for a project namespace"
msgstr ""
msgid "must be unique by status and elapsed time within a policy" msgid "must be unique by status and elapsed time within a policy"
msgstr "" msgstr ""
...@@ -40664,6 +40673,9 @@ msgstr "" ...@@ -40664,6 +40673,9 @@ msgstr ""
msgid "project name" msgid "project name"
msgstr "" msgstr ""
msgid "project namespace cannot be the parent of another namespace"
msgstr ""
msgid "projects" msgid "projects"
msgstr "" msgstr ""
...@@ -40900,6 +40912,9 @@ msgstr "" ...@@ -40900,6 +40912,9 @@ msgstr ""
msgid "user avatar" msgid "user avatar"
msgstr "" msgstr ""
msgid "user namespace cannot be the parent of another namespace"
msgstr ""
msgid "user preferences" msgid "user preferences"
msgstr "" msgstr ""
......
...@@ -7,5 +7,6 @@ FactoryBot.define do ...@@ -7,5 +7,6 @@ FactoryBot.define do
path { project.path } path { project.path }
type { Namespaces::ProjectNamespace.sti_name } type { Namespaces::ProjectNamespace.sti_name }
owner { nil } owner { nil }
parent factory: :group
end end
end end
...@@ -82,7 +82,7 @@ RSpec.describe Group do ...@@ -82,7 +82,7 @@ RSpec.describe Group do
group = build(:group, parent: build(:namespace)) group = build(:group, parent: build(:namespace))
expect(group).not_to be_valid expect(group).not_to be_valid
expect(group.errors[:parent_id].first).to eq('a group cannot have a user namespace as its parent') expect(group.errors[:parent_id].first).to eq('user namespace cannot be the parent of another namespace')
end end
it 'allows a group to have another group as its parent' do it 'allows a group to have another group as its parent' do
......
...@@ -36,27 +36,34 @@ RSpec.describe Namespace do ...@@ -36,27 +36,34 @@ RSpec.describe Namespace do
it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) } it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) }
context 'validating the parent of a namespace' do context 'validating the parent of a namespace' do
context 'when the namespace has no parent' do using RSpec::Parameterized::TableSyntax
it 'allows a namespace to have no parent associated with it' do
namespace = build(:namespace) where(:parent_type, :child_type, :error) do
nil | 'User' | nil
expect(namespace).to be_valid nil | 'Group' | nil
end nil | 'Project' | 'must be set for a project namespace'
'Project' | 'User' | 'project namespace cannot be the parent of another namespace'
'Project' | 'Group' | 'project namespace cannot be the parent of another namespace'
'Project' | 'Project' | 'project namespace cannot be the parent of another namespace'
'Group' | 'User' | 'cannot not be used for user namespace'
'Group' | 'Group' | nil
'Group' | 'Project' | nil
'User' | 'User' | 'cannot not be used for user namespace'
'User' | 'Group' | 'user namespace cannot be the parent of another namespace'
'User' | 'Project' | nil
end end
context 'when the namespace has a parent' do with_them do
it 'does not allow a namespace to have a group as its parent' do it 'validates namespace parent' do
namespace = build(:namespace, parent: build(:group)) parent = build(:namespace, type: parent_type) if parent_type
namespace = build(:namespace, type: child_type, parent: parent)
expect(namespace).not_to be_valid
expect(namespace.errors[:parent_id].first).to eq('a user namespace cannot have a parent') if error
end expect(namespace).not_to be_valid
expect(namespace.errors[:parent_id].first).to eq(error)
it 'does not allow a namespace to have another namespace as its parent' do else
namespace = build(:namespace, parent: build(:namespace)) expect(namespace).to be_valid
end
expect(namespace).not_to be_valid
expect(namespace.errors[:parent_id].first).to eq('a user namespace cannot have a parent')
end end
end end
...@@ -159,7 +166,8 @@ RSpec.describe Namespace do ...@@ -159,7 +166,8 @@ RSpec.describe Namespace do
describe 'handling STI', :aggregate_failures do describe 'handling STI', :aggregate_failures do
let(:namespace_type) { nil } let(:namespace_type) { nil }
let(:namespace) { Namespace.find(create(:namespace, type: namespace_type).id) } let(:parent) { nil }
let(:namespace) { Namespace.find(create(:namespace, type: namespace_type, parent: parent).id) }
context 'creating a Group' do context 'creating a Group' do
let(:namespace_type) { 'Group' } let(:namespace_type) { 'Group' }
...@@ -173,6 +181,7 @@ RSpec.describe Namespace do ...@@ -173,6 +181,7 @@ RSpec.describe Namespace do
context 'creating a ProjectNamespace' do context 'creating a ProjectNamespace' do
let(:namespace_type) { 'Project' } let(:namespace_type) { 'Project' }
let(:parent) { create(:group) }
it 'is valid' do it 'is valid' do
expect(Namespace.find(namespace.id)).to be_a(Namespaces::ProjectNamespace) expect(Namespace.find(namespace.id)).to be_a(Namespaces::ProjectNamespace)
......
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