2016-01-21 18:09:32 +00:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2017-07-10 14:24:02 +00:00
|
|
|
describe Projects::ImportService do
|
2017-08-02 19:55:11 +00:00
|
|
|
let!(:project) { create(:project) }
|
2016-01-21 18:09:32 +00:00
|
|
|
let(:user) { project.creator }
|
2018-06-06 16:42:18 +00:00
|
|
|
let(:import_url) { 'http://www.gitlab.com/demo/repo.git' }
|
|
|
|
let(:oid_download_links) { { 'oid1' => "#{import_url}/gitlab-lfs/objects/oid1", 'oid2' => "#{import_url}/gitlab-lfs/objects/oid2" } }
|
2016-01-21 18:09:32 +00:00
|
|
|
|
|
|
|
subject { described_class.new(project, user) }
|
|
|
|
|
2018-06-06 16:42:18 +00:00
|
|
|
before do
|
|
|
|
allow(project).to receive(:lfs_enabled?).and_return(true)
|
|
|
|
allow_any_instance_of(Projects::LfsPointers::LfsDownloadService).to receive(:execute)
|
|
|
|
allow_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute).and_return(oid_download_links)
|
|
|
|
end
|
|
|
|
|
2017-10-13 16:50:36 +00:00
|
|
|
describe '#async?' do
|
|
|
|
it 'returns true for an asynchronous importer' do
|
|
|
|
importer_class = double(:importer, async?: true)
|
|
|
|
|
|
|
|
allow(subject).to receive(:has_importer?).and_return(true)
|
|
|
|
allow(subject).to receive(:importer_class).and_return(importer_class)
|
|
|
|
|
|
|
|
expect(subject).to be_async
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false for a regular importer' do
|
|
|
|
importer_class = double(:importer, async?: false)
|
|
|
|
|
|
|
|
allow(subject).to receive(:has_importer?).and_return(true)
|
|
|
|
allow(subject).to receive(:importer_class).and_return(importer_class)
|
|
|
|
|
|
|
|
expect(subject).not_to be_async
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false when the importer does not define #async?' do
|
|
|
|
importer_class = double(:importer)
|
|
|
|
|
|
|
|
allow(subject).to receive(:has_importer?).and_return(true)
|
|
|
|
allow(subject).to receive(:importer_class).and_return(importer_class)
|
|
|
|
|
|
|
|
expect(subject).not_to be_async
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false when the importer does not exist' do
|
|
|
|
allow(subject).to receive(:has_importer?).and_return(false)
|
|
|
|
|
|
|
|
expect(subject).not_to be_async
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-01-21 18:09:32 +00:00
|
|
|
describe '#execute' do
|
|
|
|
context 'with unknown url' do
|
|
|
|
before do
|
|
|
|
project.import_url = Project::UNKNOWN_IMPORT_URL
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'succeeds if repository is created successfully' do
|
|
|
|
expect(project).to receive(:create_repository).and_return(true)
|
|
|
|
|
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :success
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fails if repository creation fails' do
|
|
|
|
expect(project).to receive(:create_repository).and_return(false)
|
|
|
|
|
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :error
|
2018-07-16 10:17:42 +00:00
|
|
|
expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - The repository could not be created."
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
2018-06-06 16:42:18 +00:00
|
|
|
|
|
|
|
context 'when repository creation succeeds' do
|
|
|
|
it 'does not download lfs files' do
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsDownloadService).not_to receive(:execute)
|
|
|
|
|
|
|
|
subject.execute
|
|
|
|
end
|
|
|
|
end
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'with known url' do
|
|
|
|
before do
|
|
|
|
project.import_url = 'https://github.com/vim/vim.git'
|
2017-04-03 18:48:09 +00:00
|
|
|
project.import_type = 'github'
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
|
|
|
|
2017-04-03 18:48:09 +00:00
|
|
|
context 'with a Github repository' do
|
2017-10-18 19:46:05 +00:00
|
|
|
it 'succeeds if repository import was scheduled' do
|
|
|
|
expect_any_instance_of(Gitlab::GithubImport::ParallelImporter)
|
|
|
|
.to receive(:execute)
|
|
|
|
.and_return(true)
|
2016-01-21 18:09:32 +00:00
|
|
|
|
2017-04-03 18:48:09 +00:00
|
|
|
result = subject.execute
|
2016-01-21 18:09:32 +00:00
|
|
|
|
2017-04-03 18:48:09 +00:00
|
|
|
expect(result[:status]).to eq :success
|
|
|
|
end
|
|
|
|
|
2017-10-18 19:46:05 +00:00
|
|
|
it 'fails if repository import was not scheduled' do
|
|
|
|
expect_any_instance_of(Gitlab::GithubImport::ParallelImporter)
|
|
|
|
.to receive(:execute)
|
|
|
|
.and_return(false)
|
2017-04-03 18:48:09 +00:00
|
|
|
|
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :error
|
2017-04-18 00:22:33 +00:00
|
|
|
end
|
2018-06-06 16:42:18 +00:00
|
|
|
|
|
|
|
context 'when repository import scheduled' do
|
|
|
|
it 'does not download lfs objects' do
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsDownloadService).not_to receive(:execute)
|
|
|
|
|
|
|
|
subject.execute
|
|
|
|
end
|
|
|
|
end
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
|
|
|
|
2017-04-03 18:48:09 +00:00
|
|
|
context 'with a non Github repository' do
|
|
|
|
before do
|
|
|
|
project.import_url = 'https://bitbucket.org/vim/vim.git'
|
|
|
|
project.import_type = 'bitbucket'
|
|
|
|
end
|
2016-01-21 18:09:32 +00:00
|
|
|
|
2018-06-06 16:42:18 +00:00
|
|
|
it 'succeeds if repository import is successfull' do
|
2017-04-03 18:48:09 +00:00
|
|
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).and_return(true)
|
|
|
|
expect_any_instance_of(Gitlab::BitbucketImport::Importer).to receive(:execute).and_return(true)
|
2018-06-06 16:42:18 +00:00
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute).and_return({})
|
2016-01-21 18:09:32 +00:00
|
|
|
|
2017-04-03 18:48:09 +00:00
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :success
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fails if repository import fails' do
|
|
|
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).and_raise(Gitlab::Shell::Error.new('Failed to import the repository'))
|
|
|
|
|
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :error
|
2018-07-16 10:17:42 +00:00
|
|
|
expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository"
|
2017-04-03 18:48:09 +00:00
|
|
|
end
|
2018-06-06 16:42:18 +00:00
|
|
|
|
|
|
|
context 'when repository import scheduled' do
|
|
|
|
before do
|
|
|
|
allow_any_instance_of(Gitlab::Shell).to receive(:import_repository).and_return(true)
|
|
|
|
allow(subject).to receive(:import_data)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'downloads lfs objects if lfs_enabled is enabled for project' do
|
|
|
|
allow(project).to receive(:lfs_enabled?).and_return(true)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute).and_return(oid_download_links)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsDownloadService).to receive(:execute).twice
|
|
|
|
|
|
|
|
subject.execute
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not download lfs objects if lfs_enabled is not enabled for project' do
|
|
|
|
allow(project).to receive(:lfs_enabled?).and_return(false)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsDownloadService).not_to receive(:execute)
|
|
|
|
|
|
|
|
subject.execute
|
|
|
|
end
|
|
|
|
end
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with valid importer' do
|
|
|
|
before do
|
|
|
|
stub_github_omniauth_provider
|
|
|
|
|
|
|
|
project.import_url = 'https://github.com/vim/vim.git'
|
|
|
|
project.import_type = 'github'
|
|
|
|
|
|
|
|
allow(project).to receive(:import_data).and_return(double.as_null_object)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'succeeds if importer succeeds' do
|
2017-10-18 19:46:05 +00:00
|
|
|
allow_any_instance_of(Gitlab::GithubImport::ParallelImporter)
|
|
|
|
.to receive(:execute).and_return(true)
|
2016-01-21 18:09:32 +00:00
|
|
|
|
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :success
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fails if importer fails' do
|
2017-10-18 19:46:05 +00:00
|
|
|
allow_any_instance_of(Gitlab::GithubImport::ParallelImporter)
|
|
|
|
.to receive(:execute)
|
|
|
|
.and_return(false)
|
2016-01-21 18:09:32 +00:00
|
|
|
|
|
|
|
result = subject.execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :error
|
2016-09-23 07:42:07 +00:00
|
|
|
end
|
2018-06-06 16:42:18 +00:00
|
|
|
|
|
|
|
context 'when importer' do
|
|
|
|
it 'has a custom repository importer it does not download lfs objects' do
|
|
|
|
allow(Gitlab::GithubImport::ParallelImporter).to receive(:imports_repository?).and_return(true)
|
|
|
|
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsDownloadService).not_to receive(:execute)
|
|
|
|
|
|
|
|
subject.execute
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not have a custom repository importer downloads lfs objects' do
|
|
|
|
allow(Gitlab::GithubImport::ParallelImporter).to receive(:imports_repository?).and_return(false)
|
|
|
|
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute).and_return(oid_download_links)
|
|
|
|
expect_any_instance_of(Projects::LfsPointers::LfsDownloadService).to receive(:execute)
|
|
|
|
|
|
|
|
subject.execute
|
|
|
|
end
|
|
|
|
end
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
|
|
|
|
2017-03-15 20:09:08 +00:00
|
|
|
context 'with blocked import_URL' do
|
|
|
|
it 'fails with localhost' do
|
|
|
|
project.import_url = 'https://localhost:9000/vim/vim.git'
|
|
|
|
|
|
|
|
result = described_class.new(project, user).execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :error
|
2018-04-02 15:13:23 +00:00
|
|
|
expect(result[:message]).to include('Requests to localhost are not allowed')
|
2017-03-15 20:09:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'fails with port 25' do
|
|
|
|
project.import_url = "https://github.com:25/vim/vim.git"
|
|
|
|
|
|
|
|
result = described_class.new(project, user).execute
|
|
|
|
|
|
|
|
expect(result[:status]).to eq :error
|
2018-04-02 15:13:23 +00:00
|
|
|
expect(result[:message]).to include('Only allowed ports are 22, 80, 443')
|
2017-03-15 20:09:08 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-01-21 18:09:32 +00:00
|
|
|
def stub_github_omniauth_provider
|
|
|
|
provider = OpenStruct.new(
|
2016-04-22 19:43:10 +00:00
|
|
|
'name' => 'github',
|
|
|
|
'app_id' => 'asd123',
|
|
|
|
'app_secret' => 'asd123',
|
|
|
|
'args' => {
|
|
|
|
'client_options' => {
|
|
|
|
'site' => 'https://github.com/api/v3',
|
|
|
|
'authorize_url' => 'https://github.com/login/oauth/authorize',
|
|
|
|
'token_url' => 'https://github.com/login/oauth/access_token'
|
|
|
|
}
|
|
|
|
}
|
2016-01-21 18:09:32 +00:00
|
|
|
)
|
|
|
|
|
2017-03-23 13:49:59 +00:00
|
|
|
stub_omniauth_setting(providers: [provider])
|
2016-01-21 18:09:32 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|