179 lines
5.7 KiB
Ruby
179 lines
5.7 KiB
Ruby
# 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
|