Commit 2f8ee6f8 authored by James Lopez's avatar James Lopez

Merge branch 'project_bot_licensing' into 'master'

Exclude project bot from .com license seat

See merge request gitlab-org/gitlab!31390
parents 82097be5 00b974ad
...@@ -24,6 +24,7 @@ module HasUserType ...@@ -24,6 +24,7 @@ module HasUserType
scope :bots_without_project_bot, -> { where(user_type: BOT_USER_TYPES - ['project_bot']) } scope :bots_without_project_bot, -> { where(user_type: BOT_USER_TYPES - ['project_bot']) }
scope :non_internal, -> { humans.or(where(user_type: NON_INTERNAL_USER_TYPES)) } scope :non_internal, -> { humans.or(where(user_type: NON_INTERNAL_USER_TYPES)) }
scope :without_ghosts, -> { humans.or(where.not(user_type: :ghost)) } scope :without_ghosts, -> { humans.or(where.not(user_type: :ghost)) }
scope :without_project_bot, -> { humans.or(where.not(user_type: :project_bot)) }
enum user_type: USER_TYPES enum user_type: USER_TYPES
......
...@@ -17,6 +17,11 @@ class ProjectMember < Member ...@@ -17,6 +17,11 @@ class ProjectMember < Member
.where('projects.namespace_id in (?)', groups.select(:id)) .where('projects.namespace_id in (?)', groups.select(:id))
end end
scope :without_project_bots, -> do
left_join_users
.merge(User.without_project_bot)
end
class << self class << self
# Add users to projects with passed access option # Add users to projects with passed access option
# #
......
# frozen_string_literal: true
class AddIndexNonRequestedProjectMembersOnSourceIdSourceType < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index(:members, [:source_id, :source_type], where: "requested_at IS NULL and type = 'ProjectMember'", name: 'index_non_requested_project_members_on_source_id_and_type')
end
def down
remove_concurrent_index_by_name(:members, 'index_non_requested_project_members_on_source_id_and_type')
end
end
...@@ -10101,6 +10101,8 @@ CREATE INDEX index_namespaces_on_trial_ends_on ON public.namespaces USING btree ...@@ -10101,6 +10101,8 @@ CREATE INDEX index_namespaces_on_trial_ends_on ON public.namespaces USING btree
CREATE INDEX index_namespaces_on_type_partial ON public.namespaces USING btree (type) WHERE (type IS NOT NULL); CREATE INDEX index_namespaces_on_type_partial ON public.namespaces USING btree (type) WHERE (type IS NOT NULL);
CREATE INDEX index_non_requested_project_members_on_source_id_and_type ON public.members USING btree (source_id, source_type) WHERE ((requested_at IS NULL) AND ((type)::text = 'ProjectMember'::text));
CREATE UNIQUE INDEX index_note_diff_files_on_diff_note_id ON public.note_diff_files USING btree (diff_note_id); CREATE UNIQUE INDEX index_note_diff_files_on_diff_note_id ON public.note_diff_files USING btree (diff_note_id);
CREATE INDEX index_notes_on_author_id_and_created_at_and_id ON public.notes USING btree (author_id, created_at, id); CREATE INDEX index_notes_on_author_id_and_created_at_and_id ON public.notes USING btree (author_id, created_at, id);
...@@ -13864,5 +13866,6 @@ COPY "schema_migrations" (version) FROM STDIN; ...@@ -13864,5 +13866,6 @@ COPY "schema_migrations" (version) FROM STDIN;
20200514000009 20200514000009
20200514000132 20200514000132
20200514000340 20200514000340
20200515155620
\. \.
...@@ -389,7 +389,7 @@ module EE ...@@ -389,7 +389,7 @@ module EE
# Members belonging directly to Projects within Group or Projects within subgroups # Members belonging directly to Projects within Group or Projects within subgroups
def billed_project_members def billed_project_members
::ProjectMember.active_without_invites_and_requests.where( ::ProjectMember.active_without_invites_and_requests.without_project_bots.where(
source_id: ::Project.joins(:group).where(namespace: self_and_descendants) source_id: ::Project.joins(:group).where(namespace: self_and_descendants)
) )
end end
......
...@@ -875,6 +875,14 @@ describe Namespace do ...@@ -875,6 +875,14 @@ describe Namespace do
end end
end end
shared_context 'project bot users' do
let(:project_bot) { create(:user, :project_bot) }
before do
project.add_maintainer(project_bot)
end
end
describe '#billed_user_ids' do describe '#billed_user_ids' do
context 'with a user namespace' do context 'with a user namespace' do
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -919,6 +927,12 @@ describe Namespace do ...@@ -919,6 +927,12 @@ describe Namespace do
expect(group.billed_user_ids).to match_array([project_developer.id, developer.id]) expect(group.billed_user_ids).to match_array([project_developer.id, developer.id])
end end
context 'with project bot users' do
include_context 'project bot users'
it { expect(group.billed_user_ids).not_to include(project_bot.id) }
end
context 'when group is invited to the project' do context 'when group is invited to the project' do
let(:invited_group) { create(:group) } let(:invited_group) { create(:group) }
let(:invited_group_developer) { create(:user) } let(:invited_group_developer) { create(:user) }
...@@ -1033,6 +1047,12 @@ describe Namespace do ...@@ -1033,6 +1047,12 @@ describe Namespace do
expect(group.billed_user_ids).to match_array([guest.id, developer.id, project_guest.id, project_developer.id]) expect(group.billed_user_ids).to match_array([guest.id, developer.id, project_guest.id, project_developer.id])
end end
context 'with project bot users' do
include_context 'project bot users'
it { expect(group.billed_user_ids).not_to include(project_bot.id) }
end
context 'when group is invited to the project' do context 'when group is invited to the project' do
let(:invited_group) { create(:group) } let(:invited_group) { create(:group) }
let(:invited_group_developer) { create(:user) } let(:invited_group_developer) { create(:user) }
...@@ -1124,6 +1144,12 @@ describe Namespace do ...@@ -1124,6 +1144,12 @@ describe Namespace do
expect(group.billable_members_count).to eq(2) expect(group.billable_members_count).to eq(2)
end end
context 'with project bot users' do
include_context 'project bot users'
it { expect(group.billable_members_count).to eq(2) }
end
context 'when group is invited to the project' do context 'when group is invited to the project' do
let(:invited_group) { create(:group) } let(:invited_group) { create(:group) }
...@@ -1181,6 +1207,12 @@ describe Namespace do ...@@ -1181,6 +1207,12 @@ describe Namespace do
expect(group.billable_members_count).to eq(4) expect(group.billable_members_count).to eq(4)
end end
context 'with project bot users' do
include_context 'project bot users'
it { expect(group.billable_members_count).to eq(4) }
end
context 'when group is invited to the project' do context 'when group is invited to the project' do
let(:invited_group) { create(:group) } let(:invited_group) { create(:group) }
......
...@@ -49,6 +49,12 @@ describe User do ...@@ -49,6 +49,12 @@ describe User do
end end
end end
describe '.without_project_bot' do
it 'includes everyone except project_bot' do
expect(described_class.without_project_bot).to match_array(everyone - [project_bot])
end
end
describe '#bot?' do describe '#bot?' do
it 'is true for all bot user types and false for others' do it 'is true for all bot user types and false for others' do
expect(bots).to all(be_bot) expect(bots).to all(be_bot)
......
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