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/services/projects')
-rw-r--r--spec/services/projects/create_service_spec.rb102
-rw-r--r--spec/services/projects/destroy_rollback_service_spec.rb1
-rw-r--r--spec/services/projects/destroy_service_spec.rb1
-rw-r--r--spec/services/projects/gitlab_projects_import_service_spec.rb1
-rw-r--r--spec/services/projects/group_links/create_service_spec.rb5
-rw-r--r--spec/services/projects/group_links/destroy_service_spec.rb1
-rw-r--r--spec/services/projects/group_links/update_service_spec.rb83
-rw-r--r--spec/services/projects/lfs_pointers/lfs_download_service_spec.rb32
-rw-r--r--spec/services/projects/operations/update_service_spec.rb18
-rw-r--r--spec/services/projects/prometheus/alerts/notify_service_spec.rb6
-rw-r--r--spec/services/projects/protect_default_branch_service_spec.rb47
-rw-r--r--spec/services/projects/transfer_service_spec.rb83
-rw-r--r--spec/services/projects/update_pages_service_spec.rb1
-rw-r--r--spec/services/projects/update_repository_storage_service_spec.rb15
-rw-r--r--spec/services/projects/update_service_spec.rb55
15 files changed, 310 insertions, 141 deletions
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index ac0b6cc8ef1..defeadb479a 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -190,6 +190,7 @@ RSpec.describe Projects::CreateService, '#execute' do
let_it_be(:group) { create(:group) }
let_it_be(:shared_group) { create(:group) }
let_it_be(:shared_group_user) { create(:user) }
+
let(:opts) do
{
name: 'GitLab',
@@ -221,6 +222,7 @@ RSpec.describe Projects::CreateService, '#execute' do
let_it_be(:subgroup_for_projects) { create(:group, :private, parent: group) }
let_it_be(:subgroup_for_access) { create(:group, :private, parent: group) }
let_it_be(:group_maintainer) { create(:user) }
+
let(:group_access_level) { Gitlab::Access::REPORTER }
let(:subgroup_access_level) { Gitlab::Access::DEVELOPER }
let(:share_max_access_level) { Gitlab::Access::MAINTAINER }
@@ -582,32 +584,49 @@ RSpec.describe Projects::CreateService, '#execute' do
expect(branches.size).to eq(1)
expect(branches.collect(&:name)).to contain_exactly('example_branch')
end
+
+ describe 'advanced readme content', experiment: :new_project_readme_content do
+ before do
+ stub_experiments(new_project_readme_content: :advanced)
+ end
+
+ it_behaves_like 'creates README.md'
+
+ it 'includes advanced content in the README.md' do
+ content = project.repository.readme.data
+ expect(content).to include <<~MARKDOWN
+ git remote add origin #{project.http_url_to_repo}
+ git branch -M example_branch
+ git push -uf origin example_branch
+ MARKDOWN
+ end
+ end
end
end
- describe 'create service for the project' do
+ describe 'create integration for the project' do
subject(:project) { create_project(user, opts) }
- context 'with an active service template' do
- let!(:template_integration) { create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/') }
+ context 'with an active integration template' do
+ let!(:template_integration) { create(:prometheus_integration, :template, api_url: 'https://prometheus.template.com/') }
- it 'creates a service from the template' do
+ it 'creates an integration from the template' do
expect(project.integrations.count).to eq(1)
expect(project.integrations.first.api_url).to eq(template_integration.api_url)
expect(project.integrations.first.inherit_from_id).to be_nil
end
context 'with an active instance-level integration' do
- let!(:instance_integration) { create(:prometheus_service, :instance, api_url: 'https://prometheus.instance.com/') }
+ let!(:instance_integration) { create(:prometheus_integration, :instance, api_url: 'https://prometheus.instance.com/') }
- it 'creates a service from the instance-level integration' do
+ it 'creates an integration from the instance-level integration' do
expect(project.integrations.count).to eq(1)
expect(project.integrations.first.api_url).to eq(instance_integration.api_url)
expect(project.integrations.first.inherit_from_id).to eq(instance_integration.id)
end
context 'with an active group-level integration' do
- let!(:group_integration) { create(:prometheus_service, group: group, project: nil, api_url: 'https://prometheus.group.com/') }
+ let!(:group_integration) { create(:prometheus_integration, group: group, project: nil, api_url: 'https://prometheus.group.com/') }
let!(:group) do
create(:group).tap do |group|
group.add_owner(user)
@@ -621,14 +640,14 @@ RSpec.describe Projects::CreateService, '#execute' do
}
end
- it 'creates a service from the group-level integration' do
+ it 'creates an integration from the group-level integration' do
expect(project.integrations.count).to eq(1)
expect(project.integrations.first.api_url).to eq(group_integration.api_url)
expect(project.integrations.first.inherit_from_id).to eq(group_integration.id)
end
context 'with an active subgroup' do
- let!(:subgroup_integration) { create(:prometheus_service, group: subgroup, project: nil, api_url: 'https://prometheus.subgroup.com/') }
+ let!(:subgroup_integration) { create(:prometheus_integration, group: subgroup, project: nil, api_url: 'https://prometheus.subgroup.com/') }
let!(:subgroup) do
create(:group, parent: group).tap do |subgroup|
subgroup.add_owner(user)
@@ -642,7 +661,7 @@ RSpec.describe Projects::CreateService, '#execute' do
}
end
- it 'creates a service from the subgroup-level integration' do
+ it 'creates an integration from the subgroup-level integration' do
expect(project.integrations.count).to eq(1)
expect(project.integrations.first.api_url).to eq(subgroup_integration.api_url)
expect(project.integrations.first.inherit_from_id).to eq(subgroup_integration.id)
@@ -686,69 +705,6 @@ RSpec.describe Projects::CreateService, '#execute' do
create_project(user, opts)
end
- context 'when project has access to shared service' do
- before do
- stub_feature_flags(projects_post_creation_worker: false)
- end
-
- context 'Prometheus integration is shared via group cluster' do
- let(:cluster) { create(:cluster, :group, groups: [group]) }
- let(:group) do
- create(:group).tap do |group|
- group.add_owner(user)
- end
- end
-
- before do
- create(:clusters_integrations_prometheus, cluster: cluster)
- end
-
- it 'creates PrometheusService record', :aggregate_failures do
- project = create_project(user, opts.merge!(namespace_id: group.id))
- service = project.prometheus_service
-
- expect(service.active).to be true
- expect(service.manual_configuration?).to be false
- expect(service.persisted?).to be true
- end
- end
-
- context 'Prometheus integration is shared via instance cluster' do
- let(:cluster) { create(:cluster, :instance) }
-
- before do
- create(:clusters_integrations_prometheus, cluster: cluster)
- end
-
- it 'creates PrometheusService record', :aggregate_failures do
- project = create_project(user, opts)
- service = project.prometheus_service
-
- expect(service.active).to be true
- expect(service.manual_configuration?).to be false
- expect(service.persisted?).to be true
- end
-
- it 'cleans invalid record and logs warning', :aggregate_failures do
- invalid_service_record = build(:prometheus_service, properties: { api_url: nil, manual_configuration: true }.to_json)
- allow(PrometheusService).to receive(:new).and_return(invalid_service_record)
-
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) }))
- project = create_project(user, opts)
-
- expect(project.prometheus_service).to be_nil
- end
- end
-
- context 'shared Prometheus integration is not available' do
- it 'does not persist PrometheusService record', :aggregate_failures do
- project = create_project(user, opts)
-
- expect(project.prometheus_service).to be_nil
- end
- end
- end
-
context 'with external authorization enabled' do
before do
enable_external_authorization_service_check
diff --git a/spec/services/projects/destroy_rollback_service_spec.rb b/spec/services/projects/destroy_rollback_service_spec.rb
index f63939337b8..3eaacc8c1e7 100644
--- a/spec/services/projects/destroy_rollback_service_spec.rb
+++ b/spec/services/projects/destroy_rollback_service_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe Projects::DestroyRollbackService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, namespace: user.namespace) }
+
let(:repository) { project.repository }
let(:repository_storage) { project.repository_storage }
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index c6b2b1e2b21..4a76347ea45 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
include ProjectForksHelper
let_it_be(:user) { create(:user) }
+
let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:path) { project.repository.disk_path }
let(:remove_path) { removal_path(path) }
diff --git a/spec/services/projects/gitlab_projects_import_service_spec.rb b/spec/services/projects/gitlab_projects_import_service_spec.rb
index 09d093a9916..d32e720a49f 100644
--- a/spec/services/projects/gitlab_projects_import_service_spec.rb
+++ b/spec/services/projects/gitlab_projects_import_service_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Projects::GitlabProjectsImportService do
let_it_be(:namespace) { create(:namespace) }
+
let(:path) { 'test-path' }
let(:file) { fixture_file_upload('spec/fixtures/project_export.tar.gz') }
let(:overwrite) { false }
diff --git a/spec/services/projects/group_links/create_service_spec.rb b/spec/services/projects/group_links/create_service_spec.rb
index 9bc780fe177..4ea5f2b3a53 100644
--- a/spec/services/projects/group_links/create_service_spec.rb
+++ b/spec/services/projects/group_links/create_service_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Projects::GroupLinks::CreateService, '#execute' do
let_it_be(:user) { create :user }
let_it_be(:group) { create :group }
let_it_be(:project) { create :project }
+
let(:group_access) { Gitlab::Access::DEVELOPER }
let(:opts) do
{
@@ -49,9 +50,9 @@ RSpec.describe Projects::GroupLinks::CreateService, '#execute' do
expect(AuthorizedProjectsWorker).not_to(
receive(:bulk_perform_async)
)
- expect(AuthorizedProjectUpdate::ProjectGroupLinkCreateWorker).to(
+ expect(AuthorizedProjectUpdate::ProjectRecalculateWorker).to(
receive(:perform_async)
- .with(project.id, group.id, group_access)
+ .with(project.id)
.and_call_original
)
expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
diff --git a/spec/services/projects/group_links/destroy_service_spec.rb b/spec/services/projects/group_links/destroy_service_spec.rb
index d60e9a01e54..d65afb68bfe 100644
--- a/spec/services/projects/group_links/destroy_service_spec.rb
+++ b/spec/services/projects/group_links/destroy_service_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Projects::GroupLinks::DestroyService, '#execute' do
let_it_be(:user) { create :user }
let_it_be(:project) { create(:project, :private) }
let_it_be(:group) { create(:group) }
+
let!(:group_link) { create(:project_group_link, project: project, group: group) }
subject { described_class.new(project, user) }
diff --git a/spec/services/projects/group_links/update_service_spec.rb b/spec/services/projects/group_links/update_service_spec.rb
index 053c5eb611e..4a38fb0c7d9 100644
--- a/spec/services/projects/group_links/update_service_spec.rb
+++ b/spec/services/projects/group_links/update_service_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Projects::GroupLinks::UpdateService, '#execute' do
let_it_be(:user) { create :user }
let_it_be(:group) { create :group }
let_it_be(:project) { create :project }
+
let!(:link) { create(:project_group_link, project: project, group: group) }
let(:expiry_date) { 1.month.from_now.to_date }
@@ -32,25 +33,87 @@ RSpec.describe Projects::GroupLinks::UpdateService, '#execute' do
expect(link.expires_at).to eq(expiry_date)
end
- it 'updates project permissions' do
- expect { subject }.to change { user.can?(:create_release, project) }.from(true).to(false)
- end
+ context 'project authorizations update' do
+ context 'when the feature flag `specialized_worker_for_project_share_update_auth_recalculation` is enabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_project_share_update_auth_recalculation: true)
+ end
+
+ it 'calls AuthorizedProjectUpdate::ProjectRecalculateWorker to update project authorizations' do
+ expect(AuthorizedProjectUpdate::ProjectRecalculateWorker)
+ .to receive(:perform_async).with(link.project.id)
+
+ subject
+ end
+
+ it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do
+ expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
+ receive(:bulk_perform_in)
+ .with(1.hour,
+ [[user.id]],
+ batch_delay: 30.seconds, batch_size: 100)
+ )
- it 'executes UserProjectAccessChangedService' do
- expect_next_instance_of(UserProjectAccessChangedService) do |service|
- expect(service).to receive(:execute)
+ subject
+ end
+
+ it 'updates project authorizations of users who had access to the project via the group share', :sidekiq_inline do
+ group.add_maintainer(user)
+
+ expect { subject }.to(
+ change { Ability.allowed?(user, :create_release, project) }
+ .from(true).to(false))
+ end
end
- subject
+ context 'when the feature flag `specialized_worker_for_project_share_update_auth_recalculation` is disabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_project_share_update_auth_recalculation: false)
+ end
+
+ it 'calls UserProjectAccessChangedService to update project authorizations' do
+ expect_next_instance_of(UserProjectAccessChangedService, [user.id]) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ subject
+ end
+
+ it 'updates project authorizations of users who had access to the project via the group share' do
+ group.add_maintainer(user)
+
+ expect { subject }.to(
+ change { Ability.allowed?(user, :create_release, project) }
+ .from(true).to(false))
+ end
+ end
end
context 'with only param not requiring authorization refresh' do
let(:group_link_params) { { expires_at: Date.tomorrow } }
- it 'does not execute UserProjectAccessChangedService' do
- expect(UserProjectAccessChangedService).not_to receive(:new)
+ context 'when the feature flag `specialized_worker_for_project_share_update_auth_recalculation` is enabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_project_share_update_auth_recalculation: true)
+ end
+
+ it 'does not perform any project authorizations update using `AuthorizedProjectUpdate::ProjectRecalculateWorker`' do
+ expect(AuthorizedProjectUpdate::ProjectRecalculateWorker).not_to receive(:perform_async)
+
+ subject
+ end
+ end
+
+ context 'when the feature flag `specialized_worker_for_project_share_update_auth_recalculation` is disabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_project_share_update_auth_recalculation: false)
+ end
+
+ it 'does not perform any project authorizations update using `UserProjectAccessChangedService`' do
+ expect(UserProjectAccessChangedService).not_to receive(:new)
- subject
+ subject
+ end
end
end
end
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 1fb6dae0c08..f27ebb2e19e 100644
--- a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
@@ -106,6 +106,26 @@ RSpec.describe Projects::LfsPointers::LfsDownloadService do
end
end
+ context 'when file download returns a redirect' do
+ let(:redirect_link) { 'http://external-link' }
+
+ before do
+ stub_full_request(download_link).to_return(status: 301, body: 'You are being redirected', headers: { 'Location' => redirect_link } )
+ stub_full_request(redirect_link).to_return(body: lfs_content)
+ end
+
+ it_behaves_like 'lfs object is created'
+
+ it 'correctly stores lfs object' do
+ subject.execute
+
+ new_lfs_object = LfsObject.first
+
+ expect(new_lfs_object).to have_attributes(oid: oid, size: size)
+ expect(File.binread(new_lfs_object.file.file.file)).to eq lfs_content
+ end
+ end
+
context 'when downloaded lfs file has a different size' do
let(:size) { 1 }
@@ -252,6 +272,18 @@ 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/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index 018bfa8ef61..f91f879b772 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -378,8 +378,8 @@ RSpec.describe Projects::Operations::UpdateService do
context 'prometheus integration' do
context 'prometheus params were passed into service' do
- let(:prometheus_service) do
- build_stubbed(:prometheus_service, project: project, properties: {
+ let(:prometheus_integration) do
+ build_stubbed(:prometheus_integration, project: project, properties: {
api_url: "http://example.prometheus.com",
manual_configuration: "0"
})
@@ -394,18 +394,18 @@ RSpec.describe Projects::Operations::UpdateService do
}
end
- it 'uses Project#find_or_initialize_service to include instance defined defaults and pass them to Projects::UpdateService', :aggregate_failures do
+ it 'uses Project#find_or_initialize_integration to include instance defined defaults and pass them to Projects::UpdateService', :aggregate_failures do
project_update_service = double(Projects::UpdateService)
expect(project)
- .to receive(:find_or_initialize_service)
+ .to receive(:find_or_initialize_integration)
.with('prometheus')
- .and_return(prometheus_service)
+ .and_return(prometheus_integration)
expect(Projects::UpdateService).to receive(:new) do |project_arg, user_arg, update_params_hash|
expect(project_arg).to eq project
expect(user_arg).to eq user
- expect(update_params_hash[:prometheus_service_attributes]).to include('properties' => { 'api_url' => 'http://new.prometheus.com', 'manual_configuration' => '1' })
- expect(update_params_hash[:prometheus_service_attributes]).not_to include(*%w(id project_id created_at updated_at))
+ expect(update_params_hash[:prometheus_integration_attributes]).to include('properties' => { 'api_url' => 'http://new.prometheus.com', 'manual_configuration' => '1' })
+ expect(update_params_hash[:prometheus_integration_attributes]).not_to include(*%w(id project_id created_at updated_at))
end.and_return(project_update_service)
expect(project_update_service).to receive(:execute)
@@ -413,13 +413,13 @@ RSpec.describe Projects::Operations::UpdateService do
end
end
- context 'prometheus params were not passed into service' do
+ context 'when prometheus params are not passed into service' do
let(:params) { { something: :else } }
it 'does not pass any prometheus params into Projects::UpdateService', :aggregate_failures do
project_update_service = double(Projects::UpdateService)
- expect(project).not_to receive(:find_or_initialize_service)
+ expect(project).not_to receive(:find_or_initialize_integration)
expect(Projects::UpdateService)
.to receive(:new)
.with(project, user, {})
diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
index 5235c64d451..25cf588dedf 100644
--- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
@@ -115,7 +115,7 @@ RSpec.describe Projects::Prometheus::Alerts::NotifyService do
let(:alert_manager_token) { token_input }
before do
- create(:prometheus_service, project: project)
+ create(:prometheus_integration, project: project)
if alerting_setting
create(:project_alerting_setting,
@@ -165,7 +165,7 @@ RSpec.describe Projects::Prometheus::Alerts::NotifyService do
context 'incident settings' do
before do
- create(:prometheus_service, project: project)
+ create(:prometheus_integration, project: project)
create(:project_alerting_setting, project: project, token: token)
end
@@ -204,7 +204,7 @@ RSpec.describe Projects::Prometheus::Alerts::NotifyService do
let(:process_service) { instance_double(AlertManagement::ProcessPrometheusAlertService) }
before do
- create(:prometheus_service, project: project)
+ create(:prometheus_integration, project: project)
create(:project_alerting_setting, project: project, token: token)
end
diff --git a/spec/services/projects/protect_default_branch_service_spec.rb b/spec/services/projects/protect_default_branch_service_spec.rb
index a485a64ca35..c8aa421cdd4 100644
--- a/spec/services/projects/protect_default_branch_service_spec.rb
+++ b/spec/services/projects/protect_default_branch_service_spec.rb
@@ -99,6 +99,53 @@ RSpec.describe Projects::ProtectDefaultBranchService do
.not_to have_received(:create_protected_branch)
end
end
+
+ context 'when protected branch does not exist' do
+ before do
+ allow(service)
+ .to receive(:protected_branch_exists?)
+ .and_return(false)
+ allow(service)
+ .to receive(:protect_branch?)
+ .and_return(true)
+ end
+
+ it 'changes the HEAD of the project' do
+ service.protect_default_branch
+
+ expect(project)
+ .to have_received(:change_head)
+ end
+
+ it 'protects the default branch' do
+ service.protect_default_branch
+
+ expect(service)
+ .to have_received(:create_protected_branch)
+ end
+ end
+
+ context 'when protected branch already exists' do
+ before do
+ allow(service)
+ .to receive(:protected_branch_exists?)
+ .and_return(true)
+ end
+
+ it 'changes the HEAD of the project' do
+ service.protect_default_branch
+
+ expect(project)
+ .to have_received(:change_head)
+ end
+
+ it 'does not protect the default branch' do
+ service.protect_default_branch
+
+ expect(service)
+ .not_to have_received(:create_protected_branch)
+ end
+ end
end
describe '#create_protected_branch' do
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 3171abfb36f..b71677a5e8f 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -7,7 +7,8 @@ RSpec.describe Projects::TransferService do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
- let_it_be(:group_integration) { create(:slack_service, group: group, project: nil, webhook: 'http://group.slack.com') }
+ let_it_be(:group_integration) { create(:integrations_slack, group: group, project: nil, webhook: 'http://group.slack.com') }
+
let(:project) { create(:project, :repository, :legacy_storage, namespace: user.namespace) }
subject(:execute_transfer) { described_class.new(project, user).execute(group).tap { project.reload } }
@@ -121,24 +122,24 @@ RSpec.describe Projects::TransferService do
context 'with a project integration' do
let_it_be_with_reload(:project) { create(:project, namespace: user.namespace) }
- let_it_be(:instance_integration) { create(:slack_service, :instance, webhook: 'http://project.slack.com') }
+ let_it_be(:instance_integration) { create(:integrations_slack, :instance, webhook: 'http://project.slack.com') }
context 'with an inherited integration' do
- let_it_be(:project_integration) { create(:slack_service, project: project, webhook: 'http://project.slack.com', inherit_from_id: instance_integration.id) }
+ let_it_be(:project_integration) { create(:integrations_slack, project: project, webhook: 'http://project.slack.com', inherit_from_id: instance_integration.id) }
it 'replaces inherited integrations', :aggregate_failures do
execute_transfer
- expect(project.slack_service.webhook).to eq(group_integration.webhook)
+ expect(project.slack_integration.webhook).to eq(group_integration.webhook)
expect(Integration.count).to eq(3)
end
end
context 'with a custom integration' do
- let_it_be(:project_integration) { create(:slack_service, project: project, webhook: 'http://project.slack.com') }
+ let_it_be(:project_integration) { create(:integrations_slack, project: project, webhook: 'http://project.slack.com') }
it 'does not updates the integrations' do
- expect { execute_transfer }.not_to change { project.slack_service.webhook }
+ expect { execute_transfer }.not_to change { project.slack_integration.webhook }
end
end
end
@@ -434,28 +435,74 @@ RSpec.describe Projects::TransferService do
end
describe 'refreshing project authorizations' do
+ let(:old_group) { create(:group) }
+ let!(:project) { create(:project, namespace: old_group) }
+ let(:member_of_old_group) { create(:user) }
let(:group) { create(:group) }
- let(:owner) { project.namespace.owner }
- let(:group_member) { create(:user) }
+ let(:member_of_new_group) { create(:user) }
before do
- group.add_user(owner, GroupMember::MAINTAINER)
- group.add_user(group_member, GroupMember::DEVELOPER)
+ old_group.add_developer(member_of_old_group)
+ group.add_maintainer(member_of_new_group)
+
+ # Add the executing user as owner in both groups, so that
+ # transfer can be executed.
+ old_group.add_owner(user)
+ group.add_owner(user)
end
- it 'refreshes the permissions of the old and new namespace' do
- execute_transfer
+ context 'when the feature flag `specialized_worker_for_project_transfer_auth_recalculation` is enabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_project_transfer_auth_recalculation: true)
+ end
+
+ it 'calls AuthorizedProjectUpdate::ProjectRecalculateWorker to update project authorizations' do
+ expect(AuthorizedProjectUpdate::ProjectRecalculateWorker)
+ .to receive(:perform_async).with(project.id)
+
+ execute_transfer
+ end
+
+ it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do
+ user_ids = [user.id, member_of_old_group.id, member_of_new_group.id].map { |id| [id] }
+
+ expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
+ receive(:bulk_perform_in)
+ .with(1.hour,
+ user_ids,
+ batch_delay: 30.seconds, batch_size: 100)
+ )
- expect(group_member.authorized_projects).to include(project)
- expect(owner.authorized_projects).to include(project)
+ subject
+ end
+
+ it 'refreshes the permissions of the members of the old and new namespace', :sidekiq_inline do
+ expect { execute_transfer }
+ .to change { member_of_old_group.authorized_projects.include?(project) }.from(true).to(false)
+ .and change { member_of_new_group.authorized_projects.include?(project) }.from(false).to(true)
+ end
end
- it 'only schedules a single job for every user' do
- expect_next_instance_of(UserProjectAccessChangedService, [owner.id, group_member.id]) do |service|
- expect(service).to receive(:execute).once.and_call_original
+ context 'when the feature flag `specialized_worker_for_project_transfer_auth_recalculation` is disabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_project_transfer_auth_recalculation: false)
end
- execute_transfer
+ it 'calls UserProjectAccessChangedService to update project authorizations' do
+ user_ids = [user.id, member_of_old_group.id, member_of_new_group.id]
+
+ expect_next_instance_of(UserProjectAccessChangedService, user_ids) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ execute_transfer
+ end
+
+ it 'refreshes the permissions of the members of the old and new namespace' do
+ expect { execute_transfer }
+ .to change { member_of_old_group.authorized_projects.include?(project) }.from(true).to(false)
+ .and change { member_of_new_group.authorized_projects.include?(project) }.from(false).to(true)
+ end
end
end
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index b11607bc213..5898504b463 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -5,6 +5,7 @@ require "spec_helper"
RSpec.describe Projects::UpdatePagesService do
let_it_be(:project, refind: true) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha) }
+
let(:build) { create(:ci_build, pipeline: pipeline, ref: 'HEAD') }
let(:invalid_file) { fixture_file_upload('spec/fixtures/dk.png') }
diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb
index 5b15b7d5f34..17d01a57221 100644
--- a/spec/services/projects/update_repository_storage_service_spec.rb
+++ b/spec/services/projects/update_repository_storage_service_spec.rb
@@ -83,9 +83,10 @@ RSpec.describe Projects::UpdateRepositoryStorageService do
.with(project.repository.raw)
.and_raise(Gitlab::Git::CommandError)
- result = subject.execute
+ expect do
+ subject.execute
+ end.to raise_error(Gitlab::Git::CommandError)
- expect(result).to be_error
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('default')
expect(repository_storage_move).to be_failed
@@ -101,9 +102,10 @@ RSpec.describe Projects::UpdateRepositoryStorageService do
expect(original_project_repository_double).to receive(:remove)
.and_raise(Gitlab::Git::CommandError)
- result = subject.execute
+ expect do
+ subject.execute
+ end.to raise_error(Gitlab::Git::CommandError)
- expect(result).to be_error
expect(repository_storage_move).to be_cleanup_failed
end
end
@@ -118,9 +120,10 @@ RSpec.describe Projects::UpdateRepositoryStorageService do
expect(project_repository_double).to receive(:checksum)
.and_return('not matching checksum')
- result = subject.execute
+ expect do
+ subject.execute
+ end.to raise_error(UpdateRepositoryStorageMethods::Error, /Failed to verify project repository checksum/)
- expect(result).to be_error
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('default')
end
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index e1b22da2e61..c74a8295d0a 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -200,17 +200,32 @@ RSpec.describe Projects::UpdateService do
context 'when updating a default branch' do
let(:project) { create(:project, :repository) }
- it 'changes a default branch' do
+ it 'changes default branch, tracking the previous branch' do
+ previous_default_branch = project.default_branch
+
update_project(project, admin, default_branch: 'feature')
- expect(Project.find(project.id).default_branch).to eq 'feature'
+ project.reload
+
+ expect(project.default_branch).to eq('feature')
+ expect(project.previous_default_branch).to eq(previous_default_branch)
+
+ update_project(project, admin, default_branch: previous_default_branch)
+
+ project.reload
+
+ expect(project.default_branch).to eq(previous_default_branch)
+ expect(project.previous_default_branch).to eq('feature')
end
it 'does not change a default branch' do
# The branch 'unexisted-branch' does not exist.
update_project(project, admin, default_branch: 'unexisted-branch')
- expect(Project.find(project.id).default_branch).to eq 'master'
+ project.reload
+
+ expect(project.default_branch).to eq 'master'
+ expect(project.previous_default_branch).to be_nil
end
end
@@ -468,58 +483,58 @@ RSpec.describe Projects::UpdateService do
end
end
- context 'when updating nested attributes for prometheus service' do
- context 'prometheus service exists' do
- let(:prometheus_service_attributes) do
- attributes_for(:prometheus_service,
+ context 'when updating nested attributes for prometheus integration' do
+ context 'prometheus integration exists' do
+ let(:prometheus_integration_attributes) do
+ attributes_for(:prometheus_integration,
project: project,
properties: { api_url: "http://new.prometheus.com", manual_configuration: "0" }
)
end
- let!(:prometheus_service) do
- create(:prometheus_service,
+ let!(:prometheus_integration) do
+ create(:prometheus_integration,
project: project,
properties: { api_url: "http://old.prometheus.com", manual_configuration: "0" }
)
end
it 'updates existing record' do
- expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) }
- .to change { prometheus_service.reload.api_url }
+ expect { update_project(project, user, prometheus_integration_attributes: prometheus_integration_attributes) }
+ .to change { prometheus_integration.reload.api_url }
.from("http://old.prometheus.com")
.to("http://new.prometheus.com")
end
end
- context 'prometheus service does not exist' do
+ context 'prometheus integration does not exist' do
context 'valid parameters' do
- let(:prometheus_service_attributes) do
- attributes_for(:prometheus_service,
+ let(:prometheus_integration_attributes) do
+ attributes_for(:prometheus_integration,
project: project,
properties: { api_url: "http://example.prometheus.com", manual_configuration: "0" }
)
end
it 'creates new record' do
- expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) }
- .to change { ::PrometheusService.where(project: project).count }
+ expect { update_project(project, user, prometheus_integration_attributes: prometheus_integration_attributes) }
+ .to change { ::Integrations::Prometheus.where(project: project).count }
.from(0)
.to(1)
end
end
context 'invalid parameters' do
- let(:prometheus_service_attributes) do
- attributes_for(:prometheus_service,
+ let(:prometheus_integration_attributes) do
+ attributes_for(:prometheus_integration,
project: project,
properties: { api_url: nil, manual_configuration: "1" }
)
end
it 'does not create new record' do
- expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) }
- .not_to change { ::PrometheusService.where(project: project).count }
+ expect { update_project(project, user, prometheus_integration_attributes: prometheus_integration_attributes) }
+ .not_to change { ::Integrations::Prometheus.where(project: project).count }
end
end
end