Commit 5aa6b6bd authored by Imre Farkas's avatar Imre Farkas

Merge branch '339933-determine-type-column-values-for-namespace-subclasses' into 'master'

Use shortened `type` values for the `namespace` table

See merge request gitlab-org/gitlab!69794
parents d3d80a33 a359fd91
......@@ -18,6 +18,10 @@ class Group < Namespace
include EachBatch
include BulkMemberAccessLoad
def self.sti_name
'Group'
end
has_many :all_group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent
has_many :group_members, -> { where(requested_at: nil).where.not(members: { access_level: Gitlab::Access::MINIMAL_ACCESS }) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent
alias_method :members, :group_members
......
......@@ -18,6 +18,11 @@ class Namespace < ApplicationRecord
ignore_column :delayed_project_removal, remove_with: '14.1', remove_after: '2021-05-22'
# Tells ActiveRecord not to store the full class name, in order to space some space
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69794
self.store_full_sti_class = false
self.store_full_class_name = false
# Prevent users from creating unreasonably deep level of nesting.
# The number 20 was taken based on maximum nesting level of
# Android repo (15) + some extra backup.
......@@ -131,6 +136,21 @@ class Namespace < ApplicationRecord
attr_writer :root_ancestor, :emails_disabled_memoized
class << self
def sti_class_for(type_name)
case type_name
when 'Group'
Group
when 'Project'
Namespaces::ProjectNamespace
when 'User'
# TODO: We create a normal Namespace until
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68894 is ready
Namespace
else
Namespace
end
end
def by_path(path)
find_by('lower(path) = :value', value: path.downcase)
end
......@@ -227,15 +247,23 @@ class Namespace < ApplicationRecord
end
def kind
type == 'Group' ? 'group' : 'user'
end
return 'group' if group?
return 'project' if project?
def user?
kind == 'user'
'user' # defaults to user
end
def group?
type == 'Group'
type == Group.sti_name
end
def project?
type == Namespaces::ProjectNamespace.sti_name
end
def user?
# That last bit ensures we're considered a user namespace as a default
type.nil? || type == Namespaces::UserNamespace.sti_name || !(group? || project?)
end
def find_fork_of(project)
......
......@@ -3,5 +3,9 @@
module Namespaces
class ProjectNamespace < Namespace
has_one :project, foreign_key: :project_namespace_id, inverse_of: :project_namespace
def self.sti_name
'Project'
end
end
end
# frozen_string_literal: true
# TODO: currently not created/mapped in the database, will be done in another issue
# https://gitlab.com/gitlab-org/gitlab/-/issues/337102
module Namespaces
class UserNamespace < Namespace
def self.sti_name
'User'
end
end
end
......@@ -146,21 +146,20 @@ RSpec.describe BillingPlansHelper do
end
context 'when the namespace belongs to a user' do
let(:group) { build(:group, type: 'user') }
let(:namespace) { build(:namespace) }
context 'when the namespace is free plan' do
it 'returns attributes with free_personal_namespace true' do
expect(helper.subscription_plan_data_attributes(group, plan))
expect(helper.subscription_plan_data_attributes(namespace, plan))
.to include(free_personal_namespace: 'true')
end
end
context 'when the namespace is paid plan' do
let(:group) { build(:group, type: 'user') }
let!(:gitlab_subscription) { build(:gitlab_subscription, :ultimate, namespace: group) }
let!(:gitlab_subscription) { build(:gitlab_subscription, :ultimate, namespace: namespace) }
it 'returns attributes with free_personal_namespace false' do
expect(helper.subscription_plan_data_attributes(group, plan))
expect(helper.subscription_plan_data_attributes(namespace, plan))
.to include(free_personal_namespace: 'false')
end
end
......
......@@ -157,6 +157,63 @@ RSpec.describe Namespace do
end
end
describe 'handling STI', :aggregate_failures do
let(:namespace_type) { nil }
let(:namespace) { Namespace.find(create(:namespace, type: namespace_type).id) }
context 'creating a Group' do
let(:namespace_type) { 'Group' }
it 'is valid' do
expect(namespace).to be_a(Group)
expect(namespace.kind).to eq('group')
expect(namespace.group?).to be_truthy
end
end
context 'creating a ProjectNamespace' do
let(:namespace_type) { 'Project' }
it 'is valid' do
expect(Namespace.find(namespace.id)).to be_a(Namespaces::ProjectNamespace)
expect(namespace.kind).to eq('project')
expect(namespace.project?).to be_truthy
end
end
context 'creating a UserNamespace' do
let(:namespace_type) { 'User' }
it 'is valid' do
# TODO: We create a normal Namespace until
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68894 is ready
expect(Namespace.find(namespace.id)).to be_a(Namespace)
expect(namespace.kind).to eq('user')
expect(namespace.user?).to be_truthy
end
end
context 'creating a default Namespace' do
let(:namespace_type) { nil }
it 'is valid' do
expect(Namespace.find(namespace.id)).to be_a(Namespace)
expect(namespace.kind).to eq('user')
expect(namespace.user?).to be_truthy
end
end
context 'creating an unknown Namespace type' do
let(:namespace_type) { 'One' }
it 'defaults to a Namespace' do
expect(Namespace.find(namespace.id)).to be_a(Namespace)
expect(namespace.kind).to eq('user')
expect(namespace.user?).to be_truthy
end
end
end
describe 'scopes', :aggregate_failures do
let_it_be(:namespace1) { create(:group, name: 'Namespace 1', path: 'namespace-1') }
let_it_be(:namespace2) { create(:group, name: 'Namespace 2', path: 'namespace-2') }
......
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