diff options
Diffstat (limited to 'spec/models/project_spec.rb')
-rw-r--r-- | spec/models/project_spec.rb | 242 |
1 files changed, 123 insertions, 119 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index a2b51684d4d..fd7975bf65d 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -21,6 +21,7 @@ RSpec.describe Project, factory_default: :keep do it { is_expected.to have_many(:services) } 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') } it { is_expected.to have_many(:issues) } it { is_expected.to have_many(:milestones) } it { is_expected.to have_many(:iterations) } @@ -558,6 +559,25 @@ RSpec.describe Project, factory_default: :keep do end end + describe '#default_pipeline_lock' do + let(:project) { build_stubbed(:project) } + + subject { project.default_pipeline_lock } + + where(:keep_latest_artifact_enabled, :result_pipeline_locked) do + false | :unlocked + true | :artifacts_locked + end + + before do + allow(project).to receive(:keep_latest_artifacts_available?).and_return(keep_latest_artifact_enabled) + end + + with_them do + it { expect(subject).to eq(result_pipeline_locked) } + end + end + describe '#autoclose_referenced_issues' do context 'when DB entry is nil' do let(:project) { build(:project, autoclose_referenced_issues: nil) } @@ -1002,103 +1022,125 @@ RSpec.describe Project, factory_default: :keep do end end - describe '#external_issue_tracker' do - let(:project) { create(:project) } - let(:ext_project) { create(:redmine_project) } + describe '#has_wiki?' do + let(:no_wiki_project) { create(:project, :wiki_disabled, has_external_wiki: false) } + let(:wiki_enabled_project) { create(:project) } + let(:external_wiki_project) { create(:project, has_external_wiki: true) } - context 'on existing projects with no value for has_external_issue_tracker' do - before do - project.update_column(:has_external_issue_tracker, nil) - ext_project.update_column(:has_external_issue_tracker, nil) + it 'returns true if project is wiki enabled or has external wiki' do + expect(wiki_enabled_project).to have_wiki + expect(external_wiki_project).to have_wiki + expect(no_wiki_project).not_to have_wiki + end + end + + describe '#default_owner' do + let_it_be(:owner) { create(:user) } + let_it_be(:namespace) { create(:namespace, owner: owner) } + + context 'the project does not have a group' do + let(:project) { build(:project, namespace: namespace) } + + it 'is the namespace owner' do + expect(project.default_owner).to eq(owner) end + end - it 'updates the has_external_issue_tracker boolean' do - expect do - project.external_issue_tracker - end.to change { project.reload.has_external_issue_tracker }.to(false) + context 'the project is in a group' do + let(:group) { build(:group) } + let(:project) { build(:project, group: group, namespace: namespace) } - expect do - ext_project.external_issue_tracker - end.to change { ext_project.reload.has_external_issue_tracker }.to(true) + it 'is the group owner' do + allow(group).to receive(:default_owner).and_return(Object.new) + + expect(project.default_owner).to eq(group.default_owner) end end + end + + describe '#external_issue_tracker' do + it 'sets Project#has_external_issue_tracker when it is nil' do + project_with_no_tracker = create(:project, has_external_issue_tracker: nil) + project_with_tracker = create(:redmine_project, has_external_issue_tracker: nil) + + expect do + project_with_no_tracker.external_issue_tracker + end.to change { project_with_no_tracker.reload.has_external_issue_tracker }.from(nil).to(false) + + expect do + project_with_tracker.external_issue_tracker + end.to change { project_with_tracker.reload.has_external_issue_tracker }.from(nil).to(true) + end it 'returns nil and does not query services when there is no external issue tracker' do - expect(project).not_to receive(:services) + project = create(:project) + expect(project).not_to receive(:services) expect(project.external_issue_tracker).to eq(nil) end it 'retrieves external_issue_tracker querying services and cache it when there is external issue tracker' do - ext_project.reload # Factory returns a project with changed attributes - expect(ext_project).to receive(:services).once.and_call_original + project = create(:redmine_project) - 2.times { expect(ext_project.external_issue_tracker).to be_a_kind_of(RedmineService) } + expect(project).to receive(:services).once.and_call_original + 2.times { expect(project.external_issue_tracker).to be_a_kind_of(RedmineService) } end end - describe '#cache_has_external_issue_tracker' do - let_it_be(:project) { create(:project, has_external_issue_tracker: nil) } - - it 'stores true if there is any external_issue_tracker' do - services = double(:service, external_issue_trackers: [RedmineService.new]) - expect(project).to receive(:services).and_return(services) + describe '#has_external_issue_tracker' do + let_it_be(:project) { create(:project) } - expect do - project.cache_has_external_issue_tracker - end.to change { project.has_external_issue_tracker}.to(true) + def subject + project.reload.has_external_issue_tracker end - it 'stores false if there is no external_issue_tracker' do - services = double(:service, external_issue_trackers: []) - expect(project).to receive(:services).and_return(services) + it 'is false when external issue tracker service is not active' do + create(:service, project: project, category: 'issue_tracker', active: false) - expect do - project.cache_has_external_issue_tracker - end.to change { project.has_external_issue_tracker}.to(false) + is_expected.to eq(false) end - it 'does not cache data when in a read-only GitLab instance' do - allow(Gitlab::Database).to receive(:read_only?) { true } + it 'is false when other service is active' do + create(:service, project: project, category: 'not_issue_tracker', active: true) - expect do - project.cache_has_external_issue_tracker - end.not_to change { project.has_external_issue_tracker } + is_expected.to eq(false) end - end - describe '#has_wiki?' do - let(:no_wiki_project) { create(:project, :wiki_disabled, has_external_wiki: false) } - let(:wiki_enabled_project) { create(:project) } - let(:external_wiki_project) { create(:project, has_external_wiki: true) } - - it 'returns true if project is wiki enabled or has external wiki' do - expect(wiki_enabled_project).to have_wiki - expect(external_wiki_project).to have_wiki - expect(no_wiki_project).not_to have_wiki - end - end + context 'when there is an active external issue tracker service' do + let!(:service) do + create(:service, project: project, type: 'JiraService', category: 'issue_tracker', active: true) + end - describe '#default_owner' do - let_it_be(:owner) { create(:user) } - let_it_be(:namespace) { create(:namespace, owner: owner) } + specify { is_expected.to eq(true) } - context 'the project does not have a group' do - let(:project) { build(:project, namespace: namespace) } + it 'becomes false when external issue tracker service is destroyed' do + expect do + Service.find(service.id).delete + end.to change { subject }.to(false) + end - it 'is the namespace owner' do - expect(project.default_owner).to eq(owner) + it 'becomes false when external issue tracker service becomes inactive' do + expect do + service.update_column(:active, false) + end.to change { subject }.to(false) end - end - context 'the project is in a group' do - let(:group) { build(:group) } - let(:project) { build(:project, group: group, namespace: namespace) } + context 'when there are two active external issue tracker services' do + let_it_be(:second_service) do + create(:service, project: project, type: 'CustomIssueTracker', category: 'issue_tracker', active: true) + end - it 'is the group owner' do - allow(group).to receive(:default_owner).and_return(Object.new) + it 'does not become false when external issue tracker service is destroyed' do + expect do + Service.find(service.id).delete + end.not_to change { subject } + end - expect(project.default_owner).to eq(group.default_owner) + it 'does not become false when external issue tracker service becomes inactive' do + expect do + service.update_column(:active, false) + end.not_to change { subject } + end end end end @@ -1234,7 +1276,7 @@ RSpec.describe Project, factory_default: :keep do it 'is false if avatar is html page' do project.update_attribute(:avatar, 'uploads/avatar.html') - expect(project.avatar_type).to eq(['file format is not supported. Please try one of the following supported formats: png, jpg, jpeg, gif, bmp, tiff, ico']) + expect(project.avatar_type).to eq(['file format is not supported. Please try one of the following supported formats: png, jpg, jpeg, gif, bmp, tiff, ico, webp']) end end @@ -1529,10 +1571,7 @@ RSpec.describe Project, factory_default: :keep do let(:project) { build(:project) } it 'picks storage from ApplicationSetting' do - expect_next_instance_of(ApplicationSetting) do |instance| - expect(instance).to receive(:pick_repository_storage).and_return('picked') - end - expect(described_class).to receive(:pick_repository_storage).and_call_original + expect(Repository).to receive(:pick_storage_shard).and_return('picked') expect(project.repository_storage).to eq('picked') end @@ -2227,8 +2266,6 @@ RSpec.describe Project, factory_default: :keep do end describe '#ci_config_path=' do - using RSpec::Parameterized::TableSyntax - let(:project) { build_stubbed(:project) } where(:default_ci_config_path, :project_ci_config_path, :expected_ci_config_path) do @@ -2980,6 +3017,7 @@ RSpec.describe Project, factory_default: :keep do it_behaves_like 'can housekeep repository' do let(:resource) { build_stubbed(:project) } let(:resource_key) { 'projects' } + let(:expected_worker_class) { Projects::GitGarbageCollectWorker } end describe '#deployment_variables' do @@ -3926,7 +3964,6 @@ RSpec.describe Project, factory_default: :keep do describe '.filter_by_feature_visibility' do include_context 'ProjectPolicyTable context' include ProjectHelpers - using RSpec::Parameterized::TableSyntax let_it_be(:group) { create(:group) } let!(:project) { create(:project, project_level, namespace: group ) } @@ -4099,7 +4136,7 @@ RSpec.describe Project, factory_default: :keep do end end - describe '#remove_pages' do + describe '#legacy_remove_pages' do let(:project) { create(:project).tap { |project| project.mark_pages_as_deployed } } let(:pages_metadatum) { project.pages_metadatum } let(:namespace) { project.namespace } @@ -4118,34 +4155,22 @@ RSpec.describe Project, factory_default: :keep do expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project).and_return(true) expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, namespace.full_path, anything) - expect { project.remove_pages }.to change { pages_metadatum.reload.deployed }.from(true).to(false) + expect { project.legacy_remove_pages }.to change { pages_metadatum.reload.deployed }.from(true).to(false) end - it 'is run when the project is destroyed' do - expect(project).to receive(:remove_pages).and_call_original - - expect { project.destroy }.not_to raise_error - end + it 'does nothing if updates on legacy storage are disabled' do + stub_feature_flags(pages_update_legacy_storage: false) - context 'when there is an old pages deployment' do - let!(:old_deployment_from_another_project) { create(:pages_deployment) } - let!(:old_deployment) { create(:pages_deployment, project: project) } + expect(Gitlab::PagesTransfer).not_to receive(:new) + expect(PagesWorker).not_to receive(:perform_in) - it 'schedules a destruction of pages deployments' do - expect(DestroyPagesDeploymentsWorker).to( - receive(:perform_async).with(project.id) - ) - - project.remove_pages - end + project.legacy_remove_pages + end - it 'removes pages deployments', :sidekiq_inline do - expect do - project.remove_pages - end.to change { PagesDeployment.count }.by(-1) + it 'is run when the project is destroyed' do + expect(project).to receive(:legacy_remove_pages).and_call_original - expect(PagesDeployment.find_by_id(old_deployment.id)).to be_nil - end + expect { project.destroy }.not_to raise_error end end @@ -4176,8 +4201,6 @@ RSpec.describe Project, factory_default: :keep do end describe '#git_transfer_in_progress?' do - using RSpec::Parameterized::TableSyntax - let(:project) { build(:project) } subject { project.git_transfer_in_progress? } @@ -5068,10 +5091,8 @@ RSpec.describe Project, factory_default: :keep do it 'executes services with the specified scope' do data = 'any data' - expect(SlackService).to receive(:allocate).and_wrap_original do |method| - method.call.tap do |instance| - expect(instance).to receive(:async_execute).with(data).once - end + expect_next_found_instance_of(SlackService) do |instance| + expect(instance).to receive(:async_execute).with(data).once end service.project.execute_services(data, :push_hooks) @@ -5801,8 +5822,6 @@ RSpec.describe Project, factory_default: :keep do end describe 'validation #changing_shared_runners_enabled_is_allowed' do - using RSpec::Parameterized::TableSyntax - where(:shared_runners_setting, :project_shared_runners_enabled, :valid_record) do 'enabled' | true | true 'enabled' | false | true @@ -6025,8 +6044,6 @@ RSpec.describe Project, factory_default: :keep do end describe '#closest_setting' do - using RSpec::Parameterized::TableSyntax - shared_examples_for 'fetching closest setting' do let!(:namespace) { create(:namespace) } let!(:project) { create(:project, namespace: namespace) } @@ -6378,20 +6395,7 @@ RSpec.describe Project, factory_default: :keep do describe 'with Debian Distributions' do subject { create(:project) } - let!(:distributions) { create_list(:debian_project_distribution, 2, :with_file, container: subject) } - - it 'removes distribution files on removal' do - distribution_file_paths = distributions.map do |distribution| - distribution.file.path - end - - expect { subject.destroy } - .to change { - distribution_file_paths.select do |path| - File.exist? path - end.length - }.from(distribution_file_paths.length).to(0) - end + it_behaves_like 'model with Debian distributions' end describe '#environments_for_scope' do |