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:
Diffstat (limited to 'spec/models/project_spec.rb')
-rw-r--r--spec/models/project_spec.rb113
1 files changed, 76 insertions, 37 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5d622b8eccd..aedfc7fca53 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -17,12 +17,14 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
it_behaves_like 'ensures runners_token is prefixed', :project
describe 'associations' do
+ it { is_expected.to belong_to(:organization) }
it { is_expected.to belong_to(:group) }
it { is_expected.to belong_to(:namespace) }
it { is_expected.to belong_to(:project_namespace).class_name('Namespaces::ProjectNamespace').with_foreign_key('project_namespace_id').inverse_of(:project) }
it { is_expected.to belong_to(:creator).class_name('User') }
it { is_expected.to belong_to(:pool_repository) }
it { is_expected.to have_many(:users) }
+ it { is_expected.to have_many(:maintainers).through(:project_members).source(:user).conditions(members: { access_level: Gitlab::Access::MAINTAINER }) }
it { is_expected.to have_many(:events) }
it { is_expected.to have_many(:merge_requests) }
it { is_expected.to have_many(:merge_request_metrics).class_name('MergeRequest::Metrics') }
@@ -139,11 +141,9 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
it { is_expected.to have_many(:sourced_pipelines) }
it { is_expected.to have_many(:source_pipelines) }
it { is_expected.to have_many(:prometheus_alert_events) }
- it { is_expected.to have_many(:self_managed_prometheus_alert_events) }
it { is_expected.to have_many(:alert_management_alerts) }
it { is_expected.to have_many(:alert_management_http_integrations) }
it { is_expected.to have_many(:jira_imports) }
- it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:project) }
it { is_expected.to have_many(:repository_storage_moves) }
it { is_expected.to have_many(:reviews).inverse_of(:project) }
it { is_expected.to have_many(:packages).class_name('Packages::Package') }
@@ -152,6 +152,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
it { is_expected.to have_many(:debian_distributions).class_name('Packages::Debian::ProjectDistribution').dependent(:destroy) }
it { is_expected.to have_many(:npm_metadata_caches).class_name('Packages::Npm::MetadataCache') }
it { is_expected.to have_one(:packages_cleanup_policy).class_name('Packages::Cleanup::Policy').inverse_of(:project) }
+ it { is_expected.to have_many(:package_protection_rules).class_name('Packages::Protection::Rule').inverse_of(:project) }
it { is_expected.to have_many(:pipeline_artifacts).dependent(:restrict_with_error) }
it { is_expected.to have_many(:terraform_states).class_name('Terraform::State').inverse_of(:project) }
it { is_expected.to have_many(:timelogs) }
@@ -224,6 +225,23 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
expect(project.lfs_objects.to_a).to eql([lfs_object])
end
+ describe 'maintainers association' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:maintainer1) { create(:user) }
+ let_it_be(:maintainer2) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+
+ before do
+ project.add_maintainer(maintainer1)
+ project.add_maintainer(maintainer2)
+ project.add_reporter(reporter)
+ end
+
+ it 'returns only maintainers' do
+ expect(project.maintainers).to match_array([maintainer1, maintainer2])
+ end
+ end
+
context 'after initialized' do
it "has a project_feature" do
expect(described_class.new.project_feature).to be_present
@@ -1140,6 +1158,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
merge_pipelines_enabled
merge_trains_enabled
auto_rollback_enabled
+ merge_trains_skip_train_allowed
)
end
end
@@ -2380,7 +2399,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
- describe '#service_desk_address' do
+ describe '#service_desk_address', feature_category: :service_desk do
let_it_be(:project, reload: true) { create(:project, service_desk_enabled: true) }
subject { project.service_desk_address }
@@ -2424,7 +2443,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
context 'when project_key is set' do
- it 'returns custom address including the project_key' do
+ it 'returns Service Desk alias address including the project_key' do
create(:service_desk_setting, project: project, project_key: 'key1')
expect(subject).to eq("foo+#{project.full_path_slug}-key1@bar.com")
@@ -2432,11 +2451,35 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
context 'when project_key is not set' do
- it 'returns custom address including the project full path' do
+ it 'returns Service Desk alias address including the project full path' do
expect(subject).to eq("foo+#{project.full_path_slug}-#{project.project_id}-issue-@bar.com")
end
end
end
+
+ context 'when custom email is enabled' do
+ let(:custom_email) { 'support@example.com' }
+
+ before do
+ setting = ServiceDeskSetting.new(project: project, custom_email: custom_email, custom_email_enabled: true)
+ allow(project).to receive(:service_desk_setting).and_return(setting)
+ end
+
+ it 'returns custom email address' do
+ expect(subject).to eq(custom_email)
+ end
+
+ context 'when feature flag service_desk_custom_email is disabled' do
+ before do
+ stub_feature_flags(service_desk_custom_email: false)
+ end
+
+ it 'returns custom email address' do
+ # Don't check for a specific value. Just make sure it's not the custom email
+ expect(subject).not_to eq(custom_email)
+ end
+ end
+ end
end
describe '.with_service_desk_key' do
@@ -3882,16 +3925,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
- describe '#mark_primary_write_location' do
- let(:project) { create(:project) }
-
- it 'marks the location with project ID' do
- expect(ApplicationRecord.sticking).to receive(:mark_primary_write_location).with(:project, project.id)
-
- project.mark_primary_write_location
- end
- end
-
describe '#mark_stuck_remote_mirrors_as_failed!' do
it 'fails stuck remote mirrors' do
project = create(:project, :repository, :remote_mirror)
@@ -5086,7 +5119,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
subject { described_class.wrap_with_cte(projects) }
it 'wrapped query matches original' do
- expect(subject.to_sql).to match(/^WITH "projects_cte" AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported}/)
+ expect(subject.to_sql).to match(/^WITH "projects_cte" AS MATERIALIZED/)
expect(subject).to match_array(projects)
end
end
@@ -6986,8 +7019,11 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
let_it_be_with_reload(:project) { create(:project, :empty_repo) }
let_it_be(:shard_to) { create(:shard, name: 'test_second_storage') }
- let!(:pool1) { create(:pool_repository, source_project: project) }
- let!(:pool2) { create(:pool_repository, shard: shard_to, source_project: project) }
+ let(:disk_path1) { '@pool/aa/bb' }
+ let(:disk_path2) { disk_path1 }
+
+ let!(:pool1) { create(:pool_repository, disk_path: disk_path1, source_project: project) }
+ let!(:pool2) { create(:pool_repository, disk_path: disk_path2, shard: shard_to, source_project: project) }
let(:project_pool) { pool1 }
let(:repository_storage) { shard_to.name }
@@ -7045,6 +7081,14 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
expect { swap_pool_repository! }.to raise_error(ActiveRecord::RecordNotFound)
end
end
+
+ context 'when pool repository has a different disk path' do
+ let(:disk_path2) { '@pool/different' }
+
+ it 'raises record not found error' do
+ expect { swap_pool_repository! }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
end
describe '#leave_pool_repository' do
@@ -7412,17 +7456,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
- describe '#pages_lookup_path' do
- let(:pages_domain) { build(:pages_domain) }
- let(:project) { build(:project) }
-
- it 'returns instance of Pages::LookupPath' do
- expect(Pages::LookupPath).to receive(:new).with(project, domain: pages_domain, trim_prefix: 'mygroup').and_call_original
-
- expect(project.pages_lookup_path(domain: pages_domain, trim_prefix: 'mygroup')).to be_a(Pages::LookupPath)
- end
- end
-
describe '.with_pages_deployed' do
it 'returns only projects that have pages deployed' do
_project_without_pages = create(:project)
@@ -8088,14 +8121,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
it { is_expected.not_to include(user) }
end
- describe "#metrics_setting" do
- let(:project) { build(:project) }
-
- it 'creates setting if it does not exist' do
- expect(project.metrics_setting).to be_an_instance_of(ProjectMetricsSetting)
- end
- end
-
describe '#enabled_group_deploy_keys' do
let_it_be(:project) { create(:project) }
@@ -9170,6 +9195,20 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
+ describe '#supports_lock_on_merge?' do
+ it_behaves_like 'checks self (project) and root ancestor feature flag' do
+ let(:feature_flag) { :enforce_locked_labels_on_merge }
+ let(:feature_flag_method) { :supports_lock_on_merge? }
+ end
+ end
+
+ context 'with loose foreign key on organization_id' do
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let_it_be(:parent) { create(:organization) }
+ let_it_be(:model) { create(:project, organization: parent) }
+ end
+ end
+
private
def finish_job(export_job)