diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 12:55:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 12:55:51 +0300 |
commit | e8d2c2579383897a1dd7f9debd359abe8ae8373d (patch) | |
tree | c42be41678c2586d49a75cabce89322082698334 /spec/services/projects | |
parent | fc845b37ec3a90aaa719975f607740c22ba6a113 (diff) |
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/services/projects')
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 |