Commit d0ccbb2e authored by Jan Provaznik's avatar Jan Provaznik Committed by charlie ablett

Reuse scope board mutation logic for epic boards

Label arguments and related logic (arguments validation) is needed
for epic boards too, so these arguments are moved to
ScopedBoardMutation and issue-specific arguments are renamed left in
ScopedIssueBoardArguments.
parent 8df02215
......@@ -22,7 +22,7 @@ module Mutations
response = ::Boards::CreateService.new(board_parent, current_user, args).execute
{
board: response.payload,
board: response.success? ? response.payload : nil,
errors: response.errors
}
end
......
---
title: Fixed error handling GraphQL API when issue board creation fails
merge_request: 55982
author:
type: fixed
......@@ -5,10 +5,10 @@ module EE
module Boards
module Create
extend ActiveSupport::Concern
prepend ::Mutations::Boards::ScopedBoardMutation
prepended do
include Mutations::Boards::ScopedBoardArguments
prepend ::Mutations::Boards::ScopedIssueBoardArguments
prepend ::Mutations::Boards::ScopedBoardMutation
end
end
end
......
# frozen_string_literal: true
module EE
module Mutations
module Boards
module ScopedBoardArguments
extend ActiveSupport::Concern
included do
argument :assignee_id,
::Types::GlobalIDType[::User],
required: false,
description: 'The ID of user to be assigned to the board.'
# Cannot pre-load ::Types::MilestoneType because we are also assigning values like:
# ::Timebox::None(0), ::Timebox::Upcoming(-2) or ::Timebox::Started(-3), that cannot be resolved to a DB record.
argument :milestone_id,
::Types::GlobalIDType[::Milestone],
required: false,
description: 'The ID of milestone to be assigned to the board.'
# Cannot pre-load ::Types::IterationType because we are also assigning values like:
# ::Iteration::Predefined::None(0) or ::Iteration::Predefined::Current(-4), that cannot be resolved to a DB record.
argument :iteration_id,
::Types::GlobalIDType[::Iteration],
required: false,
description: 'The ID of iteration to be assigned to the board.'
argument :weight,
GraphQL::INT_TYPE,
required: false,
description: 'The weight value to be assigned to the board.'
argument :labels, [GraphQL::STRING_TYPE],
required: false,
description: copy_field_description(::Types::IssueType, :labels)
argument :label_ids, [::Types::GlobalIDType[::Label]],
required: false,
description: 'The IDs of labels to be added to the board.'
end
end
end
end
end
......@@ -5,10 +5,10 @@ module EE
module Boards
module Update
extend ActiveSupport::Concern
prepend ::Mutations::Boards::ScopedBoardMutation
prepended do
include Mutations::Boards::ScopedBoardArguments
prepend ::Mutations::Boards::ScopedIssueBoardArguments
prepend ::Mutations::Boards::ScopedBoardMutation
end
end
end
......
......@@ -6,6 +6,7 @@ module Mutations
class Create < ::Mutations::BaseMutation
include Mutations::ResolvesGroup
include Mutations::Boards::CommonMutationArguments
prepend Mutations::Boards::ScopedBoardMutation
graphql_name 'EpicBoardCreate'
......@@ -27,7 +28,7 @@ module Mutations
service_response = ::Boards::EpicBoards::CreateService.new(group, current_user, args).execute
{
epic_board: service_response.payload,
epic_board: service_response.success? ? service_response.payload : nil,
errors: service_response.errors
}
end
......
......@@ -16,14 +16,6 @@ module Mutations
required: true,
description: 'The epic board global ID.'
argument :labels, [GraphQL::STRING_TYPE],
required: false,
description: 'Labels to be added to the board.'
argument :label_ids, [::Types::GlobalIDType[::Label]],
required: false,
description: 'The IDs of labels to be added to the board.'
field :epic_board,
Types::Boards::EpicBoardType,
null: true,
......
......@@ -5,6 +5,16 @@ module Mutations
module ScopedBoardMutation
extend ActiveSupport::Concern
prepended do
argument :labels, [GraphQL::STRING_TYPE],
required: false,
description: copy_field_description(::Types::IssueType, :labels)
argument :label_ids, [::Types::GlobalIDType[::Label]],
required: false,
description: 'IDs of labels to be added to the board.'
end
def resolve(**args)
parsed_params = parse_arguments(args)
......
# frozen_string_literal: true
module Mutations
module Boards
module ScopedIssueBoardArguments
extend ActiveSupport::Concern
prepended do
argument :assignee_id,
::Types::GlobalIDType[::User],
required: false,
description: 'ID of user to be assigned to the board.'
# Cannot pre-load ::Types::MilestoneType because we are also assigning values like:
# ::Timebox::None(0), ::Timebox::Upcoming(-2) or ::Timebox::Started(-3), that cannot be resolved to a DB record.
argument :milestone_id,
::Types::GlobalIDType[::Milestone],
required: false,
description: 'ID of milestone to be assigned to the board.'
# Cannot pre-load ::Types::IterationType because we are also assigning values like:
# ::Iteration::Predefined::None(0) or ::Iteration::Predefined::Current(-4), that cannot be resolved to a DB record.
argument :iteration_id,
::Types::GlobalIDType[::Iteration],
required: false,
description: 'ID of iteration to be assigned to the board.'
argument :weight,
GraphQL::INT_TYPE,
required: false,
description: 'Weight value to be assigned to the board.'
end
end
end
end
......@@ -23,7 +23,7 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Create do
context 'field tests' do
subject { described_class }
it { is_expected.to have_graphql_arguments(:groupPath, :name, :hideBacklogList, :hideClosedList) }
it { is_expected.to have_graphql_arguments(:groupPath, :name, :hideBacklogList, :hideClosedList, :labels, :labelIds) }
it { is_expected.to have_graphql_fields(:epic_board).at_least }
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Mutations::Boards::EpicBoards::Create do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create(:group) }
let(:name) { 'board name' }
let(:mutation) { graphql_mutation(:epic_board_create, params) }
let(:label) { create(:group_label, group: group) }
let(:params) { { groupPath: group.full_path, name: 'foo', hide_backlog_list: true, labels: [label.name] } }
subject { post_graphql_mutation(mutation, current_user: current_user) }
def mutation_response
graphql_mutation_response(:epic_board_create)
end
before do
stub_licensed_features(epics: true, scoped_issue_board: true)
end
context 'when the user does not have permission' do
it_behaves_like 'a mutation that returns a top-level access error'
end
context 'when the user has permission' do
before do
group.add_developer(current_user)
end
it 'returns the created board' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to have_key('epicBoard')
expect(mutation_response['epicBoard']['name']).to eq(params[:name])
expect(mutation_response['epicBoard']['hideBacklogList']).to eq(params[:hide_backlog_list])
expect(mutation_response['epicBoard']['labels']['count']).to eq(1)
end
context 'when create fails' do
let(:params) { { groupPath: group.full_path, name: 'x' * 256 } }
it 'returns an error' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to have_key('epicBoard')
expect(mutation_response['epicBoard']).to be_nil
expect(mutation_response['errors'].first).to eq('There was an error when creating a board.')
end
end
end
end
......@@ -66,9 +66,7 @@ RSpec.shared_examples 'boards create mutation' do
context 'when the Boards::CreateService returns an error response' do
before do
allow_next_instance_of(Boards::CreateService) do |service|
allow(service).to receive(:execute).and_return(ServiceResponse.error(message: 'There was an error.'))
end
params[:name] = ''
end
it 'does not create a board' do
......@@ -80,7 +78,7 @@ RSpec.shared_examples 'boards create mutation' do
expect(mutation_response).to have_key('board')
expect(mutation_response['board']).to be_nil
expect(mutation_response['errors'].first).to eq('There was an error.')
expect(mutation_response['errors'].first).to eq('There was an error when creating a board.')
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