Commit f7d1ffb9 authored by Jan Provaznik's avatar Jan Provaznik

Validate project namespace's parent

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