Commit 8c062bbb authored by Vitali Tatarintev's avatar Vitali Tatarintev

Merge branch '346042-refactor-create-service' into 'master'

Refactor WorkItems::CreateService

See merge request gitlab-org/gitlab!80309
parents bd90f71f 4b787b6d
...@@ -32,13 +32,13 @@ module Mutations ...@@ -32,13 +32,13 @@ module Mutations
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id) params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request]) spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
work_item = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute create_result = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
check_spam_action_response!(work_item) check_spam_action_response!(create_result[:work_item]) if create_result[:work_item]
{ {
work_item: work_item.valid? ? work_item : nil, work_item: create_result.success? ? create_result[:work_item] : nil,
errors: errors_on_object(work_item) errors: create_result.errors
} }
end end
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
module WorkItems module WorkItems
class CreateService class CreateService
include ::Services::ReturnServiceResponses
def initialize(project:, current_user: nil, params: {}, spam_params:) def initialize(project:, current_user: nil, params: {}, spam_params:)
@create_service = ::Issues::CreateService.new( @create_service = ::Issues::CreateService.new(
project: project, project: project,
...@@ -10,10 +12,28 @@ module WorkItems ...@@ -10,10 +12,28 @@ module WorkItems
spam_params: spam_params, spam_params: spam_params,
build_service: ::WorkItems::BuildService.new(project: project, current_user: current_user, params: params) build_service: ::WorkItems::BuildService.new(project: project, current_user: current_user, params: params)
) )
@current_user = current_user
@project = project
end end
def execute def execute
@create_service.execute unless @current_user.can?(:create_work_item, @project)
return error(_('Operation not allowed'), :forbidden)
end
work_item = @create_service.execute
if work_item.valid?
success(payload(work_item))
else
error(work_item.errors.full_messages, :unprocessable_entity, pass_back: payload(work_item))
end
end
private
def payload(work_item)
{ work_item: work_item }
end end
end end
end end
...@@ -47,6 +47,18 @@ RSpec.describe 'Create a work item' do ...@@ -47,6 +47,18 @@ RSpec.describe 'Create a work item' do
) )
end end
context 'when input is invalid' do
let(:input) { { 'title' => '', 'workItemTypeId' => WorkItems::Type.default_by_type(:task).to_global_id.to_s } }
it 'does not create and returns validation errors' do
expect do
post_graphql_mutation(mutation, current_user: current_user)
end.to not_change(WorkItem, :count)
expect(graphql_mutation_response(:work_item_create)['errors']).to contain_exactly("Title can't be blank")
end
end
it_behaves_like 'has spam protection' do it_behaves_like 'has spam protection' do
let(:mutation_class) { ::Mutations::WorkItems::Create } let(:mutation_class) { ::Mutations::WorkItems::Create }
end end
......
...@@ -5,34 +5,46 @@ require 'spec_helper' ...@@ -5,34 +5,46 @@ require 'spec_helper'
RSpec.describe WorkItems::CreateService do RSpec.describe WorkItems::CreateService do
include AfterNextHelpers include AfterNextHelpers
let_it_be(:group) { create(:group) } let_it_be_with_reload(:project) { create(:project) }
let_it_be_with_reload(:project) { create(:project, group: group) } let_it_be(:guest) { create(:user) }
let_it_be(:user) { create(:user) } let_it_be(:user_with_no_access) { create(:user) }
let(:spam_params) { double } let(:spam_params) { double }
let(:current_user) { guest }
let(:opts) do
{
title: 'Awesome work_item',
description: 'please fix'
}
end
before_all do
project.add_guest(guest)
end
describe '#execute' do describe '#execute' do
let(:work_item) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute } subject(:service_result) { described_class.new(project: project, current_user: current_user, params: opts, spam_params: spam_params).execute }
before do before do
stub_spam_services stub_spam_services
end end
context 'when params are valid' do context 'when user is not allowed to create a work item in the project' do
before_all do let(:current_user) { user_with_no_access }
project.add_guest(user)
end it { is_expected.to be_error }
let(:opts) do it 'returns an access error' do
{ expect(service_result.errors).to contain_exactly('Operation not allowed')
title: 'Awesome work_item',
description: 'please fix'
}
end end
end
context 'when params are valid' do
it 'created instance is a WorkItem' do it 'created instance is a WorkItem' do
expect(Issuable::CommonSystemNotesService).to receive_message_chain(:new, :execute) expect(Issuable::CommonSystemNotesService).to receive_message_chain(:new, :execute)
work_item = service_result[:work_item]
expect(work_item).to be_persisted expect(work_item).to be_persisted
expect(work_item).to be_a(::WorkItem) expect(work_item).to be_a(::WorkItem)
expect(work_item.title).to eq('Awesome work_item') expect(work_item.title).to eq('Awesome work_item')
...@@ -41,17 +53,17 @@ RSpec.describe WorkItems::CreateService do ...@@ -41,17 +53,17 @@ RSpec.describe WorkItems::CreateService do
end end
end end
context 'checking spam' do context 'when params are invalid' do
let(:params) do let(:opts) { { title: '' } }
{
title: 'Spam work_item'
}
end
subject do it { is_expected.to be_error }
described_class.new(project: project, current_user: user, params: params, spam_params: spam_params)
it 'returns validation errors' do
expect(service_result.errors).to contain_exactly("Title can't be blank")
end end
end
context 'checking spam' do
it 'executes SpamActionService' do it 'executes SpamActionService' do
expect_next_instance_of( expect_next_instance_of(
Spam::SpamActionService, Spam::SpamActionService,
...@@ -65,7 +77,7 @@ RSpec.describe WorkItems::CreateService do ...@@ -65,7 +77,7 @@ RSpec.describe WorkItems::CreateService do
expect(instance).to receive(:execute) expect(instance).to receive(:execute)
end end
subject.execute service_result
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment