summaryrefslogtreecommitdiff
path: root/spec/services/projects
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/projects')
-rw-r--r--spec/services/projects/alerting/notify_service_spec.rb30
-rw-r--r--spec/services/projects/autocomplete_service_spec.rb28
-rw-r--r--spec/services/projects/cleanup_service_spec.rb87
-rw-r--r--spec/services/projects/container_repository/delete_tags_service_spec.rb18
-rw-r--r--spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb2
-rw-r--r--spec/services/projects/create_service_spec.rb35
-rw-r--r--spec/services/projects/lfs_pointers/lfs_download_service_spec.rb12
-rw-r--r--spec/services/projects/update_pages_service_spec.rb59
-rw-r--r--spec/services/projects/update_repository_storage_service_spec.rb18
-rw-r--r--spec/services/projects/update_service_spec.rb50
10 files changed, 273 insertions, 66 deletions
diff --git a/spec/services/projects/alerting/notify_service_spec.rb b/spec/services/projects/alerting/notify_service_spec.rb
index 809b12910a1..4674f614cf1 100644
--- a/spec/services/projects/alerting/notify_service_spec.rb
+++ b/spec/services/projects/alerting/notify_service_spec.rb
@@ -34,13 +34,11 @@ RSpec.describe Projects::Alerting::NotifyService do
let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
- subject { service.execute(token) }
-
- context 'with activated Alerts Service' do
- let_it_be_with_reload(:alerts_service) { create(:alerts_service, project: project) }
+ subject { service.execute(token, nil) }
+ shared_examples 'notifcations are handled correctly' do
context 'with valid token' do
- let(:token) { alerts_service.token }
+ let(:token) { integration.token }
let(:incident_management_setting) { double(send_email?: email_enabled, create_issue?: issue_enabled, auto_close_incident?: auto_close_enabled) }
let(:email_enabled) { false }
let(:issue_enabled) { false }
@@ -131,6 +129,12 @@ RSpec.describe Projects::Alerting::NotifyService do
it { expect { subject }.to change { issue.reload.state }.from('opened').to('closed') }
it { expect { subject }.to change(ResourceStateEvent, :count).by(1) }
end
+
+ context 'with issue enabled' do
+ let(:issue_enabled) { true }
+
+ it_behaves_like 'does not process incident issues'
+ end
end
end
@@ -197,7 +201,7 @@ RSpec.describe Projects::Alerting::NotifyService do
it 'creates a system note corresponding to alert creation' do
expect { subject }.to change(Note, :count).by(1)
- expect(Note.last.note).to include('Generic Alert Endpoint')
+ expect(Note.last.note).to include(source)
end
end
end
@@ -247,10 +251,20 @@ RSpec.describe Projects::Alerting::NotifyService do
it_behaves_like 'does not process incident issues due to error', http_status: :unauthorized
it_behaves_like 'does not an create alert management alert'
end
+ end
+
+ context 'with an HTTP Integration' do
+ let_it_be_with_reload(:integration) { create(:alert_management_http_integration, project: project) }
+
+ subject { service.execute(token, integration) }
+
+ it_behaves_like 'notifcations are handled correctly' do
+ let(:source) { integration.name }
+ end
- context 'with deactivated Alerts Service' do
+ context 'with deactivated HTTP Integration' do
before do
- alerts_service.update!(active: false)
+ integration.update!(active: false)
end
it_behaves_like 'does not process incident issues due to error', http_status: :forbidden
diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb
index aff1aa41091..ef7741c2d0f 100644
--- a/spec/services/projects/autocomplete_service_spec.rb
+++ b/spec/services/projects/autocomplete_service_spec.rb
@@ -79,14 +79,28 @@ RSpec.describe Projects::AutocompleteService do
expect(issues.count).to eq 3
end
- it 'lists all project issues for admin' do
- autocomplete = described_class.new(project, admin)
- issues = autocomplete.issues.map(&:iid)
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'lists all project issues for admin', :enable_admin_mode do
+ autocomplete = described_class.new(project, admin)
+ issues = autocomplete.issues.map(&:iid)
+
+ expect(issues).to include issue.iid
+ expect(issues).to include security_issue_1.iid
+ expect(issues).to include security_issue_2.iid
+ expect(issues.count).to eq 3
+ end
+ end
- expect(issues).to include issue.iid
- expect(issues).to include security_issue_1.iid
- expect(issues).to include security_issue_2.iid
- expect(issues.count).to eq 3
+ context 'when admin mode is disabled' do
+ it 'does not list project confidential issues for admin' do
+ autocomplete = described_class.new(project, admin)
+ issues = autocomplete.issues.map(&:iid)
+
+ expect(issues).to include issue.iid
+ expect(issues).not_to include security_issue_1.iid
+ expect(issues).not_to include security_issue_2.iid
+ expect(issues.count).to eq 1
+ end
end
end
end
diff --git a/spec/services/projects/cleanup_service_spec.rb b/spec/services/projects/cleanup_service_spec.rb
index 7c28b729e84..6fd29813d98 100644
--- a/spec/services/projects/cleanup_service_spec.rb
+++ b/spec/services/projects/cleanup_service_spec.rb
@@ -3,14 +3,84 @@
require 'spec_helper'
RSpec.describe Projects::CleanupService do
- let(:project) { create(:project, :repository, bfg_object_map: fixture_file_upload('spec/fixtures/bfg_object_map.txt')) }
- let(:object_map) { project.bfg_object_map }
+ subject(:service) { described_class.new(project) }
- let(:cleaner) { service.__send__(:repository_cleaner) }
+ describe '.enqueue' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
- subject(:service) { described_class.new(project) }
+ let(:object_map_file) { fixture_file_upload('spec/fixtures/bfg_object_map.txt') }
+
+ subject(:enqueue) { described_class.enqueue(project, user, object_map_file) }
+
+ it 'makes the repository read-only' do
+ expect { enqueue }
+ .to change(project, :repository_read_only?)
+ .from(false)
+ .to(true)
+ end
+
+ it 'sets the bfg_object_map of the project' do
+ enqueue
+
+ expect(project.bfg_object_map.read).to eq(object_map_file.read)
+ end
+
+ it 'enqueues a RepositoryCleanupWorker' do
+ enqueue
+
+ expect(RepositoryCleanupWorker.jobs.count).to eq(1)
+ end
+
+ it 'returns success' do
+ expect(enqueue[:status]).to eq(:success)
+ end
+
+ it 'returns an error if making the repository read-only fails' do
+ project.set_repository_read_only!
+
+ expect(enqueue[:status]).to eq(:error)
+ end
+
+ it 'returns an error if updating the project fails' do
+ expect_next_instance_of(Projects::UpdateService) do |service|
+ expect(service).to receive(:execute).and_return(status: :error)
+ end
+
+ expect(enqueue[:status]).to eq(:error)
+ expect(project.reload.repository_read_only?).to be_falsy
+ end
+ end
+
+ describe '.cleanup_after' do
+ let(:project) { create(:project, :repository, bfg_object_map: fixture_file_upload('spec/fixtures/bfg_object_map.txt')) }
+
+ subject(:cleanup_after) { described_class.cleanup_after(project) }
+
+ before do
+ project.set_repository_read_only!
+ end
+
+ it 'sets the repository read-write' do
+ expect { cleanup_after }.to change(project, :repository_read_only?).from(true).to(false)
+ end
+
+ it 'removes the BFG object map' do
+ cleanup_after
+
+ expect(project.bfg_object_map).not_to be_exist
+ end
+ end
describe '#execute' do
+ let(:project) { create(:project, :repository, bfg_object_map: fixture_file_upload('spec/fixtures/bfg_object_map.txt')) }
+ let(:object_map) { project.bfg_object_map }
+ let(:cleaner) { service.__send__(:repository_cleaner) }
+
+ before do
+ project.set_repository_read_only!
+ end
+
it 'runs the apply_bfg_object_map_stream gitaly RPC' do
expect(cleaner).to receive(:apply_bfg_object_map_stream).with(kind_of(IO))
@@ -19,7 +89,7 @@ RSpec.describe Projects::CleanupService do
it 'runs garbage collection on the repository' do
expect_next_instance_of(GitGarbageCollectWorker) do |worker|
- expect(worker).to receive(:perform).with(project.id, :gc, "project_cleanup:gc:#{project.id}")
+ expect(worker).to receive(:perform).with(project.id, :prune, "project_cleanup:gc:#{project.id}")
end
service.execute
@@ -37,6 +107,13 @@ RSpec.describe Projects::CleanupService do
expect(object_map.exists?).to be_falsy
end
+ it 'makes the repository read-write again' do
+ expect { service.execute }
+ .to change(project, :repository_read_only?)
+ .from(true)
+ .to(false)
+ end
+
context 'with a tainted merge request diff' do
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:diff) { merge_request.merge_request_diff }
diff --git a/spec/services/projects/container_repository/delete_tags_service_spec.rb b/spec/services/projects/container_repository/delete_tags_service_spec.rb
index c3ae26b1f05..a012ec29be5 100644
--- a/spec/services/projects/container_repository/delete_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/delete_tags_service_spec.rb
@@ -27,13 +27,17 @@ RSpec.describe Projects::ContainerRepository::DeleteTagsService do
end
end
- RSpec.shared_examples 'logging an error response' do |message: 'could not delete tags'|
+ RSpec.shared_examples 'logging an error response' do |message: 'could not delete tags', extra_log: {}|
it 'logs an error message' do
- expect(service).to receive(:log_error).with(
- service_class: 'Projects::ContainerRepository::DeleteTagsService',
- message: message,
- container_repository_id: repository.id
- )
+ log_data = {
+ service_class: 'Projects::ContainerRepository::DeleteTagsService',
+ message: message,
+ container_repository_id: repository.id
+ }
+
+ log_data.merge!(extra_log) if extra_log.any?
+
+ expect(service).to receive(:log_error).with(log_data)
subject
end
@@ -115,7 +119,7 @@ RSpec.describe Projects::ContainerRepository::DeleteTagsService do
it { is_expected.to include(status: :error, message: 'timeout while deleting tags') }
- it_behaves_like 'logging an error response', message: 'timeout while deleting tags'
+ it_behaves_like 'logging an error response', message: 'timeout while deleting tags', extra_log: { deleted_tags_count: 0 }
end
end
end
diff --git a/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb b/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb
index 3bbcec8775e..988971171fc 100644
--- a/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/gitlab/delete_tags_service_spec.rb
@@ -67,7 +67,7 @@ RSpec.describe Projects::ContainerRepository::Gitlab::DeleteTagsService do
stub_delete_reference_requests('A' => 200)
end
- it { is_expected.to include(status: :error, message: 'timeout while deleting tags') }
+ it { is_expected.to eq(status: :error, message: 'timeout while deleting tags', deleted: ['A']) }
it 'tracks the exception' do
expect(::Gitlab::ErrorTracking)
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index d959cc87901..6c0e6654622 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -72,14 +72,25 @@ RSpec.describe Projects::CreateService, '#execute' do
end
context "admin creates project with other user's namespace_id" do
- it 'sets the correct permissions' do
- admin = create(:admin)
- project = create_project(admin, opts)
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'sets the correct permissions' do
+ admin = create(:admin)
+ project = create_project(admin, opts)
- expect(project).to be_persisted
- expect(project.owner).to eq(user)
- expect(project.team.maintainers).to contain_exactly(user)
- expect(project.namespace).to eq(user.namespace)
+ expect(project).to be_persisted
+ expect(project.owner).to eq(user)
+ expect(project.team.maintainers).to contain_exactly(user)
+ expect(project.namespace).to eq(user.namespace)
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'is not allowed' do
+ admin = create(:admin)
+ project = create_project(admin, opts)
+
+ expect(project).not_to be_persisted
+ end
end
end
@@ -336,7 +347,15 @@ RSpec.describe Projects::CreateService, '#execute' do
)
end
- it 'allows a restricted visibility level for admins' do
+ it 'does not allow a restricted visibility level for admins when admin mode is disabled' do
+ admin = create(:admin)
+ project = create_project(admin, opts)
+
+ expect(project.errors.any?).to be(true)
+ expect(project.saved?).to be_falsey
+ end
+
+ it 'allows a restricted visibility level for admins when admin mode is enabled', :enable_admin_mode do
admin = create(:admin)
project = create_project(admin, opts)
diff --git a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
index cfe8e863223..1b829df6e6a 100644
--- a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
@@ -241,18 +241,6 @@ RSpec.describe Projects::LfsPointers::LfsDownloadService do
context 'and first fragments are the same' do
let(:lfs_content) { existing_lfs_object.file.read }
- context 'when lfs_link_existing_object feature flag disabled' do
- before do
- stub_feature_flags(lfs_link_existing_object: false)
- end
-
- it 'does not call link_existing_lfs_object!' do
- expect(subject).not_to receive(:link_existing_lfs_object!)
-
- subject.execute
- end
- end
-
it 'returns success' do
expect(subject.execute).to eq({ status: :success })
end
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index d3eb84a3137..d2c6c0eb971 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe Projects::UpdatePagesService do
context 'for new artifacts' do
context "for a valid job" do
- let!(:artifacts_archive) { create(:ci_job_artifact, file: file, job: build) }
+ let!(:artifacts_archive) { create(:ci_job_artifact, :correct_checksum, file: file, job: build) }
before do
create(:ci_job_artifact, file_type: :metadata, file_format: :gzip, file: metadata, job: build)
@@ -66,9 +66,45 @@ RSpec.describe Projects::UpdatePagesService do
expect(deployment.size).to eq(file.size)
expect(deployment.file).to be
+ expect(deployment.file_count).to eq(3)
+ expect(deployment.file_sha256).to eq(artifacts_archive.file_sha256)
expect(project.pages_metadatum.reload.pages_deployment_id).to eq(deployment.id)
end
+ it 'does not fail if pages_metadata is absent' do
+ project.pages_metadatum.destroy!
+ project.reload
+
+ expect do
+ expect(execute).to eq(:success)
+ end.to change { project.pages_deployments.count }.by(1)
+
+ expect(project.pages_metadatum.reload.pages_deployment).to eq(project.pages_deployments.last)
+ end
+
+ 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) }
+
+ it 'schedules a destruction of older deployments' do
+ expect(DestroyPagesDeploymentsWorker).to(
+ receive(:perform_in).with(described_class::OLD_DEPLOYMENTS_DESTRUCTION_DELAY,
+ project.id,
+ instance_of(Integer))
+ )
+
+ execute
+ end
+
+ it 'removes older deployments', :sidekiq_inline do
+ expect do
+ execute
+ end.not_to change { PagesDeployment.count } # it creates one and deletes one
+
+ expect(PagesDeployment.find_by_id(old_deployment.id)).to be_nil
+ end
+ end
+
it 'does not create deployment when zip_pages_deployments feature flag is disabled' do
stub_feature_flags(zip_pages_deployments: false)
@@ -188,6 +224,25 @@ RSpec.describe Projects::UpdatePagesService do
end
end
+ # this situation should never happen in real life because all new archives have sha256
+ # and we only use new archives
+ # this test is here just to clarify that this behavior is intentional
+ context 'when artifacts archive does not have sha256' do
+ let!(:artifacts_archive) { create(:ci_job_artifact, file: file, job: build) }
+
+ before do
+ create(:ci_job_artifact, file_type: :metadata, file_format: :gzip, file: metadata, job: build)
+
+ build.reload
+ end
+
+ it 'fails with exception raised' do
+ expect do
+ execute
+ end.to raise_error("Validation failed: File sha256 can't be blank")
+ end
+ end
+
it 'fails to remove project pages when no pages is deployed' do
expect(PagesWorker).not_to receive(:perform_in)
expect(project.pages_deployed?).to be_falsey
@@ -210,7 +265,7 @@ RSpec.describe Projects::UpdatePagesService do
file = fixture_file_upload('spec/fixtures/pages.zip')
metafile = fixture_file_upload('spec/fixtures/pages.zip.meta')
- create(:ci_job_artifact, :archive, file: file, job: build)
+ create(:ci_job_artifact, :archive, :correct_checksum, file: file, job: build)
create(:ci_job_artifact, :metadata, file: metafile, job: build)
allow(build).to receive(:artifacts_metadata_entry)
diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb
index 0fcd14f3bc9..123f604e7a4 100644
--- a/spec/services/projects/update_repository_storage_service_spec.rb
+++ b/spec/services/projects/update_repository_storage_service_spec.rb
@@ -168,6 +168,24 @@ RSpec.describe Projects::UpdateRepositoryStorageService do
end
end
+ context 'project with no repositories' do
+ let(:project) { create(:project) }
+ let(:repository_storage_move) { create(:project_repository_storage_move, :scheduled, project: project, destination_storage_name: 'test_second_storage') }
+
+ it 'updates the database' do
+ allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original
+ allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('test_second_storage').and_return(SecureRandom.uuid)
+
+ result = subject.execute
+ project.reload
+
+ expect(result).to be_success
+ expect(project).not_to be_repository_read_only
+ expect(project.repository_storage).to eq('test_second_storage')
+ expect(project.project_repository.shard_name).to eq('test_second_storage')
+ end
+ end
+
context 'with wiki repository' do
include_examples 'moves repository to another storage', 'wiki' do
let(:project) { create(:project, :repository, wiki_enabled: true) }
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 989426fde8b..760cd85bf71 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -127,11 +127,22 @@ RSpec.describe Projects::UpdateService do
end
context 'when updated by an admin' do
- it 'updates the project to public' do
- result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'updates the project to public' do
+ result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
- expect(result).to eq({ status: :success })
- expect(project).to be_public
+ expect(result).to eq({ status: :success })
+ expect(project).to be_public
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'does not update the project to public' do
+ result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+
+ expect(result).to eq({ status: :error, message: 'New visibility level not allowed!' })
+ expect(project).to be_private
+ end
end
end
end
@@ -144,7 +155,7 @@ RSpec.describe Projects::UpdateService do
project.update!(namespace: group, visibility_level: group.visibility_level)
end
- it 'does not update project visibility level' do
+ it 'does not update project visibility level even if admin', :enable_admin_mode do
result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
expect(result).to eq({ status: :error, message: 'Visibility level public is not allowed in a internal group.' })
@@ -181,6 +192,7 @@ RSpec.describe Projects::UpdateService do
describe 'when updating project that has forks' do
let(:project) { create(:project, :internal) }
+ let(:user) { project.owner }
let(:forked_project) { fork_project(project) }
context 'and unlink forks feature flag is off' do
@@ -194,7 +206,7 @@ RSpec.describe Projects::UpdateService do
expect(project).to be_internal
expect(forked_project).to be_internal
- expect(update_project(project, admin, opts)).to eq({ status: :success })
+ expect(update_project(project, user, opts)).to eq({ status: :success })
expect(project).to be_private
expect(forked_project.reload).to be_private
@@ -206,7 +218,7 @@ RSpec.describe Projects::UpdateService do
expect(project).to be_internal
expect(forked_project).to be_internal
- expect(update_project(project, admin, opts)).to eq({ status: :success })
+ expect(update_project(project, user, opts)).to eq({ status: :success })
expect(project).to be_public
expect(forked_project.reload).to be_internal
@@ -220,7 +232,7 @@ RSpec.describe Projects::UpdateService do
expect(project).to be_internal
expect(forked_project).to be_internal
- expect(update_project(project, admin, opts)).to eq({ status: :success })
+ expect(update_project(project, user, opts)).to eq({ status: :success })
expect(project).to be_private
expect(forked_project.reload).to be_internal
@@ -576,15 +588,21 @@ RSpec.describe Projects::UpdateService do
context 'authenticated as admin' do
let(:user) { create(:admin) }
- it 'schedules the transfer of the repository to the new storage and locks the project' do
- update_project(project, admin, opts)
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'schedules the transfer of the repository to the new storage and locks the project' do
+ update_project(project, admin, opts)
- expect(project).to be_repository_read_only
- expect(project.repository_storage_moves.last).to have_attributes(
- state: ::ProjectRepositoryStorageMove.state_machines[:state].states[:scheduled].value,
- source_storage_name: 'default',
- destination_storage_name: 'test_second_storage'
- )
+ expect(project).to be_repository_read_only
+ expect(project.repository_storage_moves.last).to have_attributes(
+ state: ::ProjectRepositoryStorageMove.state_machines[:state].states[:scheduled].value,
+ source_storage_name: 'default',
+ destination_storage_name: 'test_second_storage'
+ )
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it_behaves_like 'the transfer was not scheduled'
end
context 'the repository is read-only' do