Commit 97f082b9 authored by Sean Arnold's avatar Sean Arnold

Add mutation for AlertManagementAlert status

- Add alert service to with change_status
- Add mutation handling
- Add specs
- Update docs
parent d597839a
# frozen_string_literal: true
module Mutations
module AlertManagement
class Base < BaseMutation
include Mutations::ResolvesProject
argument :project_path, GraphQL::ID_TYPE,
required: true,
description: "The project the alert to mutate is in"
argument :iid, GraphQL::STRING_TYPE,
required: true,
description: "The iid of the alert to mutate"
field :alert,
Types::AlertManagement::AlertType,
null: true,
description: "The alert after mutation"
private
def find_alert(project_path:, iid:)
project = resolve_project(full_path: project_path)
return unless project
resolver = Resolvers::AlertManagementAlertResolver.single.new(object: project, context: context, field: nil)
resolver.resolve(iid: iid)
end
end
end
end
# frozen_string_literal: true
module Mutations
module AlertManagement
class ChangeAlertStatus < Base
graphql_name 'ChangeAlertStatus'
argument :status, Types::AlertManagement::StatusEnum,
required: true,
description: "The status to set the alert"
def resolve(args)
alert = find_alert(project_path: args[:project_path], iid: args[:iid])
if alert
service = ::AlertManagement::AlertService.new(alert)
service.set_status!(args[:status])
else
self.errors = Array('Alert could not be found')
end
{
alert: alert,
errors: errors
}
end
private
attr_accessor :errors
end
end
end
......@@ -7,6 +7,7 @@ module Types
graphql_name 'Mutation'
mount_mutation Mutations::Admin::SidekiqQueues::DeleteJobs
mount_mutation Mutations::AlertManagement::ChangeAlertStatus
mount_mutation Mutations::AwardEmojis::Add
mount_mutation Mutations::AwardEmojis::Remove
mount_mutation Mutations::AwardEmojis::Toggle
......
# frozen_string_literal: true
module AlertManagement
class AlertService
attr_reader :alert
def initialize(alert)
@alert = alert
end
def set_status!(status)
return unless AlertManagement::Alert.statuses.key?(status.to_s)
# rubocop:disable GitlabSecurity/PublicSend
alert.public_send("#{status}!")
# rubocop:enable GitlabSecurity/PublicSend
end
end
end
......@@ -653,6 +653,51 @@ type Branch {
name: String!
}
"""
Autogenerated input type of ChangeAlertStatus
"""
input ChangeAlertStatusInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The iid of the alert to mutate
"""
iid: String!
"""
The project the alert to mutate is in
"""
projectPath: ID!
"""
The status to set the alert
"""
status: AlertManagementStatus!
}
"""
Autogenerated return type of ChangeAlertStatus
"""
type ChangeAlertStatusPayload {
"""
The alert after mutation
"""
alert: AlertManagementAlert
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Reasons why the mutation failed.
"""
errors: [String!]!
}
type Commit {
"""
Author of the commit
......@@ -6042,6 +6087,7 @@ type Mutation {
addProjectToSecurityDashboard(input: AddProjectToSecurityDashboardInput!): AddProjectToSecurityDashboardPayload
adminSidekiqQueuesDeleteJobs(input: AdminSidekiqQueuesDeleteJobsInput!): AdminSidekiqQueuesDeleteJobsPayload
boardListUpdateLimitMetrics(input: BoardListUpdateLimitMetricsInput!): BoardListUpdateLimitMetricsPayload
changeAlertStatus(input: ChangeAlertStatusInput!): ChangeAlertStatusPayload
createBranch(input: CreateBranchInput!): CreateBranchPayload
createDiffNote(input: CreateDiffNoteInput!): CreateDiffNotePayload
createEpic(input: CreateEpicInput!): CreateEpicPayload
......
......@@ -1888,6 +1888,136 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "ChangeAlertStatusInput",
"description": "Autogenerated input type of ChangeAlertStatus",
"fields": null,
"inputFields": [
{
"name": "projectPath",
"description": "The project the alert 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 alert to mutate",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "status",
"description": "The status to set the alert",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AlertManagementStatus",
"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": "ChangeAlertStatusPayload",
"description": "Autogenerated return type of ChangeAlertStatus",
"fields": [
{
"name": "alert",
"description": "The alert after mutation",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "AlertManagementAlert",
"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": "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
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "Commit",
......@@ -17265,6 +17395,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "changeAlertStatus",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "ChangeAlertStatusInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ChangeAlertStatusPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "createBranch",
"description": null,
......
......@@ -140,6 +140,16 @@ Autogenerated return type of BoardListUpdateLimitMetrics
| `commit` | Commit | Commit for the branch |
| `name` | String! | Name of the branch |
## ChangeAlertStatusPayload
Autogenerated return type of ChangeAlertStatus
| Name | Type | Description |
| --- | ---- | ---------- |
| `alert` | AlertManagementAlert | The alert after mutation |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Reasons why the mutation failed. |
## Commit
| Name | Type | Description |
......
# frozen_string_literal: true
require 'spec_helper'
describe Mutations::AlertManagement::ChangeAlertStatus do
let_it_be(:current_user) { create(:user) }
let_it_be(:alert) { create(:alert_management_alert) }
let(:project) { alert.project }
let(:new_status) { 'acknowledged' }
let(:args) { { status: new_status, project_path: project.full_path, iid: alert.iid } }
describe '#resolve' do
subject(:resolve) { mutation_for(project, current_user).resolve(args) }
context 'user has access to project' do
before do
project.add_developer(current_user)
end
it 'does not change the status' do
expect { resolve }.to change { alert.reload.status }.from(alert.status).to(new_status)
end
end
context 'user has no access' do
it 'does not change the status' do
expect { resolve }.not_to change { alert.reload.status }
end
it 'sets the error' do
expect(resolve.dig(:errors)).not_to be_empty
end
end
end
private
def mutation_for(project, user)
described_class.new(object: project, context: { current_user: user }, field: nil)
end
end
# frozen_string_literal: true
require 'spec_helper'
describe AlertManagement::AlertService do
let_it_be(:alert) { create(:alert_management_alert) }
let(:instance) { described_class.new(alert) }
describe '#set_status!' do
subject(:set_status) { instance.set_status!(new_status) }
let(:new_status) { 'acknowledged' }
it 'updates the status' do
expect { set_status }.to change { alert.status }.to(new_status)
end
context 'with unknown status' do
let(:new_status) { 'random_status' }
it { is_expected.to be_nil }
it 'does not update the status' do
expect { set_status }.not_to change { alert.status }
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