summaryrefslogtreecommitdiff
path: root/spec/services/import/gitlab_projects/create_project_service_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/import/gitlab_projects/create_project_service_spec.rb')
-rw-r--r--spec/services/import/gitlab_projects/create_project_service_spec.rb179
1 files changed, 179 insertions, 0 deletions
diff --git a/spec/services/import/gitlab_projects/create_project_service_spec.rb b/spec/services/import/gitlab_projects/create_project_service_spec.rb
new file mode 100644
index 00000000000..0da897448b8
--- /dev/null
+++ b/spec/services/import/gitlab_projects/create_project_service_spec.rb
@@ -0,0 +1,179 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Import::GitlabProjects::CreateProjectService, :aggregate_failures do
+ let(:fake_file_acquisition_strategy) do
+ Class.new do
+ attr_reader :errors
+
+ def initialize(...)
+ @errors = ActiveModel::Errors.new(self)
+ end
+
+ def valid?
+ true
+ end
+
+ def project_params
+ {}
+ end
+ end
+ end
+
+ let(:params) do
+ {
+ path: 'path',
+ namespace: user.namespace,
+ name: 'name'
+ }
+ end
+
+ let_it_be(:user) { create(:user) }
+
+ subject { described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy) }
+
+ before do
+ stub_const('FakeStrategy', fake_file_acquisition_strategy)
+ end
+
+ describe 'validation' do
+ it { expect(subject).to be_valid }
+
+ it 'validates presence of path' do
+ params[:path] = nil
+
+ invalid = described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy)
+
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("Path can't be blank")
+ end
+
+ it 'validates presence of name' do
+ params[:namespace] = nil
+
+ invalid = described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy)
+
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("Namespace can't be blank")
+ end
+
+ it 'is invalid if the strategy is invalid' do
+ expect_next_instance_of(FakeStrategy) do |strategy|
+ allow(strategy).to receive(:valid?).and_return(false)
+ allow(strategy).to receive(:errors).and_wrap_original do |original|
+ original.call.tap do |errors|
+ errors.add(:base, "some error")
+ end
+ end
+ end
+
+ invalid = described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy)
+
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("some error")
+ expect(invalid.errors.full_messages).to include("some error")
+ end
+ end
+
+ describe '#execute' do
+ it 'creates a project successfully' do
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(1)
+
+ expect(response).to be_success
+ expect(response.http_status).to eq(:ok)
+ expect(response.payload).to be_instance_of(Project)
+ expect(response.payload.name).to eq('name')
+ expect(response.payload.path).to eq('path')
+ expect(response.payload.namespace).to eq(user.namespace)
+
+ project = Project.last
+ expect(project.name).to eq('name')
+ expect(project.path).to eq('path')
+ expect(project.namespace_id).to eq(user.namespace.id)
+ expect(project.import_type).to eq('gitlab_project')
+ end
+
+ context 'when the project creation raises an error' do
+ it 'fails to create a project' do
+ expect_next_instance_of(Projects::GitlabProjectsImportService) do |service|
+ expect(service).to receive(:execute).and_raise(StandardError, "failed to create project")
+ end
+
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(0)
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:bad_request)
+ expect(response.message).to eq("failed to create project")
+ expect(response.payload).to eq(other_errors: [])
+ end
+ end
+
+ context 'when the validation fail' do
+ it 'fails to create a project' do
+ params.delete(:path)
+
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(0)
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:bad_request)
+ expect(response.message).to eq("Path can't be blank")
+ expect(response.payload).to eq(other_errors: [])
+ end
+
+ context 'when the project contains multilple errors' do
+ it 'fails to create a project' do
+ params.merge!(name: '_ an invalid name _', path: '_ an invalid path _')
+
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(0)
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:bad_request)
+ expect(response.message)
+ .to eq(%{Project namespace path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'})
+ expect(response.payload).to eq(other_errors: [
+ %{Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'},
+ %{Path must not start or end with a special character and must not contain consecutive special characters.}
+ ])
+ end
+ end
+ end
+
+ context 'when the strategy adds project parameters' do
+ before do
+ expect_next_instance_of(FakeStrategy) do |strategy|
+ expect(strategy).to receive(:project_params).and_return(name: 'the strategy name')
+ end
+
+ subject.valid?
+ end
+
+ it 'merges the strategy project parameters' do
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(1)
+
+ expect(response).to be_success
+ expect(response.http_status).to eq(:ok)
+ expect(response.payload).to be_instance_of(Project)
+ expect(response.payload.name).to eq('the strategy name')
+ expect(response.payload.path).to eq('path')
+ expect(response.payload.namespace).to eq(user.namespace)
+
+ project = Project.last
+ expect(project.name).to eq('the strategy name')
+ expect(project.path).to eq('path')
+ expect(project.namespace_id).to eq(user.namespace.id)
+ expect(project.import_type).to eq('gitlab_project')
+ end
+ end
+ end
+end