Commit 03411f99 authored by charlie ablett's avatar charlie ablett

Merge branch 'ld-graphql-aliased-mutations' into 'master'

Alias and deprecate AwardEmoji mutations to match our naming guidelines

See merge request gitlab-org/gitlab!34798
parents 603b113d cc6731a7
......@@ -3,7 +3,7 @@
module Mutations
module AwardEmojis
class Add < Base
graphql_name 'AddAwardEmoji'
graphql_name 'AwardEmojiAdd'
def resolve(args)
awardable = authorized_find!(id: args[:awardable_id])
......
......@@ -3,7 +3,7 @@
module Mutations
module AwardEmojis
class Remove < Base
graphql_name 'RemoveAwardEmoji'
graphql_name 'AwardEmojiRemove'
def resolve(args)
awardable = authorized_find!(id: args[:awardable_id])
......
......@@ -3,7 +3,7 @@
module Mutations
module AwardEmojis
class Toggle < Base
graphql_name 'ToggleAwardEmoji'
graphql_name 'AwardEmojiToggle'
field :toggledOn, GraphQL::BOOLEAN_TYPE, null: false,
description: 'Indicates the status of the emoji. ' \
......
# frozen_string_literal: true
module Types
module DeprecatedMutations
extend ActiveSupport::Concern
prepended do
mount_aliased_mutation 'AddAwardEmoji',
Mutations::AwardEmojis::Add,
deprecated: { reason: 'Use awardEmojiAdd', milestone: '13.2' }
mount_aliased_mutation 'RemoveAwardEmoji',
Mutations::AwardEmojis::Remove,
deprecated: { reason: 'Use awardEmojiRemove', milestone: '13.2' }
mount_aliased_mutation 'ToggleAwardEmoji',
Mutations::AwardEmojis::Toggle,
deprecated: { reason: 'Use awardEmojiToggle', milestone: '13.2' }
end
end
end
......@@ -57,4 +57,5 @@ module Types
end
end
::Types::MutationType.prepend(::Types::DeprecatedMutations)
::Types::MutationType.prepend_if_ee('::EE::Types::MutationType')
---
title: Rename GraphQL AwardEmoji mutations to follow naming conventions, deprecating
the old mutations
merge_request: 34798
author:
type: changed
......@@ -147,7 +147,7 @@ Example: Let's have some tea - add a `:tea:` reaction emoji to an issue.
```graphql
mutation {
addAwardEmoji(input: { awardableId: "gid://gitlab/Issue/27039960",
awardEmojiAdd(input: { awardableId: "gid://gitlab/Issue/27039960",
name: "tea"
}) {
awardEmoji {
......
......@@ -635,6 +635,131 @@ type AwardEmoji {
user: User!
}
"""
Autogenerated input type of AwardEmojiAdd
"""
input AwardEmojiAddInput {
"""
The global id of the awardable resource
"""
awardableId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The emoji name
"""
name: String!
}
"""
Autogenerated return type of AwardEmojiAdd
"""
type AwardEmojiAddPayload {
"""
The award emoji after mutation
"""
awardEmoji: AwardEmoji
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Errors encountered during execution of the mutation.
"""
errors: [String!]!
}
"""
Autogenerated input type of AwardEmojiRemove
"""
input AwardEmojiRemoveInput {
"""
The global id of the awardable resource
"""
awardableId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The emoji name
"""
name: String!
}
"""
Autogenerated return type of AwardEmojiRemove
"""
type AwardEmojiRemovePayload {
"""
The award emoji after mutation
"""
awardEmoji: AwardEmoji
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Errors encountered during execution of the mutation.
"""
errors: [String!]!
}
"""
Autogenerated input type of AwardEmojiToggle
"""
input AwardEmojiToggleInput {
"""
The global id of the awardable resource
"""
awardableId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The emoji name
"""
name: String!
}
"""
Autogenerated return type of AwardEmojiToggle
"""
type AwardEmojiTogglePayload {
"""
The award emoji after mutation
"""
awardEmoji: AwardEmoji
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Errors encountered during execution of the mutation.
"""
errors: [String!]!
"""
Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji.
"""
toggledOn: Boolean!
}
type BaseService implements Service {
"""
Indicates if the service is active
......@@ -7628,10 +7753,13 @@ enum MoveType {
}
type Mutation {
addAwardEmoji(input: AddAwardEmojiInput!): AddAwardEmojiPayload
addAwardEmoji(input: AddAwardEmojiInput!): AddAwardEmojiPayload @deprecated(reason: "Use awardEmojiAdd. Deprecated in 13.2")
addProjectToSecurityDashboard(input: AddProjectToSecurityDashboardInput!): AddProjectToSecurityDashboardPayload
adminSidekiqQueuesDeleteJobs(input: AdminSidekiqQueuesDeleteJobsInput!): AdminSidekiqQueuesDeleteJobsPayload
alertSetAssignees(input: AlertSetAssigneesInput!): AlertSetAssigneesPayload
awardEmojiAdd(input: AwardEmojiAddInput!): AwardEmojiAddPayload
awardEmojiRemove(input: AwardEmojiRemoveInput!): AwardEmojiRemovePayload
awardEmojiToggle(input: AwardEmojiToggleInput!): AwardEmojiTogglePayload
boardListUpdateLimitMetrics(input: BoardListUpdateLimitMetricsInput!): BoardListUpdateLimitMetricsPayload
commitCreate(input: CommitCreateInput!): CommitCreatePayload
createAlertIssue(input: CreateAlertIssueInput!): CreateAlertIssuePayload
......@@ -7677,14 +7805,14 @@ type Mutation {
Update attributes of a merge request
"""
mergeRequestUpdate(input: MergeRequestUpdateInput!): MergeRequestUpdatePayload
removeAwardEmoji(input: RemoveAwardEmojiInput!): RemoveAwardEmojiPayload
removeAwardEmoji(input: RemoveAwardEmojiInput!): RemoveAwardEmojiPayload @deprecated(reason: "Use awardEmojiRemove. Deprecated in 13.2")
removeProjectFromSecurityDashboard(input: RemoveProjectFromSecurityDashboardInput!): RemoveProjectFromSecurityDashboardPayload
runDastScan(input: RunDASTScanInput!): RunDASTScanPayload
todoMarkDone(input: TodoMarkDoneInput!): TodoMarkDonePayload
todoRestore(input: TodoRestoreInput!): TodoRestorePayload
todoRestoreMany(input: TodoRestoreManyInput!): TodoRestoreManyPayload
todosMarkAllDone(input: TodosMarkAllDoneInput!): TodosMarkAllDonePayload
toggleAwardEmoji(input: ToggleAwardEmojiInput!): ToggleAwardEmojiPayload
toggleAwardEmoji(input: ToggleAwardEmojiInput!): ToggleAwardEmojiPayload @deprecated(reason: "Use awardEmojiToggle. Deprecated in 13.2")
updateAlertStatus(input: UpdateAlertStatusInput!): UpdateAlertStatusPayload
updateContainerExpirationPolicy(input: UpdateContainerExpirationPolicyInput!): UpdateContainerExpirationPolicyPayload
updateEpic(input: UpdateEpicInput!): UpdateEpicPayload
......
......@@ -1576,6 +1576,372 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "AwardEmojiAddInput",
"description": "Autogenerated input type of AwardEmojiAdd",
"fields": null,
"inputFields": [
{
"name": "awardableId",
"description": "The global id of the awardable resource",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "name",
"description": "The emoji name",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"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": "OBJECT",
"name": "AwardEmojiAddPayload",
"description": "Autogenerated return type of AwardEmojiAdd",
"fields": [
{
"name": "awardEmoji",
"description": "The award emoji after mutation",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "AwardEmoji",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"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": "Errors encountered during execution of the mutation.",
"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
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "AwardEmojiRemoveInput",
"description": "Autogenerated input type of AwardEmojiRemove",
"fields": null,
"inputFields": [
{
"name": "awardableId",
"description": "The global id of the awardable resource",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "name",
"description": "The emoji name",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"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": "OBJECT",
"name": "AwardEmojiRemovePayload",
"description": "Autogenerated return type of AwardEmojiRemove",
"fields": [
{
"name": "awardEmoji",
"description": "The award emoji after mutation",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "AwardEmoji",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"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": "Errors encountered during execution of the mutation.",
"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
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "AwardEmojiToggleInput",
"description": "Autogenerated input type of AwardEmojiToggle",
"fields": null,
"inputFields": [
{
"name": "awardableId",
"description": "The global id of the awardable resource",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "name",
"description": "The emoji name",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"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": "OBJECT",
"name": "AwardEmojiTogglePayload",
"description": "Autogenerated return type of AwardEmojiToggle",
"fields": [
{
"name": "awardEmoji",
"description": "The award emoji after mutation",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "AwardEmoji",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"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": "Errors encountered during execution of the mutation.",
"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": "toggledOn",
"description": "Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "BaseService",
......@@ -21388,8 +21754,8 @@
"name": "AddAwardEmojiPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
"isDeprecated": true,
"deprecationReason": "Use awardEmojiAdd. Deprecated in 13.2"
},
{
"name": "addProjectToSecurityDashboard",
......@@ -21472,6 +21838,87 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "awardEmojiAdd",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "AwardEmojiAddInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "AwardEmojiAddPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "awardEmojiRemove",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "AwardEmojiRemoveInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "AwardEmojiRemovePayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "awardEmojiToggle",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "AwardEmojiToggleInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "AwardEmojiTogglePayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "boardListUpdateLimitMetrics",
"description": null,
......@@ -22495,8 +22942,8 @@
"name": "RemoveAwardEmojiPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
"isDeprecated": true,
"deprecationReason": "Use awardEmojiRemove. Deprecated in 13.2"
},
{
"name": "removeProjectFromSecurityDashboard",
......@@ -22684,8 +23131,8 @@
"name": "ToggleAwardEmojiPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
"isDeprecated": true,
"deprecationReason": "Use awardEmojiToggle. Deprecated in 13.2"
},
{
"name": "updateAlertStatus",
......@@ -114,6 +114,37 @@ An emoji awarded by a user.
| `unicodeVersion` | String! | The unicode version for this emoji |
| `user` | User! | The user who awarded the emoji |
## AwardEmojiAddPayload
Autogenerated return type of AwardEmojiAdd
| Name | Type | Description |
| --- | ---- | ---------- |
| `awardEmoji` | AwardEmoji | The award emoji after mutation |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
## AwardEmojiRemovePayload
Autogenerated return type of AwardEmojiRemove
| Name | Type | Description |
| --- | ---- | ---------- |
| `awardEmoji` | AwardEmoji | The award emoji after mutation |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
## AwardEmojiTogglePayload
Autogenerated return type of AwardEmojiToggle
| Name | Type | Description |
| --- | ---- | ---------- |
| `awardEmoji` | AwardEmoji | The award emoji after mutation |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `toggledOn` | Boolean! | Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji. |
## BaseService
| Name | Type | Description |
......
......@@ -13,6 +13,14 @@ module Gitlab
mutation: mutation_class,
**custom_kwargs
end
def mount_aliased_mutation(alias_name, mutation_class, **custom_kwargs)
aliased_mutation_class = Class.new(mutation_class) do
graphql_name alias_name
end
mount_mutation(aliased_mutation_class, **custom_kwargs)
end
end
end
end
......
......@@ -6,4 +6,30 @@ describe Types::MutationType do
it 'is expected to have the MergeRequestSetWip' do
expect(described_class).to have_graphql_mutation(Mutations::MergeRequests::SetWip)
end
describe 'deprecated and aliased mutations' do
using RSpec::Parameterized::TableSyntax
where(:alias_name, :canonical_name) do
'AddAwardEmoji' | 'AwardEmojiAdd'
'RemoveAwardEmoji' | 'AwardEmojiRemove'
'ToggleAwardEmoji' | 'AwardEmojiToggle'
end
with_them do
let(:alias_field) { get_field(alias_name) }
let(:canonical_field) { get_field(canonical_name) }
it { expect(alias_field).to be_present }
it { expect(canonical_field).to be_present }
it { expect(alias_field.deprecation_reason).to be_present }
it { expect(canonical_field.deprecation_reason).not_to be_present }
it { expect(alias_field.resolver.fields).to eq(canonical_field.resolver.fields) }
it { expect(alias_field.resolver.arguments).to eq(canonical_field.resolver.arguments) }
end
def get_field(name)
described_class.fields[GraphqlHelpers.fieldnamerize(name)]
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Graphql::MountMutation do
let_it_be(:mutation) do
Class.new(Mutations::BaseMutation) do
graphql_name 'TestMutation'
argument :foo, GraphQL::STRING_TYPE, required: false
field :bar, GraphQL::STRING_TYPE, null: true
end
end
describe '.mount_mutation' do
subject(:field) do
mutation_type = mutation_type_factory do |f|
f.mount_mutation(mutation)
end
mutation_type.get_field('testMutation').to_graphql
end
it 'mounts a mutation' do
expect(field.mutation).to be_present
end
end
describe '.mount_aliased_mutation' do
subject(:field) do
mutation_type = mutation_type_factory do |f|
f.mount_aliased_mutation('MyAlias', mutation)
end
mutation_type.get_field('myAlias').to_graphql
end
it 'mounts a mutation' do
expect(field.mutation).to be_present
end
it 'has a correct `graphql_name`' do
expect(field.mutation.graphql_name).to eq('MyAlias')
end
it 'has a correct type' do
expect(field.type.name).to eq('MyAliasPayload')
end
it 'has a correct input argument' do
expect(field.arguments['input'].type.unwrap.name).to eq('MyAliasInput')
end
end
def mutation_type_factory
Class.new(GraphQL::Schema::Object) do
include Gitlab::Graphql::MountMutation
graphql_name 'MutationType'
yield(self) if block_given?
end
end
end
......@@ -15,11 +15,11 @@ describe 'Adding an AwardEmoji' do
name: emoji_name
}
graphql_mutation(:add_award_emoji, variables)
graphql_mutation(:award_emoji_add, variables)
end
def mutation_response
graphql_mutation_response(:add_award_emoji)
graphql_mutation_response(:award_emoji_add)
end
shared_examples 'a mutation that does not create an AwardEmoji' do
......
......@@ -12,11 +12,11 @@ describe 'Removing an AwardEmoji' do
let(:input) { { awardable_id: GitlabSchema.id_from_object(awardable).to_s, name: emoji_name } }
let(:mutation) do
graphql_mutation(:remove_award_emoji, input)
graphql_mutation(:award_emoji_remove, input)
end
def mutation_response
graphql_mutation_response(:remove_award_emoji)
graphql_mutation_response(:award_emoji_remove)
end
def create_award_emoji(user)
......
......@@ -15,11 +15,11 @@ describe 'Toggling an AwardEmoji' do
name: emoji_name
}
graphql_mutation(:toggle_award_emoji, variables)
graphql_mutation(:award_emoji_toggle, variables)
end
def mutation_response
graphql_mutation_response(:toggle_award_emoji)
graphql_mutation_response(:award_emoji_toggle)
end
shared_examples 'a mutation that does not create or destroy an AwardEmoji' do
......
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