summaryrefslogtreecommitdiff
path: root/app/graphql/types/work_item_id_type.rb
blob: ddcf3416014825339505795518b398f7a307a474 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# frozen_string_literal: true

module Types
  # rubocop:disable Graphql/AuthorizeTypes
  # TODO: This type should be removed when Work Items become generally available.
  # This mechanism is introduced temporarily to make the client implementation easier during this transition.
  class WorkItemIdType < GlobalIDType
    graphql_name 'WorkItemID'
    description <<~DESC
      A `WorkItemID` is a global ID. It is encoded as a string.

      An example `WorkItemID` is: `"gid://gitlab/WorkItem/1"`.

      While we transition from Issues into Work Items this type will temporarily support
      `IssueID` like: `"gid://gitlab/Issue/1"`. This behavior will be removed without notice in the future.
    DESC

    class << self
      def coerce_result(gid, ctx)
        global_id = ::Gitlab::GlobalId.as_global_id(gid, model_name: 'WorkItem')

        raise GraphQL::CoercionError, "Expected a WorkItem ID, got #{global_id}" unless suitable?(global_id)

        # Always return a WorkItemID even if an Issue is returned by a resolver
        work_item_gid(global_id).to_s
      end

      def coerce_input(string, ctx)
        gid = super
        # Always return a WorkItemID even if an Issue Global ID is provided as input
        return work_item_gid(gid) if suitable?(gid)

        raise GraphQL::CoercionError, "#{string.inspect} does not represent an instance of WorkItem"
      end

      def suitable?(gid)
        return false if gid&.model_name&.safe_constantize.blank?

        [::WorkItem, ::Issue].any? { |model_class| gid.model_class == model_class }
      end

      private

      def work_item_gid(gid)
        GlobalID.new(::Gitlab::GlobalId.build(model_name: 'WorkItem', id: gid.model_id))
      end
    end
  end
  # rubocop:enable Graphql/AuthorizeTypes
end