Add mark as spam snippet mutation

Add the mark_as_spam_snippet mutation to the
GraphQL endpoint.
parent a98b8302
# frozen_string_literal: true
module Mutations
module Snippets
class MarkAsSpam < Base
graphql_name 'MarkAsSpamSnippet'
argument :id,
GraphQL::ID_TYPE,
required: true,
description: 'The global id of the snippet to update'
def resolve(id:)
snippet = authorized_find!(id: id)
result = mark_as_spam(snippet)
errors = result ? [] : ['Error with Akismet. Please check the logs for more info.']
{
errors: errors
}
end
private
def mark_as_spam(snippet)
SpamService.new(snippet).mark_as_spam!
end
def authorized_resource?(snippet)
super && snippet.submittable_as_spam_by?(context[:current_user])
end
def ability_name
"admin"
end
end
end
end
......@@ -28,6 +28,7 @@ module Types
mount_mutation Mutations::Snippets::Destroy
mount_mutation Mutations::Snippets::Update
mount_mutation Mutations::Snippets::Create
mount_mutation Mutations::Snippets::MarkAsSpam
end
end
......
---
title: Add mark as spam snippet mutation
merge_request: 21912
author:
type: other
......@@ -3069,6 +3069,41 @@ type LabelEdge {
node: Label
}
"""
Autogenerated input type of MarkAsSpamSnippet
"""
input MarkAsSpamSnippetInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The global id of the snippet to update
"""
id: ID!
}
"""
Autogenerated return type of MarkAsSpamSnippet
"""
type MarkAsSpamSnippetPayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Reasons why the mutation failed.
"""
errors: [String!]!
"""
The snippet after mutation
"""
snippet: Snippet
}
type MergeRequest implements Noteable {
"""
Indicates if members of the target project can push to the fork
......@@ -3941,6 +3976,7 @@ type Mutation {
issueSetConfidential(input: IssueSetConfidentialInput!): IssueSetConfidentialPayload
issueSetDueDate(input: IssueSetDueDateInput!): IssueSetDueDatePayload
issueSetWeight(input: IssueSetWeightInput!): IssueSetWeightPayload
markAsSpamSnippet(input: MarkAsSpamSnippetInput!): MarkAsSpamSnippetPayload
mergeRequestSetAssignees(input: MergeRequestSetAssigneesInput!): MergeRequestSetAssigneesPayload
mergeRequestSetLabels(input: MergeRequestSetLabelsInput!): MergeRequestSetLabelsPayload
mergeRequestSetLocked(input: MergeRequestSetLockedInput!): MergeRequestSetLockedPayload
......
......@@ -16121,6 +16121,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "markAsSpamSnippet",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "MarkAsSpamSnippetInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "MarkAsSpamSnippetPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "mergeRequestSetAssignees",
"description": null,
......@@ -19662,6 +19689,108 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "MarkAsSpamSnippetPayload",
"description": "Autogenerated return type of MarkAsSpamSnippet",
"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": "snippet",
"description": "The snippet after mutation",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "Snippet",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "MarkAsSpamSnippetInput",
"description": "Autogenerated input type of MarkAsSpamSnippet",
"fields": null,
"inputFields": [
{
"name": "id",
"description": "The global id of the snippet to update",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"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": "DesignManagementUploadPayload",
......
......@@ -429,6 +429,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `color` | String! | Background color of the label |
| `textColor` | String! | Text color of the label |
### MarkAsSpamSnippetPayload
| Name | Type | Description |
| --- | ---- | ---------- |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Reasons why the mutation failed. |
| `snippet` | Snippet | The snippet after mutation |
### MergeRequest
| Name | Type | Description |
......
# frozen_string_literal: true
require 'spec_helper'
describe 'Mark snippet as spam' do
include GraphqlHelpers
let_it_be(:admin) { create(:admin) }
let_it_be(:other_user) { create(:user) }
let_it_be(:snippet) { create(:personal_snippet) }
let_it_be(:user_agent_detail) { create(:user_agent_detail, subject: snippet) }
let(:current_user) { snippet.author }
let(:mutation) do
variables = {
id: snippet.to_global_id.to_s
}
graphql_mutation(:mark_as_spam_snippet, variables)
end
def mutation_response
graphql_mutation_response(:mark_as_spam_snippet)
end
shared_examples 'does not mark the snippet as spam' do
it do
expect do
post_graphql_mutation(mutation, current_user: current_user)
end.not_to change { snippet.reload.user_agent_detail.submitted }
end
end
context 'when the user does not have permission' do
let(:current_user) { other_user }
it_behaves_like 'a mutation that returns top-level errors',
errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
it_behaves_like 'does not mark the snippet as spam'
end
context 'when the user has permission' do
context 'when user can not mark snippet as spam' do
it_behaves_like 'does not mark the snippet as spam'
end
context 'when user can mark snippet as spam' do
let(:current_user) { admin }
before do
stub_application_setting(akismet_enabled: true)
end
it 'marks snippet as spam' do
expect_next_instance_of(SpamService) do |instance|
expect(instance).to receive(:mark_as_spam!)
end
post_graphql_mutation(mutation, current_user: current_user)
end
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