summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/graphql/mutations/.keep0
-rw-r--r--app/graphql/mutations/award_emojis/add.rb25
-rw-r--r--app/graphql/mutations/award_emojis/base.rb41
-rw-r--r--app/graphql/mutations/award_emojis/remove.rb33
-rw-r--r--app/graphql/mutations/award_emojis/toggle.rb40
-rw-r--r--app/graphql/mutations/base_mutation.rb7
-rw-r--r--app/graphql/types/award_emojis/award_emoji_type.rb46
-rw-r--r--app/graphql/types/mutation_type.rb3
-rw-r--r--app/models/snippet.rb4
-rw-r--r--app/policies/award_emoji_policy.rb11
-rw-r--r--app/presenters/award_emoji_presenter.rb27
11 files changed, 237 insertions, 0 deletions
diff --git a/app/graphql/mutations/.keep b/app/graphql/mutations/.keep
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/app/graphql/mutations/.keep
+++ /dev/null
diff --git a/app/graphql/mutations/award_emojis/add.rb b/app/graphql/mutations/award_emojis/add.rb
new file mode 100644
index 00000000000..8e050dd6d29
--- /dev/null
+++ b/app/graphql/mutations/award_emojis/add.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Mutations
+ module AwardEmojis
+ class Add < Base
+ graphql_name 'AddAwardEmoji'
+
+ def resolve(args)
+ awardable = authorized_find!(id: args[:awardable_id])
+
+ check_object_is_awardable!(awardable)
+
+ # TODO this will be handled by AwardEmoji::AddService
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/63372 and
+ # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/29782
+ award = awardable.create_award_emoji(args[:name], current_user)
+
+ {
+ award_emoji: (award if award.persisted?),
+ errors: errors_on_object(award)
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/award_emojis/base.rb b/app/graphql/mutations/award_emojis/base.rb
new file mode 100644
index 00000000000..d868db84f9d
--- /dev/null
+++ b/app/graphql/mutations/award_emojis/base.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Mutations
+ module AwardEmojis
+ class Base < BaseMutation
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorize :award_emoji
+
+ argument :awardable_id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the awardable resource'
+
+ argument :name,
+ GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::AwardEmojis::AwardEmojiType, :name)
+
+ field :award_emoji,
+ Types::AwardEmojis::AwardEmojiType,
+ null: true,
+ description: 'The award emoji after mutation'
+
+ private
+
+ def find_object(id:)
+ GitlabSchema.object_from_id(id)
+ end
+
+ # Called by mutations methods after performing an authorization check
+ # of an awardable object.
+ def check_object_is_awardable!(object)
+ unless object.is_a?(Awardable) && object.emoji_awardable?
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable,
+ 'Cannot award emoji to this resource'
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/award_emojis/remove.rb b/app/graphql/mutations/award_emojis/remove.rb
new file mode 100644
index 00000000000..3ba85e445b8
--- /dev/null
+++ b/app/graphql/mutations/award_emojis/remove.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Mutations
+ module AwardEmojis
+ class Remove < Base
+ graphql_name 'RemoveAwardEmoji'
+
+ def resolve(args)
+ awardable = authorized_find!(id: args[:awardable_id])
+
+ check_object_is_awardable!(awardable)
+
+ # TODO this check can be removed once AwardEmoji services are available.
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/63372 and
+ # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/29782
+ unless awardable.awarded_emoji?(args[:name], current_user)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable,
+ 'You have not awarded emoji of type name to the awardable'
+ end
+
+ # TODO this will be handled by AwardEmoji::DestroyService
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/63372 and
+ # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/29782
+ awardable.remove_award_emoji(args[:name], current_user)
+
+ {
+ # Mutation response is always a `nil` award_emoji
+ errors: []
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/award_emojis/toggle.rb b/app/graphql/mutations/award_emojis/toggle.rb
new file mode 100644
index 00000000000..c03902e8035
--- /dev/null
+++ b/app/graphql/mutations/award_emojis/toggle.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Mutations
+ module AwardEmojis
+ class Toggle < Base
+ graphql_name 'ToggleAwardEmoji'
+
+ field :toggledOn,
+ GraphQL::BOOLEAN_TYPE,
+ null: false,
+ description: 'True when the emoji was awarded, false when it was removed'
+
+ def resolve(args)
+ awardable = authorized_find!(id: args[:awardable_id])
+
+ check_object_is_awardable!(awardable)
+
+ # TODO this will be handled by AwardEmoji::ToggleService
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/63372 and
+ # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/29782
+ award = awardable.toggle_award_emoji(args[:name], current_user)
+
+ # Destroy returns a collection :(
+ award = award.first if award.is_a?(Array)
+
+ errors = errors_on_object(award)
+
+ toggled_on = awardable.awarded_emoji?(args[:name], current_user)
+
+ {
+ # For consistency with the AwardEmojis::Remove mutation, only return
+ # the AwardEmoji if it was created and not destroyed
+ award_emoji: (award if toggled_on),
+ errors: errors,
+ toggled_on: toggled_on
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/base_mutation.rb b/app/graphql/mutations/base_mutation.rb
index eb03dfe1624..08d2a1f18a3 100644
--- a/app/graphql/mutations/base_mutation.rb
+++ b/app/graphql/mutations/base_mutation.rb
@@ -2,6 +2,8 @@
module Mutations
class BaseMutation < GraphQL::Schema::RelayClassicMutation
+ prepend Gitlab::Graphql::CopyFieldDescription
+
field :errors, [GraphQL::STRING_TYPE],
null: false,
description: "Reasons why the mutation failed."
@@ -9,5 +11,10 @@ module Mutations
def current_user
context[:current_user]
end
+
+ # Returns Array of errors on an ActiveRecord object
+ def errors_on_object(record)
+ record.errors.full_messages
+ end
end
end
diff --git a/app/graphql/types/award_emojis/award_emoji_type.rb b/app/graphql/types/award_emojis/award_emoji_type.rb
new file mode 100644
index 00000000000..8daf699a112
--- /dev/null
+++ b/app/graphql/types/award_emojis/award_emoji_type.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Types
+ module AwardEmojis
+ class AwardEmojiType < BaseObject
+ graphql_name 'AwardEmoji'
+
+ authorize :read_emoji
+
+ present_using AwardEmojiPresenter
+
+ field :name,
+ GraphQL::STRING_TYPE,
+ null: false,
+ description: 'The emoji name'
+
+ field :description,
+ GraphQL::STRING_TYPE,
+ null: false,
+ description: 'The emoji description'
+
+ field :unicode,
+ GraphQL::STRING_TYPE,
+ null: false,
+ description: 'The emoji in unicode'
+
+ field :emoji,
+ GraphQL::STRING_TYPE,
+ null: false,
+ description: 'The emoji as an icon'
+
+ field :unicode_version,
+ GraphQL::STRING_TYPE,
+ null: false,
+ description: 'The unicode version for this emoji'
+
+ field :user,
+ Types::UserType,
+ null: false,
+ description: 'The user who awarded the emoji',
+ resolve: -> (award_emoji, _args, _context) {
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, award_emoji.user_id).find
+ }
+ end
+ end
+end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 2b4ef299296..6ef1d816b7c 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -6,6 +6,9 @@ module Types
graphql_name "Mutation"
+ mount_mutation Mutations::AwardEmojis::Add
+ mount_mutation Mutations::AwardEmojis::Remove
+ mount_mutation Mutations::AwardEmojis::Toggle
mount_mutation Mutations::MergeRequests::SetWip
end
end
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index f4fdac2558c..00931457344 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -194,6 +194,10 @@ class Snippet < ApplicationRecord
'snippet'
end
+ def to_ability_name
+ model_name.singular
+ end
+
class << self
# Searches for snippets with a matching title or file name.
#
diff --git a/app/policies/award_emoji_policy.rb b/app/policies/award_emoji_policy.rb
new file mode 100644
index 00000000000..21e382e24b3
--- /dev/null
+++ b/app/policies/award_emoji_policy.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AwardEmojiPolicy < BasePolicy
+ delegate { @subject.awardable if DeclarativePolicy.has_policy?(@subject.awardable) }
+
+ condition(:can_read_awardable) do
+ can?(:"read_#{@subject.awardable.to_ability_name}")
+ end
+
+ rule { can_read_awardable }.enable :read_emoji
+end
diff --git a/app/presenters/award_emoji_presenter.rb b/app/presenters/award_emoji_presenter.rb
new file mode 100644
index 00000000000..98713855d35
--- /dev/null
+++ b/app/presenters/award_emoji_presenter.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class AwardEmojiPresenter < Gitlab::View::Presenter::Delegated
+ presents :award_emoji
+
+ def description
+ as_emoji['description']
+ end
+
+ def unicode
+ as_emoji['unicode']
+ end
+
+ def emoji
+ as_emoji['moji']
+ end
+
+ def unicode_version
+ Gitlab::Emoji.emoji_unicode_version(award_emoji.name)
+ end
+
+ private
+
+ def as_emoji
+ @emoji ||= Gitlab::Emoji.emojis[award_emoji.name] || {}
+ end
+end