summaryrefslogtreecommitdiff
path: root/spec/models/project_spec.rb
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 13:37:47 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 13:37:47 +0000
commitaee0a117a889461ce8ced6fcf73207fe017f1d99 (patch)
tree891d9ef189227a8445d83f35c1b0fc99573f4380 /spec/models/project_spec.rb
parent8d46af3258650d305f53b819eabf7ab18d22f59e (diff)
downloadgitlab-ce-aee0a117a889461ce8ced6fcf73207fe017f1d99.tar.gz
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'spec/models/project_spec.rb')
-rw-r--r--spec/models/project_spec.rb183
1 files changed, 172 insertions, 11 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 3a8768ff463..4e38bf7d3e3 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -261,7 +261,49 @@ RSpec.describe Project, factory_default: :keep do
end
context 'updating a project' do
- context 'with project namespaces' do
+ shared_examples 'project update' do
+ let_it_be(:project_namespace) { create(:project_namespace) }
+ let_it_be(:project) { project_namespace.project }
+
+ context 'when project namespace is not set' do
+ before do
+ project.update_column(:project_namespace_id, nil)
+ project.reload
+ end
+
+ it 'updates the project successfully' do
+ # pre-check that project does not have a project namespace
+ expect(project.project_namespace).to be_nil
+
+ project.update!(path: 'hopefully-valid-path2')
+
+ expect(project).to be_persisted
+ expect(project).to be_valid
+ expect(project.path).to eq('hopefully-valid-path2')
+ expect(project.project_namespace).to be_nil
+ end
+ end
+
+ context 'when project has an associated project namespace' do
+ # when FF is disabled creating a project does not create a project_namespace, so we create one
+ it 'project is INVALID when trying to remove project namespace' do
+ project.reload
+ # check that project actually has an associated project namespace
+ expect(project.project_namespace_id).to eq(project_namespace.id)
+
+ expect do
+ project.update!(project_namespace_id: nil, path: 'hopefully-valid-path1')
+ end.to raise_error(ActiveRecord::RecordInvalid)
+ expect(project).to be_invalid
+ expect(project.errors.full_messages).to include("Project namespace can't be blank")
+ expect(project.reload.project_namespace).to be_in_sync_with_project(project)
+ end
+ end
+ end
+
+ context 'with create_project_namespace_on_project_create FF enabled' do
+ it_behaves_like 'project update'
+
it 'keeps project namespace in sync with project' do
project = create(:project)
project.update!(path: 'hopefully-valid-path1')
@@ -270,19 +312,21 @@ RSpec.describe Project, factory_default: :keep do
expect(project.project_namespace).to be_persisted
expect(project.project_namespace).to be_in_sync_with_project(project)
end
+ end
- context 'with FF disabled' do
- before do
- stub_feature_flags(create_project_namespace_on_project_create: false)
- end
+ context 'with create_project_namespace_on_project_create FF disabled' do
+ before do
+ stub_feature_flags(create_project_namespace_on_project_create: false)
+ end
- it 'does not create a project namespace when project is updated' do
- project = create(:project)
- project.update!(path: 'hopefully-valid-path1')
+ it_behaves_like 'project update'
- expect(project).to be_persisted
- expect(project.project_namespace).to be_nil
- end
+ it 'does not create a project namespace when project is updated' do
+ project = create(:project)
+ project.update!(path: 'hopefully-valid-path1')
+
+ expect(project).to be_persisted
+ expect(project.project_namespace).to be_nil
end
end
end
@@ -807,6 +851,23 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#remove_project_authorizations' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user_1) { create(:user) }
+ let_it_be(:user_2) { create(:user) }
+ let_it_be(:user_3) { create(:user) }
+
+ it 'removes the project authorizations of the specified users in the current project' do
+ create(:project_authorization, user: user_1, project: project)
+ create(:project_authorization, user: user_2, project: project)
+ create(:project_authorization, user: user_3, project: project)
+
+ project.remove_project_authorizations([user_1.id, user_2.id])
+
+ expect(project.project_authorizations.pluck(:user_id)).not_to include(user_1.id, user_2.id)
+ end
+ end
+
describe 'reference methods' do
let_it_be(:owner) { create(:user, name: 'Gitlab') }
let_it_be(:namespace) { create(:namespace, name: 'Sample namespace', path: 'sample-namespace', owner: owner) }
@@ -3520,6 +3581,29 @@ RSpec.describe Project, factory_default: :keep do
expect(project.forks).to contain_exactly(forked_project)
end
end
+
+ describe '#lfs_object_oids_from_fork_source' do
+ let_it_be(:lfs_object) { create(:lfs_object) }
+ let_it_be(:another_lfs_object) { create(:lfs_object) }
+
+ let(:oids) { [lfs_object.oid, another_lfs_object.oid] }
+
+ context 'when fork has one of two LFS objects' do
+ before do
+ create(:lfs_objects_project, lfs_object: lfs_object, project: project)
+ create(:lfs_objects_project, lfs_object: another_lfs_object, project: forked_project)
+ end
+
+ it 'returns OIDs of owned LFS objects', :aggregate_failures do
+ expect(forked_project.lfs_objects_oids_from_fork_source(oids: oids)).to eq([lfs_object.oid])
+ expect(forked_project.lfs_objects_oids(oids: oids)).to eq([another_lfs_object.oid])
+ end
+
+ it 'returns empty when project is not a fork' do
+ expect(project.lfs_objects_oids_from_fork_source(oids: oids)).to eq([])
+ end
+ end
+ end
end
it_behaves_like 'can housekeep repository' do
@@ -7392,6 +7476,83 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ it_behaves_like 'it has loose foreign keys' do
+ let(:factory_name) { :project }
+ end
+
+ context 'Projects::SyncEvent' do
+ let!(:project) { create(:project) }
+
+ let_it_be(:new_namespace1) { create(:namespace) }
+ let_it_be(:new_namespace2) { create(:namespace) }
+
+ context 'when creating the project' do
+ it 'creates a projects_sync_event record' do
+ expect(project.sync_events.count).to eq(1)
+ end
+
+ it 'enqueues ProcessProjectSyncEventsWorker' do
+ expect(Projects::ProcessSyncEventsWorker).to receive(:perform_async)
+
+ create(:project)
+ end
+ end
+
+ context 'when updating project namespace_id' do
+ it 'creates a projects_sync_event record' do
+ expect do
+ project.update!(namespace_id: new_namespace1.id)
+ end.to change(Projects::SyncEvent, :count).by(1)
+
+ expect(project.sync_events.count).to eq(2)
+ end
+
+ it 'enqueues ProcessProjectSyncEventsWorker' do
+ expect(Projects::ProcessSyncEventsWorker).to receive(:perform_async)
+
+ project.update!(namespace_id: new_namespace1.id)
+ end
+ end
+
+ context 'when updating project other attribute' do
+ it 'creates a projects_sync_event record' do
+ expect do
+ project.update!(name: 'hello')
+ end.not_to change(Projects::SyncEvent, :count)
+ end
+ end
+
+ context 'in the same transaction' do
+ context 'when updating different namespace_id' do
+ it 'creates two projects_sync_event records' do
+ expect do
+ Project.transaction do
+ project.update!(namespace_id: new_namespace1.id)
+ project.update!(namespace_id: new_namespace2.id)
+ end
+ end.to change(Projects::SyncEvent, :count).by(2)
+
+ expect(project.sync_events.count).to eq(3)
+ end
+ end
+
+ context 'when updating the same namespace_id' do
+ it 'creates one projects_sync_event record' do
+ expect do
+ Project.transaction do
+ project.update!(namespace_id: new_namespace1.id)
+ project.update!(namespace_id: new_namespace1.id)
+ end
+ end.to change(Projects::SyncEvent, :count).by(1)
+
+ expect(project.sync_events.count).to eq(2)
+ end
+ end
+ end
+ end
+
+ private
+
def finish_job(export_job)
export_job.start
export_job.finish