Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
36c1b2bb
Commit
36c1b2bb
authored
Oct 28, 2019
by
Mario de la Ossa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add MergeRequestSetAssignees GraphQL mutation
Add a mutation to change assignees for merge requests
parent
9488d696
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
754 additions
and
0 deletions
+754
-0
app/graphql/mutations/merge_requests/set_assignees.rb
app/graphql/mutations/merge_requests/set_assignees.rb
+48
-0
app/graphql/types/mutation_operation_mode_enum.rb
app/graphql/types/mutation_operation_mode_enum.rb
+14
-0
app/graphql/types/mutation_type.rb
app/graphql/types/mutation_type.rb
+1
-0
changelogs/unreleased/31919-graphql-MR-assignee-mutation.yml
changelogs/unreleased/31919-graphql-MR-assignee-mutation.yml
+5
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+71
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+204
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+8
-0
ee/spec/graphql/mutations/merge_requests/set_assignees_spec.rb
...ec/graphql/mutations/merge_requests/set_assignees_spec.rb
+67
-0
ee/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
...pi/graphql/mutations/merge_requests/set_assignees_spec.rb
+96
-0
spec/graphql/mutations/merge_requests/set_assignees_spec.rb
spec/graphql/mutations/merge_requests/set_assignees_spec.rb
+106
-0
spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
...pi/graphql/mutations/merge_requests/set_assignees_spec.rb
+134
-0
No files found.
app/graphql/mutations/merge_requests/set_assignees.rb
0 → 100644
View file @
36c1b2bb
# frozen_string_literal: true
module
Mutations
module
MergeRequests
class
SetAssignees
<
Base
graphql_name
'MergeRequestSetAssignees'
argument
:assignee_usernames
,
[
GraphQL
::
STRING_TYPE
],
required:
true
,
description:
<<~
DESC
The usernames to assign to the merge request. Replaces existing assignees by default.
DESC
argument
:operation_mode
,
Types
::
MutationOperationModeEnum
,
required:
false
,
description:
<<~
DESC
The operation to perform. Defaults to REPLACE.
DESC
def
resolve
(
project_path
:,
iid
:,
assignee_usernames
:,
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:replace
])
Gitlab
::
QueryLimiting
.
whitelist
(
'https://gitlab.com/gitlab-org/gitlab/issues/36098'
)
merge_request
=
authorized_find!
(
project_path:
project_path
,
iid:
iid
)
project
=
merge_request
.
project
assignee_ids
=
[]
assignee_ids
+=
merge_request
.
assignees
.
map
(
&
:id
)
if
Types
::
MutationOperationModeEnum
.
enum
.
values_at
(
:remove
,
:append
).
include?
(
operation_mode
)
user_ids
=
UsersFinder
.
new
(
current_user
,
username:
assignee_usernames
).
execute
.
map
(
&
:id
)
if
operation_mode
==
Types
::
MutationOperationModeEnum
.
enum
[
:remove
]
assignee_ids
-=
user_ids
else
assignee_ids
|=
user_ids
end
::
MergeRequests
::
UpdateService
.
new
(
project
,
current_user
,
assignee_ids:
assignee_ids
)
.
execute
(
merge_request
)
{
merge_request:
merge_request
,
errors:
merge_request
.
errors
.
full_messages
}
end
end
end
end
app/graphql/types/mutation_operation_mode_enum.rb
0 → 100644
View file @
36c1b2bb
# frozen_string_literal: true
module
Types
class
MutationOperationModeEnum
<
BaseEnum
graphql_name
'MutationOperationMode'
description
'Different toggles for changing mutator behavior.'
# Suggested param name for the enum: `operation_mode`
value
'REPLACE'
,
'Performs a replace operation'
value
'APPEND'
,
'Performs an append operation'
value
'REMOVE'
,
'Performs a removal operation'
end
end
app/graphql/types/mutation_type.rb
View file @
36c1b2bb
...
...
@@ -11,6 +11,7 @@ module Types
mount_mutation
Mutations
::
AwardEmojis
::
Toggle
mount_mutation
Mutations
::
MergeRequests
::
SetMilestone
mount_mutation
Mutations
::
MergeRequests
::
SetWip
,
calls_gitaly:
true
mount_mutation
Mutations
::
MergeRequests
::
SetAssignees
mount_mutation
Mutations
::
Notes
::
Create
::
Note
,
calls_gitaly:
true
mount_mutation
Mutations
::
Notes
::
Create
::
DiffNote
,
calls_gitaly:
true
mount_mutation
Mutations
::
Notes
::
Create
::
ImageDiffNote
,
calls_gitaly:
true
...
...
changelogs/unreleased/31919-graphql-MR-assignee-mutation.yml
0 → 100644
View file @
36c1b2bb
---
title
:
Add MergeRequestSetAssignees GraphQL mutation
merge_request
:
19272
author
:
type
:
added
doc/api/graphql/reference/gitlab_schema.graphql
View file @
36c1b2bb
...
...
@@ -3275,6 +3275,56 @@ type MergeRequestPermissions {
updateMergeRequest
:
Boolean
!
}
"""
Autogenerated input type of MergeRequestSetAssignees
"""
input
MergeRequestSetAssigneesInput
{
"""
The
usernames
to
assign
to
the
merge
request
.
Replaces
existing
assignees
by
default
.
"""
assigneeUsernames
:
[
String
!]!
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
The
iid
of
the
merge
request
to
mutate
"""
iid
:
String
!
"""
The
operation
to
perform
.
Defaults
to
REPLACE
.
"""
operationMode
:
MutationOperationMode
"""
The
project
the
merge
request
to
mutate
is
in
"""
projectPath
:
ID
!
}
"""
Autogenerated return type of MergeRequestSetAssignees
"""
type
MergeRequestSetAssigneesPayload
{
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
Reasons
why
the
mutation
failed
.
"""
errors
:
[
String
!]!
"""
The
merge
request
after
mutation
"""
mergeRequest
:
MergeRequest
}
"""
Autogenerated input type of MergeRequestSetMilestone
"""
...
...
@@ -3455,6 +3505,7 @@ type Mutation {
destroyNote
(
input
:
DestroyNoteInput
!):
DestroyNotePayload
epicSetSubscription
(
input
:
EpicSetSubscriptionInput
!):
EpicSetSubscriptionPayload
epicTreeReorder
(
input
:
EpicTreeReorderInput
!):
EpicTreeReorderPayload
mergeRequestSetAssignees
(
input
:
MergeRequestSetAssigneesInput
!):
MergeRequestSetAssigneesPayload
mergeRequestSetMilestone
(
input
:
MergeRequestSetMilestoneInput
!):
MergeRequestSetMilestonePayload
mergeRequestSetWip
(
input
:
MergeRequestSetWipInput
!):
MergeRequestSetWipPayload
removeAwardEmoji
(
input
:
RemoveAwardEmojiInput
!):
RemoveAwardEmojiPayload
...
...
@@ -3464,6 +3515,26 @@ type Mutation {
updateNote
(
input
:
UpdateNoteInput
!):
UpdateNotePayload
}
"""
Different toggles for changing mutator behavior.
"""
enum
MutationOperationMode
{
"""
Performs
an
append
operation
"""
APPEND
"""
Performs
a
removal
operation
"""
REMOVE
"""
Performs
a
replace
operation
"""
REPLACE
}
type
Namespace
{
"""
Description
of
the
namespace
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
36c1b2bb
...
...
@@ -14541,6 +14541,33 @@
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"mergeRequestSetAssignees"
,
"description"
:
null
,
"args"
:
[
{
"name"
:
"input"
,
"description"
:
null
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"INPUT_OBJECT"
,
"name"
:
"MergeRequestSetAssigneesInput"
,
"ofType"
:
null
}
},
"defaultValue"
:
null
}
],
"type"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"MergeRequestSetAssigneesPayload"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"mergeRequestSetMilestone"
,
"description"
:
null
,
...
...
@@ -15481,6 +15508,183 @@
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
"kind"
:
"OBJECT"
,
"name"
:
"MergeRequestSetAssigneesPayload"
,
"description"
:
"Autogenerated return type of MergeRequestSetAssignees"
,
"fields"
:
[
{
"name"
:
"clientMutationId"
,
"description"
:
"A unique identifier for the client performing the mutation."
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"errors"
,
"description"
:
"Reasons why the mutation failed."
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"LIST"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
}
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"mergeRequest"
,
"description"
:
"The merge request after mutation"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"MergeRequest"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"inputFields"
:
null
,
"interfaces"
:
[
],
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
"kind"
:
"INPUT_OBJECT"
,
"name"
:
"MergeRequestSetAssigneesInput"
,
"description"
:
"Autogenerated input type of MergeRequestSetAssignees"
,
"fields"
:
null
,
"inputFields"
:
[
{
"name"
:
"projectPath"
,
"description"
:
"The project the merge request to mutate is in"
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"ID"
,
"ofType"
:
null
}
},
"defaultValue"
:
null
},
{
"name"
:
"iid"
,
"description"
:
"The iid of the merge request to mutate"
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"defaultValue"
:
null
},
{
"name"
:
"assigneeUsernames"
,
"description"
:
"The usernames to assign to the merge request. Replaces existing assignees by default.
\n
"
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"LIST"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
}
}
},
"defaultValue"
:
null
},
{
"name"
:
"operationMode"
,
"description"
:
"The operation to perform. Defaults to REPLACE.
\n
"
,
"type"
:
{
"kind"
:
"ENUM"
,
"name"
:
"MutationOperationMode"
,
"ofType"
:
null
},
"defaultValue"
:
null
},
{
"name"
:
"clientMutationId"
,
"description"
:
"A unique identifier for the client performing the mutation."
,
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"defaultValue"
:
null
}
],
"interfaces"
:
null
,
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
"kind"
:
"ENUM"
,
"name"
:
"MutationOperationMode"
,
"description"
:
"Different toggles for changing mutator behavior."
,
"fields"
:
null
,
"inputFields"
:
null
,
"interfaces"
:
null
,
"enumValues"
:
[
{
"name"
:
"REPLACE"
,
"description"
:
"Performs a replace operation"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"APPEND"
,
"description"
:
"Performs an append operation"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"REMOVE"
,
"description"
:
"Performs a removal operation"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"possibleTypes"
:
null
},
{
"kind"
:
"OBJECT"
,
"name"
:
"CreateNotePayload"
,
...
...
doc/api/graphql/reference/index.md
View file @
36c1b2bb
...
...
@@ -473,6 +473,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`cherryPickOnCurrentMergeRequest`
| Boolean! | Whether or not a user can perform
`cherry_pick_on_current_merge_request`
on this resource |
|
`revertOnCurrentMergeRequest`
| Boolean! | Whether or not a user can perform
`revert_on_current_merge_request`
on this resource |
### MergeRequestSetAssigneesPayload
| Name | Type | Description |
| --- | ---- | ---------- |
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`errors`
| String! => Array | Reasons why the mutation failed. |
|
`mergeRequest`
| MergeRequest | The merge request after mutation |
### MergeRequestSetMilestonePayload
| Name | Type | Description |
...
...
ee/spec/graphql/mutations/merge_requests/set_assignees_spec.rb
0 → 100644
View file @
36c1b2bb
# frozen_string_literal: true
require
'spec_helper'
describe
Mutations
::
MergeRequests
::
SetAssignees
do
let
(
:merge_request
)
{
create
(
:merge_request
)
}
let
(
:user
)
{
create
(
:user
)
}
subject
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
user
})
}
describe
'#resolve'
do
let
(
:assignees
)
{
create_list
(
:user
,
3
)
}
let
(
:assignee_usernames
)
{
assignees
.
map
(
&
:username
)
}
let
(
:mutated_merge_request
)
{
subject
[
:merge_request
]
}
subject
{
mutation
.
resolve
(
project_path:
merge_request
.
project
.
full_path
,
iid:
merge_request
.
iid
,
assignee_usernames:
assignee_usernames
)
}
before
do
assignees
.
each
do
|
user
|
merge_request
.
project
.
add_developer
(
user
)
end
end
context
'when the user can update the merge request'
do
before
do
merge_request
.
project
.
add_developer
(
user
)
end
it
'sets merge request assignees'
do
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
match_array
(
assignees
)
expect
(
subject
[
:errors
]).
to
be_empty
end
it
'removes assignees not in the list'
do
users
=
create_list
(
:user
,
2
)
users
.
each
do
|
user
|
merge_request
.
project
.
add_developer
(
user
)
end
merge_request
.
assignees
=
users
merge_request
.
save!
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
match_array
(
assignees
)
expect
(
subject
[
:errors
]).
to
be_empty
end
context
'when passing "append" as true'
do
subject
{
mutation
.
resolve
(
project_path:
merge_request
.
project
.
full_path
,
iid:
merge_request
.
iid
,
assignee_usernames:
assignee_usernames
,
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:append
])
}
let
(
:existing_assignees
)
{
create_list
(
:user
,
2
)
}
before
do
existing_assignees
.
each
do
|
user
|
merge_request
.
project
.
add_developer
(
user
)
end
merge_request
.
assignees
=
existing_assignees
merge_request
.
save!
end
it
'does not remove assignees not in the list'
do
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
match_array
(
assignees
+
existing_assignees
)
expect
(
subject
[
:errors
]).
to
be_empty
end
end
end
end
end
ee/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
0 → 100644
View file @
36c1b2bb
# frozen_string_literal: true
require
'spec_helper'
describe
'Setting assignees of a merge request'
do
include
GraphqlHelpers
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:merge_request
)
{
create
(
:merge_request
)
}
let
(
:project
)
{
merge_request
.
project
}
let
(
:assignees
)
{
create_list
(
:user
,
3
)
}
let
(
:extra_assignees
)
{
create_list
(
:user
,
2
)
}
let
(
:input
)
{
{
assignee_usernames:
assignees
.
map
(
&
:username
)
}
}
let
(
:expected_result
)
do
assignees
.
map
{
|
u
|
{
'username'
=>
u
.
username
}
}
end
let
(
:mutation
)
do
variables
=
{
project_path:
project
.
full_path
,
iid:
merge_request
.
iid
.
to_s
}
graphql_mutation
(
:merge_request_set_assignees
,
variables
.
merge
(
input
),
<<-
QL
.
strip_heredoc
clientMutationId
errors
mergeRequest {
id
assignees {
nodes {
username
}
}
}
QL
)
end
def
mutation_response
graphql_mutation_response
(
:merge_request_set_assignees
)
end
def
mutation_assignee_nodes
mutation_response
[
'mergeRequest'
][
'assignees'
][
'nodes'
]
end
before
do
project
.
add_developer
(
current_user
)
assignees
.
each
do
|
user
|
project
.
add_developer
(
user
)
end
extra_assignees
.
each
do
|
user
|
project
.
add_developer
(
user
)
end
end
it
'adds the assignees to the merge request'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
match_array
(
expected_result
)
end
context
'with assignees already assigned'
do
before
do
merge_request
.
assignees
=
extra_assignees
merge_request
.
save!
end
it
'removes assignees not in the list'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
match_array
(
expected_result
)
end
end
context
'when passing append as true'
do
let
(
:input
)
{
{
assignee_usernames:
assignees
.
map
(
&
:username
),
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:append
]
}
}
let
(
:expected_result
)
do
assignees
.
map
{
|
u
|
{
'username'
=>
u
.
username
}
}
+
extra_assignees
.
map
{
|
u
|
{
'username'
=>
u
.
username
}
}
end
before
do
merge_request
.
assignees
=
extra_assignees
merge_request
.
save!
end
it
'does not remove users not in the list'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
match_array
(
expected_result
)
end
end
end
spec/graphql/mutations/merge_requests/set_assignees_spec.rb
0 → 100644
View file @
36c1b2bb
# frozen_string_literal: true
require
'spec_helper'
describe
Mutations
::
MergeRequests
::
SetAssignees
do
let
(
:merge_request
)
{
create
(
:merge_request
)
}
let
(
:user
)
{
create
(
:user
)
}
subject
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
user
})
}
describe
'#resolve'
do
let
(
:assignee
)
{
create
(
:user
)
}
let
(
:assignee2
)
{
create
(
:user
)
}
let
(
:assignee_usernames
)
{
[
assignee
.
username
]
}
let
(
:mutated_merge_request
)
{
subject
[
:merge_request
]
}
subject
{
mutation
.
resolve
(
project_path:
merge_request
.
project
.
full_path
,
iid:
merge_request
.
iid
,
assignee_usernames:
assignee_usernames
)
}
before
do
merge_request
.
project
.
add_developer
(
assignee
)
merge_request
.
project
.
add_developer
(
assignee2
)
end
it
'raises an error if the resource is not accessible to the user'
do
expect
{
subject
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
end
context
'when the user can update the merge request'
do
before
do
merge_request
.
project
.
add_developer
(
user
)
end
it
'replaces the assignee'
do
merge_request
.
assignees
=
[
assignee2
]
merge_request
.
save!
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
contain_exactly
(
assignee
)
expect
(
subject
[
:errors
]).
to
be_empty
end
it
'returns errors merge request could not be updated'
do
# Make the merge request invalid
merge_request
.
allow_broken
=
true
merge_request
.
update!
(
source_project:
nil
)
expect
(
subject
[
:errors
]).
not_to
be_empty
end
context
'when passing an empty assignee list'
do
let
(
:assignee_usernames
)
{
[]
}
before
do
merge_request
.
assignees
=
[
assignee
]
merge_request
.
save!
end
it
'removes all assignees'
do
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
eq
([])
expect
(
subject
[
:errors
]).
to
be_empty
end
end
context
'when passing "append" as true'
do
subject
{
mutation
.
resolve
(
project_path:
merge_request
.
project
.
full_path
,
iid:
merge_request
.
iid
,
assignee_usernames:
assignee_usernames
,
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:append
])
}
before
do
merge_request
.
assignees
=
[
assignee2
]
merge_request
.
save!
# In CE, APPEND is a NOOP as you can't have multiple assignees
# We test multiple assignment in EE specs
stub_licensed_features
(
multiple_merge_request_assignees:
false
)
end
it
'is a NO-OP in FOSS'
do
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
contain_exactly
(
assignee2
)
expect
(
subject
[
:errors
]).
to
be_empty
end
end
context
'when passing "remove" as true'
do
before
do
merge_request
.
assignees
=
[
assignee
]
merge_request
.
save!
end
it
'removes named assignee'
do
mutated_merge_request
=
mutation
.
resolve
(
project_path:
merge_request
.
project
.
full_path
,
iid:
merge_request
.
iid
,
assignee_usernames:
assignee_usernames
,
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:remove
])[
:merge_request
]
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
eq
([])
expect
(
subject
[
:errors
]).
to
be_empty
end
it
'does not remove unnamed assignee'
do
mutated_merge_request
=
mutation
.
resolve
(
project_path:
merge_request
.
project
.
full_path
,
iid:
merge_request
.
iid
,
assignee_usernames:
[
assignee2
.
username
],
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:remove
])[
:merge_request
]
expect
(
mutated_merge_request
).
to
eq
(
merge_request
)
expect
(
mutated_merge_request
.
assignees
).
to
contain_exactly
(
assignee
)
expect
(
subject
[
:errors
]).
to
be_empty
end
end
end
end
end
spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
0 → 100644
View file @
36c1b2bb
# frozen_string_literal: true
require
'spec_helper'
describe
'Setting assignees of a merge request'
do
include
GraphqlHelpers
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:merge_request
)
{
create
(
:merge_request
)
}
let
(
:project
)
{
merge_request
.
project
}
let
(
:assignee
)
{
create
(
:user
)
}
let
(
:assignee2
)
{
create
(
:user
)
}
let
(
:input
)
{
{
assignee_usernames:
[
assignee
.
username
]
}
}
let
(
:expected_result
)
do
[{
'username'
=>
assignee
.
username
}]
end
let
(
:mutation
)
do
variables
=
{
project_path:
project
.
full_path
,
iid:
merge_request
.
iid
.
to_s
}
graphql_mutation
(
:merge_request_set_assignees
,
variables
.
merge
(
input
),
<<-
QL
.
strip_heredoc
clientMutationId
errors
mergeRequest {
id
assignees {
nodes {
username
}
}
}
QL
)
end
def
mutation_response
graphql_mutation_response
(
:merge_request_set_assignees
)
end
def
mutation_assignee_nodes
mutation_response
[
'mergeRequest'
][
'assignees'
][
'nodes'
]
end
before
do
project
.
add_developer
(
current_user
)
project
.
add_developer
(
assignee
)
project
.
add_developer
(
assignee2
)
end
it
'returns an error if the user is not allowed to update the merge request'
do
post_graphql_mutation
(
mutation
,
current_user:
create
(
:user
))
expect
(
graphql_errors
).
not_to
be_empty
end
it
'does not allow members without the right permission to add assignees'
do
user
=
create
(
:user
)
project
.
add_guest
(
user
)
post_graphql_mutation
(
mutation
,
current_user:
user
)
expect
(
graphql_errors
).
not_to
be_empty
end
context
'with assignees already assigned'
do
before
do
merge_request
.
assignees
=
[
assignee2
]
merge_request
.
save!
end
it
'replaces the assignee'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
match_array
(
expected_result
)
end
end
context
'when passing an empty list of assignees'
do
let
(
:input
)
{
{
assignee_usernames:
[]
}
}
before
do
merge_request
.
assignees
=
[
assignee2
]
merge_request
.
save!
end
it
'removes assignee'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
eq
([])
end
end
context
'when passing append as true'
do
let
(
:input
)
{
{
assignee_usernames:
[
assignee2
.
username
],
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:append
]
}
}
before
do
# In CE, APPEND is a NOOP as you can't have multiple assignees
# We test multiple assignment in EE specs
stub_licensed_features
(
multiple_merge_request_assignees:
false
)
merge_request
.
assignees
=
[
assignee
]
merge_request
.
save!
end
it
'does not replace the assignee in CE'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
match_array
(
expected_result
)
end
end
context
'when passing remove as true'
do
let
(
:input
)
{
{
assignee_usernames:
[
assignee
.
username
],
operation_mode:
Types
::
MutationOperationModeEnum
.
enum
[
:remove
]
}
}
let
(
:expected_result
)
{
[]
}
before
do
merge_request
.
assignees
=
[
assignee
]
merge_request
.
save!
end
it
'removes the users in the list, while adding none'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_assignee_nodes
).
to
match_array
(
expected_result
)
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment