PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/services/projects/import_service_spec.rb

http://github.com/gitlabhq/gitlabhq
Ruby | 291 lines | 211 code | 79 blank | 1 comment | 0 complexity | 07fe4d32ab4b24fe8c05b884ccba3a23 MD5 | raw file
Possible License(s): CC-BY-SA-4.0, Apache-2.0, CC-BY-3.0, CC0-1.0, JSON
  1. # frozen_string_literal: true
  2. require 'spec_helper'
  3. describe Projects::ImportService do
  4. let!(:project) { create(:project) }
  5. let(:user) { project.creator }
  6. subject { described_class.new(project, user) }
  7. before do
  8. allow(project).to receive(:lfs_enabled?).and_return(true)
  9. end
  10. describe '#async?' do
  11. it 'returns true for an asynchronous importer' do
  12. importer_class = double(:importer, async?: true)
  13. allow(subject).to receive(:has_importer?).and_return(true)
  14. allow(subject).to receive(:importer_class).and_return(importer_class)
  15. expect(subject).to be_async
  16. end
  17. it 'returns false for a regular importer' do
  18. importer_class = double(:importer, async?: false)
  19. allow(subject).to receive(:has_importer?).and_return(true)
  20. allow(subject).to receive(:importer_class).and_return(importer_class)
  21. expect(subject).not_to be_async
  22. end
  23. it 'returns false when the importer does not define #async?' do
  24. importer_class = double(:importer)
  25. allow(subject).to receive(:has_importer?).and_return(true)
  26. allow(subject).to receive(:importer_class).and_return(importer_class)
  27. expect(subject).not_to be_async
  28. end
  29. it 'returns false when the importer does not exist' do
  30. allow(subject).to receive(:has_importer?).and_return(false)
  31. expect(subject).not_to be_async
  32. end
  33. end
  34. describe '#execute' do
  35. context 'with unknown url' do
  36. before do
  37. project.import_url = Project::UNKNOWN_IMPORT_URL
  38. end
  39. it 'succeeds if repository is created successfully' do
  40. expect(project).to receive(:create_repository).and_return(true)
  41. result = subject.execute
  42. expect(result[:status]).to eq :success
  43. end
  44. it 'fails if repository creation fails' do
  45. expect(project).to receive(:create_repository).and_return(false)
  46. result = subject.execute
  47. expect(result[:status]).to eq :error
  48. expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - The repository could not be created."
  49. end
  50. context 'when repository creation succeeds' do
  51. it 'does not download lfs files' do
  52. expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
  53. subject.execute
  54. end
  55. end
  56. end
  57. context 'with known url' do
  58. before do
  59. project.import_url = 'https://github.com/vim/vim.git'
  60. project.import_type = 'github'
  61. end
  62. context 'with a Github repository' do
  63. it 'succeeds if repository import was scheduled' do
  64. expect_any_instance_of(Gitlab::GithubImport::ParallelImporter)
  65. .to receive(:execute)
  66. .and_return(true)
  67. result = subject.execute
  68. expect(result[:status]).to eq :success
  69. end
  70. it 'fails if repository import was not scheduled' do
  71. expect_any_instance_of(Gitlab::GithubImport::ParallelImporter)
  72. .to receive(:execute)
  73. .and_return(false)
  74. result = subject.execute
  75. expect(result[:status]).to eq :error
  76. end
  77. context 'when repository import scheduled' do
  78. it 'does not download lfs objects' do
  79. expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
  80. subject.execute
  81. end
  82. end
  83. end
  84. context 'with a non Github repository' do
  85. before do
  86. project.import_url = 'https://bitbucket.org/vim/vim.git'
  87. project.import_type = 'bitbucket'
  88. end
  89. it 'succeeds if repository import is successful' do
  90. expect(project.repository).to receive(:import_repository).and_return(true)
  91. expect_next_instance_of(Gitlab::BitbucketImport::Importer) do |importer|
  92. expect(importer).to receive(:execute).and_return(true)
  93. end
  94. expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
  95. expect(service).to receive(:execute).and_return(status: :success)
  96. end
  97. result = subject.execute
  98. expect(result[:status]).to eq :success
  99. end
  100. it 'fails if repository import fails' do
  101. expect(project.repository)
  102. .to receive(:import_repository)
  103. .and_raise(Gitlab::Git::CommandError, 'Failed to import the repository /a/b/c')
  104. result = subject.execute
  105. expect(result[:status]).to eq :error
  106. expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository [FILTERED]"
  107. end
  108. context 'when lfs import fails' do
  109. it 'logs the error' do
  110. error_message = 'error message'
  111. expect(project.repository).to receive(:import_repository).and_return(true)
  112. expect_next_instance_of(Gitlab::BitbucketImport::Importer) do |importer|
  113. expect(importer).to receive(:execute).and_return(true)
  114. end
  115. expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service|
  116. expect(service).to receive(:execute).and_return(status: :error, message: error_message)
  117. end
  118. expect(Gitlab::AppLogger).to receive(:error).with("The Lfs import process failed. #{error_message}")
  119. subject.execute
  120. end
  121. end
  122. context 'when repository import scheduled' do
  123. before do
  124. expect(project.repository).to receive(:import_repository).and_return(true)
  125. allow(subject).to receive(:import_data)
  126. end
  127. it 'downloads lfs objects if lfs_enabled is enabled for project' do
  128. allow(project).to receive(:lfs_enabled?).and_return(true)
  129. expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute)
  130. subject.execute
  131. end
  132. it 'does not download lfs objects if lfs_enabled is not enabled for project' do
  133. allow(project).to receive(:lfs_enabled?).and_return(false)
  134. expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
  135. subject.execute
  136. end
  137. end
  138. end
  139. end
  140. context 'with valid importer' do
  141. before do
  142. stub_github_omniauth_provider
  143. project.import_url = 'https://github.com/vim/vim.git'
  144. project.import_type = 'github'
  145. allow(project).to receive(:import_data).and_return(double.as_null_object)
  146. end
  147. it 'succeeds if importer succeeds' do
  148. allow_any_instance_of(Gitlab::GithubImport::ParallelImporter)
  149. .to receive(:execute).and_return(true)
  150. result = subject.execute
  151. expect(result[:status]).to eq :success
  152. end
  153. it 'fails if importer fails' do
  154. allow_any_instance_of(Gitlab::GithubImport::ParallelImporter)
  155. .to receive(:execute)
  156. .and_return(false)
  157. result = subject.execute
  158. expect(result[:status]).to eq :error
  159. end
  160. context 'when importer' do
  161. it 'has a custom repository importer it does not download lfs objects' do
  162. allow(Gitlab::GithubImport::ParallelImporter).to receive(:imports_repository?).and_return(true)
  163. expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute)
  164. subject.execute
  165. end
  166. it 'does not have a custom repository importer downloads lfs objects' do
  167. allow(Gitlab::GithubImport::ParallelImporter).to receive(:imports_repository?).and_return(false)
  168. expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute)
  169. subject.execute
  170. end
  171. context 'when lfs import fails' do
  172. it 'logs the error' do
  173. error_message = 'error message'
  174. allow(Gitlab::GithubImport::ParallelImporter).to receive(:imports_repository?).and_return(false)
  175. expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute).and_return(status: :error, message: error_message)
  176. expect(Gitlab::AppLogger).to receive(:error).with("The Lfs import process failed. #{error_message}")
  177. subject.execute
  178. end
  179. end
  180. end
  181. end
  182. context 'with blocked import_URL' do
  183. it 'fails with localhost' do
  184. project.import_url = 'https://localhost:9000/vim/vim.git'
  185. result = described_class.new(project, user).execute
  186. expect(result[:status]).to eq :error
  187. expect(result[:message]).to include('Requests to localhost are not allowed')
  188. end
  189. it 'fails with port 25' do
  190. project.import_url = "https://github.com:25/vim/vim.git"
  191. result = described_class.new(project, user).execute
  192. expect(result[:status]).to eq :error
  193. expect(result[:message]).to include('Only allowed ports are 80, 443')
  194. end
  195. end
  196. def stub_github_omniauth_provider
  197. provider = OpenStruct.new(
  198. 'name' => 'github',
  199. 'app_id' => 'asd123',
  200. 'app_secret' => 'asd123',
  201. 'args' => {
  202. 'client_options' => {
  203. 'site' => 'https://github.com/api/v3',
  204. 'authorize_url' => 'https://github.com/login/oauth/authorize',
  205. 'token_url' => 'https://github.com/login/oauth/access_token'
  206. }
  207. }
  208. )
  209. stub_omniauth_setting(providers: [provider])
  210. end
  211. end
  212. end