Commit 1d8f7f5c authored by Sean McGivern's avatar Sean McGivern

Merge branch '31912-epic-labels' into 'master'

Manage and display labels from epic graphql

See merge request gitlab-org/gitlab!19642
parents 9d7db02f 28462a20
---
title: Manage and display labels from epic in the GraphQL API
merge_request: 19642
author:
type: added
...@@ -216,6 +216,11 @@ type CreateDiffNotePayload { ...@@ -216,6 +216,11 @@ type CreateDiffNotePayload {
Autogenerated input type of CreateEpic Autogenerated input type of CreateEpic
""" """
input CreateEpicInput { input CreateEpicInput {
"""
The IDs of labels to be added to the epic.
"""
addLabelIds: [ID!]
""" """
A unique identifier for the client performing the mutation. A unique identifier for the client performing the mutation.
""" """
...@@ -241,6 +246,11 @@ input CreateEpicInput { ...@@ -241,6 +246,11 @@ input CreateEpicInput {
""" """
groupPath: ID! groupPath: ID!
"""
The IDs of labels to be removed from the epic.
"""
removeLabelIds: [ID!]
""" """
The start date of the epic The start date of the epic
""" """
...@@ -1171,6 +1181,31 @@ type Epic implements Noteable { ...@@ -1171,6 +1181,31 @@ type Epic implements Noteable {
last: Int last: Int
): EpicIssueConnection ): EpicIssueConnection
"""
Labels assigned to the epic
"""
labels(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): LabelConnection
""" """
All notes on this noteable All notes on this noteable
""" """
...@@ -5061,6 +5096,11 @@ type TreeEntryEdge { ...@@ -5061,6 +5096,11 @@ type TreeEntryEdge {
Autogenerated input type of UpdateEpic Autogenerated input type of UpdateEpic
""" """
input UpdateEpicInput { input UpdateEpicInput {
"""
The IDs of labels to be added to the epic.
"""
addLabelIds: [ID!]
""" """
A unique identifier for the client performing the mutation. A unique identifier for the client performing the mutation.
""" """
...@@ -5091,6 +5131,11 @@ input UpdateEpicInput { ...@@ -5091,6 +5131,11 @@ input UpdateEpicInput {
""" """
iid: String! iid: String!
"""
The IDs of labels to be removed from the epic.
"""
removeLabelIds: [ID!]
""" """
The start date of the epic The start date of the epic
""" """
......
...@@ -38,6 +38,14 @@ module Mutations ...@@ -38,6 +38,14 @@ module Mutations
GraphQL::BOOLEAN_TYPE, GraphQL::BOOLEAN_TYPE,
required: false, required: false,
description: 'Indicates end date should be sourced from due_date_fixed field not the issue milestones' description: 'Indicates end date should be sourced from due_date_fixed field not the issue milestones'
argument :add_label_ids,
[GraphQL::ID_TYPE],
required: false,
description: 'The IDs of labels to be added to the epic.'
argument :remove_label_ids,
[GraphQL::ID_TYPE],
required: false,
description: 'The IDs of labels to be removed from the epic.'
end end
def validate_arguments!(args) def validate_arguments!(args)
......
...@@ -46,6 +46,8 @@ module Types ...@@ -46,6 +46,8 @@ module Types
::Types::EpicType.connection_type, ::Types::EpicType.connection_type,
null: true, null: true,
resolver: ::Resolvers::EpicResolver resolver: ::Resolvers::EpicResolver
field :labels, Types::LabelType.connection_type, null: true,
description: 'Labels assigned to the epic'
field :has_children, GraphQL::BOOLEAN_TYPE, null: false, method: :has_children? # rubocop:disable Graphql/Descriptions field :has_children, GraphQL::BOOLEAN_TYPE, null: false, method: :has_children? # rubocop:disable Graphql/Descriptions
field :has_issues, GraphQL::BOOLEAN_TYPE, null: false, method: :has_issues? # rubocop:disable Graphql/Descriptions field :has_issues, GraphQL::BOOLEAN_TYPE, null: false, method: :has_issues? # rubocop:disable Graphql/Descriptions
......
...@@ -5,7 +5,7 @@ require 'spec_helper' ...@@ -5,7 +5,7 @@ require 'spec_helper'
describe GitlabSchema.types['Epic'] do describe GitlabSchema.types['Epic'] do
let(:fields) do let(:fields) do
%i[ %i[
id iid title description state group parent author id iid title description state group parent author labels
start_date start_date_is_fixed start_date_fixed start_date_from_milestones start_date start_date_is_fixed start_date_fixed start_date_from_milestones
due_date due_date_is_fixed due_date_fixed due_date_from_milestones due_date due_date_is_fixed due_date_fixed due_date_from_milestones
closed_at created_at updated_at children has_children has_issues closed_at created_at updated_at children has_children has_issues
......
...@@ -7,7 +7,10 @@ describe 'Updating an Epic' do ...@@ -7,7 +7,10 @@ describe 'Updating an Epic' do
let_it_be(:current_user) { create(:user) } let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let(:epic) { create(:epic, group: group, title: 'original title') } let(:label_1) { create(:group_label, group: group) }
let(:label_2) { create(:group_label, group: group) }
let(:label_3) { create(:group_label, group: group) }
let(:epic) { create(:epic, group: group, title: 'original title', labels: [label_2]) }
let(:attributes) do let(:attributes) do
{ {
...@@ -100,6 +103,15 @@ describe 'Updating an Epic' do ...@@ -100,6 +103,15 @@ describe 'Updating an Epic' do
end end
end end
context 'when changing labels of the epic' do
let(:attributes) { { add_label_ids: [label_1.id, label_3.id], remove_label_ids: label_2.id } }
it 'adds and removes labels correctly' do
post_graphql_mutation(mutation, current_user: current_user)
expect(epic.reload.labels).to match_array([label_1, label_3])
end
end
context 'when there are ActiveRecord validation errors' do context 'when there are ActiveRecord validation errors' do
let(:attributes) { { title: '' } } let(:attributes) { { title: '' } }
......
...@@ -606,6 +606,24 @@ describe Issues::UpdateService, :mailer do ...@@ -606,6 +606,24 @@ describe Issues::UpdateService, :mailer do
end end
end end
context 'when same id is passed as add_label_ids and remove_label_ids' do
let(:params) { { add_label_ids: [label.id], remove_label_ids: [label.id] } }
context 'for a label assigned to an issue' do
it 'removes the label' do
issue.update(labels: [label])
expect(result.label_ids).to be_empty
end
end
context 'for a label not assigned to an issue' do
it 'does not add the label' do
expect(result.label_ids).to be_empty
end
end
end
context 'when duplicate label titles are given' do context 'when duplicate label titles are given' do
let(:params) do let(:params) do
{ labels: [label3.title, label3.title] } { labels: [label3.title, label3.title] }
......
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