Commit 8d0ec9fb authored by charlie ablett's avatar charlie ablett

Merge branch 'board_args_consolidation' into 'master'

Reuse scope board mutation logic for epic boards

See merge request gitlab-org/gitlab!55982
parents a96ca241 d0ccbb2e
......@@ -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