debian-mirror-gitlab/spec/services/import/gitlab_projects/create_project_service_spec.rb
2022-05-07 20:08:51 +05:30

180 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