Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-04-20 17:36:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-20 17:36:54 +0300
commitf61bb2a16a514b71bf33aabbbb999d6732016a24 (patch)
tree9548caa89e60b4f40b99bbd1dac030420b812aa8 /spec/models/group_spec.rb
parent35fc54e5d261f8898e390aea7c2f5ec5fdf0539d (diff)
Add latest changes from gitlab-org/gitlab@13-11-stable-eev13.11.0-rc42
Diffstat (limited to 'spec/models/group_spec.rb')
-rw-r--r--spec/models/group_spec.rb367
1 files changed, 312 insertions, 55 deletions
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 24d09d1c035..2f82d8a0bbe 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Group do
+ include ReloadHelpers
+
let!(:group) { create(:group) }
describe 'associations' do
@@ -281,7 +283,7 @@ RSpec.describe Group do
end
describe '#two_factor_authentication_allowed' do
- let_it_be(:group) { create(:group) }
+ let_it_be_with_reload(:group) { create(:group) }
context 'for a parent group' do
it 'is valid' do
@@ -311,6 +313,120 @@ RSpec.describe Group do
end
end
+ context 'traversal_ids on create' do
+ context 'default traversal_ids' do
+ let(:group) { build(:group) }
+
+ before do
+ group.save!
+ group.reload
+ end
+
+ it { expect(group.traversal_ids).to eq [group.id] }
+ end
+
+ context 'has a parent' do
+ let(:parent) { create(:group) }
+ let(:group) { build(:group, parent: parent) }
+
+ before do
+ group.save!
+ reload_models(parent, group)
+ end
+
+ it { expect(parent.traversal_ids).to eq [parent.id] }
+ it { expect(group.traversal_ids).to eq [parent.id, group.id] }
+ end
+
+ context 'has a parent update before save' do
+ let(:parent) { create(:group) }
+ let(:group) { build(:group, parent: parent) }
+ let!(:new_grandparent) { create(:group) }
+
+ before do
+ parent.update!(parent: new_grandparent)
+ group.save!
+ reload_models(parent, group)
+ end
+
+ it 'avoid traversal_ids race condition' do
+ expect(parent.traversal_ids).to eq [new_grandparent.id, parent.id]
+ expect(group.traversal_ids).to eq [new_grandparent.id, parent.id, group.id]
+ end
+ end
+ end
+
+ context 'traversal_ids on update' do
+ context 'parent is updated' do
+ let(:new_parent) { create(:group) }
+
+ subject {group.update!(parent: new_parent, name: 'new name') }
+
+ it_behaves_like 'update on column', :traversal_ids
+ end
+
+ context 'parent is not updated' do
+ subject { group.update!(name: 'new name') }
+
+ it_behaves_like 'no update on column', :traversal_ids
+ end
+ end
+
+ context 'traversal_ids on ancestral update' do
+ context 'update multiple ancestors before save' do
+ let(:parent) { create(:group) }
+ let(:group) { create(:group, parent: parent) }
+ let!(:new_grandparent) { create(:group) }
+ let!(:new_parent) { create(:group) }
+
+ before do
+ group.parent = new_parent
+ new_parent.update!(parent: new_grandparent)
+
+ group.save!
+ reload_models(parent, group, new_grandparent, new_parent)
+ end
+
+ it 'avoids traversal_ids race condition' do
+ expect(parent.traversal_ids).to eq [parent.id]
+ expect(group.traversal_ids).to eq [new_grandparent.id, new_parent.id, group.id]
+ expect(new_grandparent.traversal_ids).to eq [new_grandparent.id]
+ expect(new_parent.traversal_ids).to eq [new_grandparent.id, new_parent.id]
+ end
+ end
+
+ context 'assigning a new parent' do
+ let!(:old_parent) { create(:group) }
+ let!(:new_parent) { create(:group) }
+ let!(:group) { create(:group, parent: old_parent) }
+
+ before do
+ group.update(parent: new_parent)
+ reload_models(old_parent, new_parent, group)
+ end
+
+ it 'updates traversal_ids' do
+ expect(group.traversal_ids).to eq [new_parent.id, group.id]
+ end
+ end
+
+ context 'assigning a new grandparent' do
+ let!(:old_grandparent) { create(:group) }
+ let!(:new_grandparent) { create(:group) }
+ let!(:parent_group) { create(:group, parent: old_grandparent) }
+ let!(:group) { create(:group, parent: parent_group) }
+
+ before do
+ parent_group.update(parent: new_grandparent)
+ end
+
+ it 'updates traversal_ids for all descendants' do
+ expect(parent_group.reload.traversal_ids).to eq [new_grandparent.id, parent_group.id]
+ expect(group.reload.traversal_ids).to eq [new_grandparent.id, parent_group.id, group.id]
+ end
+ end
+ end
+
describe '.without_integration' do
let(:another_group) { create(:group) }
let(:instance_integration) { build(:jira_service, :instance) }
@@ -565,39 +681,178 @@ RSpec.describe Group do
end
end
- describe '#last_blocked_owner?' do
- let(:blocked_user) { create(:user, :blocked) }
+ describe '#member_last_blocked_owner?' do
+ let_it_be(:blocked_user) { create(:user, :blocked) }
+
+ let(:member) { blocked_user.group_members.last }
before do
group.add_user(blocked_user, GroupMember::OWNER)
end
- it { expect(group.last_blocked_owner?(blocked_user)).to be_truthy }
+ context 'when last_blocked_owner is set' do
+ before do
+ expect(group).not_to receive(:members_with_parents)
+ end
+
+ it 'returns true' do
+ member.last_blocked_owner = true
+
+ expect(group.member_last_blocked_owner?(member)).to be(true)
+ end
+
+ it 'returns false' do
+ member.last_blocked_owner = false
+
+ expect(group.member_last_blocked_owner?(member)).to be(false)
+ end
+ end
+
+ context 'when last_blocked_owner is not set' do
+ it { expect(group.member_last_blocked_owner?(member)).to be(true) }
+
+ context 'with another active owner' do
+ before do
+ group.add_user(create(:user), GroupMember::OWNER)
+ end
+
+ it { expect(group.member_last_blocked_owner?(member)).to be(false) }
+ end
+
+ context 'with 2 blocked owners' do
+ before do
+ group.add_user(create(:user, :blocked), GroupMember::OWNER)
+ end
+
+ it { expect(group.member_last_blocked_owner?(member)).to be(false) }
+ end
+
+ context 'with owners from a parent' do
+ before do
+ parent_group = create(:group)
+ create(:group_member, :owner, group: parent_group)
+ group.update(parent: parent_group)
+ end
+
+ it { expect(group.member_last_blocked_owner?(member)).to be(false) }
+ end
+ end
+ end
+
+ context 'when analyzing blocked owners' do
+ let_it_be(:blocked_user) { create(:user, :blocked) }
+
+ describe '#single_blocked_owner?' do
+ context 'when there is only one blocked owner' do
+ before do
+ group.add_user(blocked_user, GroupMember::OWNER)
+ end
+
+ it 'returns true' do
+ expect(group.single_blocked_owner?).to eq(true)
+ end
+ end
+
+ context 'when there are multiple blocked owners' do
+ let_it_be(:blocked_user_2) { create(:user, :blocked) }
+
+ before do
+ group.add_user(blocked_user, GroupMember::OWNER)
+ group.add_user(blocked_user_2, GroupMember::OWNER)
+ end
+
+ it 'returns true' do
+ expect(group.single_blocked_owner?).to eq(false)
+ end
+ end
+
+ context 'when there are no blocked owners' do
+ it 'returns false' do
+ expect(group.single_blocked_owner?).to eq(false)
+ end
+ end
+ end
+
+ describe '#blocked_owners' do
+ let_it_be(:user) { create(:user) }
- context 'with another active owner' do
before do
- group.add_user(create(:user), GroupMember::OWNER)
+ group.add_user(blocked_user, GroupMember::OWNER)
+ group.add_user(user, GroupMember::OWNER)
end
- it { expect(group.last_blocked_owner?(blocked_user)).to be_falsy }
+ it 'has only blocked owners' do
+ expect(group.blocked_owners.map(&:user)).to match([blocked_user])
+ end
end
+ end
+
+ describe '#single_owner?' do
+ let_it_be(:user) { create(:user) }
- context 'with 2 blocked owners' do
+ context 'when there is only one owner' do
before do
- group.add_user(create(:user, :blocked), GroupMember::OWNER)
+ group.add_user(user, GroupMember::OWNER)
end
- it { expect(group.last_blocked_owner?(blocked_user)).to be_falsy }
+ it 'returns true' do
+ expect(group.single_owner?).to eq(true)
+ end
end
- context 'with owners from a parent' do
+ context 'when there are multiple owners' do
+ let_it_be(:user_2) { create(:user) }
+
before do
- parent_group = create(:group)
- create(:group_member, :owner, group: parent_group)
- group.update(parent: parent_group)
+ group.add_user(user, GroupMember::OWNER)
+ group.add_user(user_2, GroupMember::OWNER)
end
- it { expect(group.last_blocked_owner?(blocked_user)).to be_falsy }
+ it 'returns true' do
+ expect(group.single_owner?).to eq(false)
+ end
+ end
+
+ context 'when there are no owners' do
+ it 'returns false' do
+ expect(group.single_owner?).to eq(false)
+ end
+ end
+ end
+
+ describe '#member_last_owner?' do
+ let_it_be(:user) { create(:user) }
+
+ let(:member) { group.members.last }
+
+ before do
+ group.add_user(user, GroupMember::OWNER)
+ end
+
+ context 'when last_owner is set' do
+ before do
+ expect(group).not_to receive(:last_owner?)
+ end
+
+ it 'returns true' do
+ member.last_owner = true
+
+ expect(group.member_last_owner?(member)).to be(true)
+ end
+
+ it 'returns false' do
+ member.last_owner = false
+
+ expect(group.member_last_owner?(member)).to be(false)
+ end
+ end
+
+ context 'when last_owner is not set' do
+ it 'returns true' do
+ expect(group).to receive(:last_owner?).and_call_original
+
+ expect(group.member_last_owner?(member)).to be(true)
+ end
end
end
@@ -1500,30 +1755,6 @@ RSpec.describe Group do
perfectly_matched_variable])
end
end
-
- context 'when :scoped_group_variables feature flag is disabled' do
- before do
- stub_feature_flags(scoped_group_variables: false)
- end
-
- context 'when environment scope is exactly matched' do
- let(:environment_scope) { 'review/name' }
-
- it { is_expected.to contain_exactly(ci_variable) }
- end
-
- context 'when environment scope is partially matched' do
- let(:environment_scope) { 'review/*' }
-
- it { is_expected.to contain_exactly(ci_variable) }
- end
-
- context 'when environment scope does not match' do
- let(:environment_scope) { 'review/*/special' }
-
- it { is_expected.to contain_exactly(ci_variable) }
- end
- end
end
context 'when group has children' do
@@ -1838,24 +2069,28 @@ RSpec.describe Group do
end
end
- def subject_and_reload(*models)
- subject
- models.map(&:reload)
- end
-
describe '#update_shared_runners_setting!' do
context 'enabled' do
subject { group.update_shared_runners_setting!('enabled') }
context 'group that its ancestors have shared runners disabled' do
- let_it_be(:parent) { create(:group, :shared_runners_disabled) }
- let_it_be(:group) { create(:group, :shared_runners_disabled, parent: parent) }
- let_it_be(:project) { create(:project, shared_runners_enabled: false, group: group) }
+ let_it_be(:parent, reload: true) { create(:group, :shared_runners_disabled) }
+ let_it_be(:group, reload: true) { create(:group, :shared_runners_disabled, parent: parent) }
+ let_it_be(:project, reload: true) { create(:project, shared_runners_enabled: false, group: group) }
- it 'raises error and does not enable shared Runners' do
- expect { subject_and_reload(parent, group, project) }
+ it 'raises exception' do
+ expect { subject }
.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Shared runners enabled cannot be enabled because parent group has shared Runners disabled')
- .and not_change { parent.shared_runners_enabled }
+ end
+
+ it 'does not enable shared runners' do
+ expect do
+ subject rescue nil
+
+ parent.reload
+ group.reload
+ project.reload
+ end.to not_change { parent.shared_runners_enabled }
.and not_change { group.shared_runners_enabled }
.and not_change { project.shared_runners_enabled }
end
@@ -1941,13 +2176,21 @@ RSpec.describe Group do
end
context 'when parent does not allow' do
- let_it_be(:parent) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false ) }
- let_it_be(:group) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false, parent: parent) }
+ let_it_be(:parent, reload: true) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false ) }
+ let_it_be(:group, reload: true) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false, parent: parent) }
- it 'raises error and does not allow descendants to override' do
- expect { subject_and_reload(parent, group) }
+ it 'raises exception' do
+ expect { subject }
.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Allow descendants override disabled shared runners cannot be enabled because parent group does not allow it')
- .and not_change { parent.allow_descendants_override_disabled_shared_runners }
+ end
+
+ it 'does not allow descendants to override' do
+ expect do
+ subject rescue nil
+
+ parent.reload
+ group.reload
+ end.to not_change { parent.allow_descendants_override_disabled_shared_runners }
.and not_change { parent.shared_runners_enabled }
.and not_change { group.allow_descendants_override_disabled_shared_runners }
.and not_change { group.shared_runners_enabled }
@@ -2104,4 +2347,18 @@ RSpec.describe Group do
it_behaves_like 'model with Debian distributions'
end
+
+ describe '.ids_with_disabled_email' do
+ let!(:parent_1) { create(:group, emails_disabled: true) }
+ let!(:child_1) { create(:group, parent: parent_1) }
+
+ let!(:parent_2) { create(:group, emails_disabled: false) }
+ let!(:child_2) { create(:group, parent: parent_2) }
+
+ let!(:other_group) { create(:group, emails_disabled: false) }
+
+ subject(:group_ids_where_email_is_disabled) { described_class.ids_with_disabled_email([child_1, child_2, other_group]) }
+
+ it { is_expected.to eq(Set.new([child_1.id])) }
+ end
end