Commit 0bd95086 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'id-create-forks-using-factories' into 'master'

Create project forks using factories

See merge request gitlab-org/gitlab!40351
parents 1d447319 0937de0c
...@@ -31,12 +31,12 @@ RSpec.describe Gitlab::Auth::GroupSaml::GmaMembershipEnforcer do ...@@ -31,12 +31,12 @@ RSpec.describe Gitlab::Auth::GroupSaml::GmaMembershipEnforcer do
end end
context 'when the project is forked' do context 'when the project is forked' do
subject { described_class.new(fork_project(project, managed_user_for_project)) }
before do before do
project.add_developer(managed_user_for_project) project.add_developer(managed_user_for_project)
end end
subject { described_class.new(fork_project(project, managed_user_for_project)) }
context 'when user is group-managed' do context 'when user is group-managed' do
it 'allows adding user to project' do it 'allows adding user to project' do
expect(subject.can_add_user?(managed_user)).to be_truthy expect(subject.can_add_user?(managed_user)).to be_truthy
...@@ -48,27 +48,26 @@ RSpec.describe Gitlab::Auth::GroupSaml::GmaMembershipEnforcer do ...@@ -48,27 +48,26 @@ RSpec.describe Gitlab::Auth::GroupSaml::GmaMembershipEnforcer do
expect(subject.can_add_user?(create(:user))).to be_falsey expect(subject.can_add_user?(create(:user))).to be_falsey
end end
end end
end
context 'when the project is forked from deleted project' do context 'from deleted project' do
let!(:forked_project) { fork_project(project, managed_user_for_project) } let!(:forked_project) { fork_project(project, managed_user_for_project) }
before do before do
project.add_developer(managed_user_for_project) project.delete
project.delete end
end
context 'when user is group-managed' do context 'when user is group-managed' do
it 'allows adding user to project' do it 'allows adding user to project' do
subject = described_class.new(forked_project) subject = described_class.new(forked_project)
expect(subject.can_add_user?(managed_user)).to be_truthy expect(subject.can_add_user?(managed_user)).to be_truthy
end
end end
end
context 'when user is not group-managed' do context 'when user is not group-managed' do
it 'does not allow adding user to project' do it 'does not allow adding user to project' do
subject = described_class.new(forked_project) subject = described_class.new(forked_project)
expect(subject.can_add_user?(create(:user))).to be_truthy expect(subject.can_add_user?(create(:user))).to be_truthy
end
end end
end end
end end
......
...@@ -159,7 +159,7 @@ RSpec.describe 'Project' do ...@@ -159,7 +159,7 @@ RSpec.describe 'Project' do
describe 'remove forked relationship', :js do describe 'remove forked relationship', :js do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { fork_project(create(:project, :public), user, namespace_id: user.namespace) } let(:project) { fork_project(create(:project, :public), user, namespace: user.namespace) }
before do before do
sign_in user sign_in user
......
...@@ -348,7 +348,7 @@ RSpec.describe Git::BranchHooksService do ...@@ -348,7 +348,7 @@ RSpec.describe Git::BranchHooksService do
context 'when the project is forked', :sidekiq_might_not_need_inline do context 'when the project is forked', :sidekiq_might_not_need_inline do
let(:upstream_project) { project } let(:upstream_project) { project }
let(:forked_project) { fork_project(upstream_project, user, repository: true) } let(:forked_project) { fork_project(upstream_project, user, repository: true, using_service: true) }
let!(:forked_service) do let!(:forked_service) do
described_class.new(forked_project, user, change: { oldrev: oldrev, newrev: newrev, ref: ref }) described_class.new(forked_project, user, change: { oldrev: oldrev, newrev: newrev, ref: ref })
......
...@@ -88,6 +88,10 @@ RSpec.describe MergeRequests::BuildService do ...@@ -88,6 +88,10 @@ RSpec.describe MergeRequests::BuildService do
let(:source_project) { fork_project(project, user) } let(:source_project) { fork_project(project, user) }
let(:merge_request) { described_class.new(project, user, mr_params).execute } let(:merge_request) { described_class.new(project, user, mr_params).execute }
before do
project.add_reporter(user)
end
it 'assigns force_remove_source_branch' do it 'assigns force_remove_source_branch' do
expect(merge_request.force_remove_source_branch?).to be_truthy expect(merge_request.force_remove_source_branch?).to be_truthy
end end
......
...@@ -9,7 +9,7 @@ RSpec.describe Projects::ForkService do ...@@ -9,7 +9,7 @@ RSpec.describe Projects::ForkService do
it 'flushes the forks count cache of the source project', :clean_gitlab_redis_cache do it 'flushes the forks count cache of the source project', :clean_gitlab_redis_cache do
expect(from_project.forks_count).to be_zero expect(from_project.forks_count).to be_zero
fork_project(from_project, to_user) fork_project(from_project, to_user, using_service: true)
BatchLoader::Executor.clear_current BatchLoader::Executor.clear_current
expect(from_project.forks_count).to eq(1) expect(from_project.forks_count).to eq(1)
...@@ -40,7 +40,7 @@ RSpec.describe Projects::ForkService do ...@@ -40,7 +40,7 @@ RSpec.describe Projects::ForkService do
@guest = create(:user) @guest = create(:user)
@from_project.add_user(@guest, :guest) @from_project.add_user(@guest, :guest)
end end
subject { fork_project(@from_project, @guest) } subject { fork_project(@from_project, @guest, using_service: true) }
it { is_expected.not_to be_persisted } it { is_expected.not_to be_persisted }
it { expect(subject.errors[:forked_from_project_id]).to eq(['is forbidden']) } it { expect(subject.errors[:forked_from_project_id]).to eq(['is forbidden']) }
...@@ -56,7 +56,7 @@ RSpec.describe Projects::ForkService do ...@@ -56,7 +56,7 @@ RSpec.describe Projects::ForkService do
end end
describe "successfully creates project in the user namespace" do describe "successfully creates project in the user namespace" do
let(:to_project) { fork_project(@from_project, @to_user, namespace: @to_user.namespace) } let(:to_project) { fork_project(@from_project, @to_user, namespace: @to_user.namespace, using_service: true) }
it { expect(to_project).to be_persisted } it { expect(to_project).to be_persisted }
it { expect(to_project.errors).to be_empty } it { expect(to_project.errors).to be_empty }
...@@ -92,21 +92,21 @@ RSpec.describe Projects::ForkService do ...@@ -92,21 +92,21 @@ RSpec.describe Projects::ForkService do
end end
it 'imports the repository of the forked project', :sidekiq_might_not_need_inline do it 'imports the repository of the forked project', :sidekiq_might_not_need_inline do
to_project = fork_project(@from_project, @to_user, repository: true) to_project = fork_project(@from_project, @to_user, repository: true, using_service: true)
expect(to_project.empty_repo?).to be_falsy expect(to_project.empty_repo?).to be_falsy
end end
end end
context 'creating a fork of a fork' do context 'creating a fork of a fork' do
let(:from_forked_project) { fork_project(@from_project, @to_user) } let(:from_forked_project) { fork_project(@from_project, @to_user, using_service: true) }
let(:other_namespace) do let(:other_namespace) do
group = create(:group) group = create(:group)
group.add_owner(@to_user) group.add_owner(@to_user)
group group
end end
let(:to_project) { fork_project(from_forked_project, @to_user, namespace: other_namespace) } let(:to_project) { fork_project(from_forked_project, @to_user, namespace: other_namespace, using_service: true) }
it 'sets the root of the network to the root project' do it 'sets the root of the network to the root project' do
expect(to_project.fork_network.root_project).to eq(@from_project) expect(to_project.fork_network.root_project).to eq(@from_project)
...@@ -126,7 +126,7 @@ RSpec.describe Projects::ForkService do ...@@ -126,7 +126,7 @@ RSpec.describe Projects::ForkService do
context 'project already exists' do context 'project already exists' do
it "fails due to validation, not transaction failure" do it "fails due to validation, not transaction failure" do
@existing_project = create(:project, :repository, creator_id: @to_user.id, name: @from_project.name, namespace: @to_namespace) @existing_project = create(:project, :repository, creator_id: @to_user.id, name: @from_project.name, namespace: @to_namespace)
@to_project = fork_project(@from_project, @to_user, namespace: @to_namespace) @to_project = fork_project(@from_project, @to_user, namespace: @to_namespace, using_service: true)
expect(@existing_project).to be_persisted expect(@existing_project).to be_persisted
expect(@to_project).not_to be_persisted expect(@to_project).not_to be_persisted
...@@ -137,7 +137,7 @@ RSpec.describe Projects::ForkService do ...@@ -137,7 +137,7 @@ RSpec.describe Projects::ForkService do
context 'repository in legacy storage already exists' do context 'repository in legacy storage already exists' do
let(:fake_repo_path) { File.join(TestEnv.repos_path, @to_user.namespace.full_path, "#{@from_project.path}.git") } let(:fake_repo_path) { File.join(TestEnv.repos_path, @to_user.namespace.full_path, "#{@from_project.path}.git") }
let(:params) { { namespace: @to_user.namespace } } let(:params) { { namespace: @to_user.namespace, using_service: true } }
before do before do
stub_application_setting(hashed_storage_enabled: false) stub_application_setting(hashed_storage_enabled: false)
...@@ -169,13 +169,13 @@ RSpec.describe Projects::ForkService do ...@@ -169,13 +169,13 @@ RSpec.describe Projects::ForkService do
context 'GitLab CI is enabled' do context 'GitLab CI is enabled' do
it "forks and enables CI for fork" do it "forks and enables CI for fork" do
@from_project.enable_ci @from_project.enable_ci
@to_project = fork_project(@from_project, @to_user) @to_project = fork_project(@from_project, @to_user, using_service: true)
expect(@to_project.builds_enabled?).to be_truthy expect(@to_project.builds_enabled?).to be_truthy
end end
end end
context "CI/CD settings" do context "CI/CD settings" do
let(:to_project) { fork_project(@from_project, @to_user) } let(:to_project) { fork_project(@from_project, @to_user, using_service: true) }
context "when origin has git depth specified" do context "when origin has git depth specified" do
before do before do
...@@ -206,7 +206,7 @@ RSpec.describe Projects::ForkService do ...@@ -206,7 +206,7 @@ RSpec.describe Projects::ForkService do
end end
it "creates fork with lowest level" do it "creates fork with lowest level" do
forked_project = fork_project(@from_project, @to_user) forked_project = fork_project(@from_project, @to_user, using_service: true)
expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
end end
...@@ -218,7 +218,7 @@ RSpec.describe Projects::ForkService do ...@@ -218,7 +218,7 @@ RSpec.describe Projects::ForkService do
end end
it "creates fork with private visibility levels" do it "creates fork with private visibility levels" do
forked_project = fork_project(@from_project, @to_user) forked_project = fork_project(@from_project, @to_user, using_service: true)
expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
end end
...@@ -232,7 +232,7 @@ RSpec.describe Projects::ForkService do ...@@ -232,7 +232,7 @@ RSpec.describe Projects::ForkService do
end end
it 'fails' do it 'fails' do
to_project = fork_project(@from_project, @to_user, namespace: @to_user.namespace) to_project = fork_project(@from_project, @to_user, namespace: @to_user.namespace, using_service: true)
expect(to_project.errors[:forked_from_project_id]).to eq(['is forbidden']) expect(to_project.errors[:forked_from_project_id]).to eq(['is forbidden'])
end end
...@@ -253,7 +253,7 @@ RSpec.describe Projects::ForkService do ...@@ -253,7 +253,7 @@ RSpec.describe Projects::ForkService do
@group.add_user(@developer, GroupMember::DEVELOPER) @group.add_user(@developer, GroupMember::DEVELOPER)
@project.add_user(@developer, :developer) @project.add_user(@developer, :developer)
@project.add_user(@group_owner, :developer) @project.add_user(@group_owner, :developer)
@opts = { namespace: @group } @opts = { namespace: @group, using_service: true }
end end
context 'fork project for group' do context 'fork project for group' do
...@@ -299,7 +299,7 @@ RSpec.describe Projects::ForkService do ...@@ -299,7 +299,7 @@ RSpec.describe Projects::ForkService do
group_owner = create(:user) group_owner = create(:user)
private_group.add_owner(group_owner) private_group.add_owner(group_owner)
forked_project = fork_project(public_project, group_owner, namespace: private_group) forked_project = fork_project(public_project, group_owner, namespace: private_group, using_service: true)
expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
end end
...@@ -310,7 +310,7 @@ RSpec.describe Projects::ForkService do ...@@ -310,7 +310,7 @@ RSpec.describe Projects::ForkService do
context 'when a project is already forked' do context 'when a project is already forked' do
it 'creates a new poolresository after the project is moved to a new shard' do it 'creates a new poolresository after the project is moved to a new shard' do
project = create(:project, :public, :repository) project = create(:project, :public, :repository)
fork_before_move = fork_project(project) fork_before_move = fork_project(project, nil, using_service: true)
# Stub everything required to move a project to a Gitaly shard that does not exist # Stub everything required to move a project to a Gitaly shard that does not exist
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original
...@@ -329,7 +329,7 @@ RSpec.describe Projects::ForkService do ...@@ -329,7 +329,7 @@ RSpec.describe Projects::ForkService do
destination_storage_name: 'test_second_storage' destination_storage_name: 'test_second_storage'
) )
Projects::UpdateRepositoryStorageService.new(storage_move).execute Projects::UpdateRepositoryStorageService.new(storage_move).execute
fork_after_move = fork_project(project.reload) fork_after_move = fork_project(project.reload, nil, using_service: true)
pool_repository_before_move = PoolRepository.joins(:shard) pool_repository_before_move = PoolRepository.joins(:shard)
.find_by(source_project: project, shards: { name: 'default' }) .find_by(source_project: project, shards: { name: 'default' })
pool_repository_after_move = PoolRepository.joins(:shard) pool_repository_after_move = PoolRepository.joins(:shard)
...@@ -350,7 +350,7 @@ RSpec.describe Projects::ForkService do ...@@ -350,7 +350,7 @@ RSpec.describe Projects::ForkService do
context 'when no pool exists' do context 'when no pool exists' do
it 'creates a new object pool' do it 'creates a new object pool' do
forked_project = fork_project(fork_from_project, forker) forked_project = fork_project(fork_from_project, forker, using_service: true)
expect(forked_project.pool_repository).to eq(fork_from_project.pool_repository) expect(forked_project.pool_repository).to eq(fork_from_project.pool_repository)
end end
...@@ -360,7 +360,7 @@ RSpec.describe Projects::ForkService do ...@@ -360,7 +360,7 @@ RSpec.describe Projects::ForkService do
let!(:pool_repository) { create(:pool_repository, source_project: fork_from_project) } let!(:pool_repository) { create(:pool_repository, source_project: fork_from_project) }
it 'joins the object pool' do it 'joins the object pool' do
forked_project = fork_project(fork_from_project, forker) forked_project = fork_project(fork_from_project, forker, using_service: true)
expect(forked_project.pool_repository).to eq(fork_from_project.pool_repository) expect(forked_project.pool_repository).to eq(fork_from_project.pool_repository)
end end
......
...@@ -17,14 +17,26 @@ module ProjectForksHelper ...@@ -17,14 +17,26 @@ module ProjectForksHelper
project.add_developer(user) project.add_developer(user)
end end
unless params[:namespace] || params[:namespace_id] unless params[:namespace]
params[:namespace] = create(:group) params[:namespace] = create(:group)
params[:namespace].add_owner(user) params[:namespace].add_owner(user)
end end
namespace = params[:namespace]
create_repository = params.delete(:repository)
unless params[:target_project] || params[:using_service]
target_level = [project.visibility_level, namespace.visibility_level].min
visibility_level = Gitlab::VisibilityLevel.closest_allowed_level(target_level)
params[:target_project] =
create(:project,
(:repository if create_repository),
visibility_level: visibility_level, creator: user, namespace: namespace)
end
service = Projects::ForkService.new(project, user, params) service = Projects::ForkService.new(project, user, params)
create_repository = params.delete(:repository)
# Avoid creating a repository # Avoid creating a repository
unless create_repository unless create_repository
allow(RepositoryForkWorker).to receive(:perform_async).and_return(true) allow(RepositoryForkWorker).to receive(:perform_async).and_return(true)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment