diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb index 31850c2cadba9ec82b1bc3b80cf78a9ac7767303..5b7eb57841c9fe3ef899aa8458edaafe3c586a29 100644 --- a/app/graphql/resolvers/base_resolver.rb +++ b/app/graphql/resolvers/base_resolver.rb @@ -10,7 +10,7 @@ module Resolvers end end - def self.resolver_complexity(args) + def self.resolver_complexity(args, child_complexity:) complexity = 1 complexity += 1 if args[:sort] complexity += 5 if args[:search] diff --git a/app/graphql/resolvers/concerns/resolves_pipelines.rb b/app/graphql/resolvers/concerns/resolves_pipelines.rb index a166211fc1899926cce020dc620df2b068b052a6..a6f82cc8505612eb11b21599fe854bd6a573cf82 100644 --- a/app/graphql/resolvers/concerns/resolves_pipelines.rb +++ b/app/graphql/resolvers/concerns/resolves_pipelines.rb @@ -20,7 +20,7 @@ module ResolvesPipelines end class_methods do - def resolver_complexity(args) + def resolver_complexity(args, child_complexity:) complexity = super complexity += 2 if args[:sha] complexity += 2 if args[:ref] diff --git a/app/graphql/resolvers/issues_resolver.rb b/app/graphql/resolvers/issues_resolver.rb index f7e49166ca041c8e0120fc97380c1c5719c9dd88..3ee3849f483cb527d0879195baaa402c0023beff 100644 --- a/app/graphql/resolvers/issues_resolver.rb +++ b/app/graphql/resolvers/issues_resolver.rb @@ -58,7 +58,7 @@ module Resolvers IssuesFinder.new(context[:current_user], args).execute end - def self.resolver_complexity(args) + def self.resolver_complexity(args, child_complexity:) complexity = super complexity += 2 if args[:labelName] diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb index 153311291346b27fd2a7e5f25f0ab10010151013..a374851e8356e3300cfef8e88576f2ac16a88942 100644 --- a/app/graphql/types/base_field.rb +++ b/app/graphql/types/base_field.rb @@ -33,7 +33,7 @@ module Types limit_value = [args[:first], args[:last], page_size].compact.min # Resolvers may add extra complexity depending on used arguments - complexity = child_complexity + self.resolver&.try(:resolver_complexity, args).to_i + complexity = child_complexity + self.resolver&.try(:resolver_complexity, args, child_complexity: child_complexity).to_i # Resolvers may add extra complexity depending on number of items being loaded. multiplier = self.resolver&.try(:complexity_multiplier, args).to_f diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index b21a226d07fee4a614de57e1b579d5cbb50c6a64..dd5133189dc92e19e23393d99ae1ef4343483e7d 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -15,6 +15,10 @@ module Types field :description, GraphQL::STRING_TYPE, null: true field :state, IssueStateEnum, null: false + field :reference, GraphQL::STRING_TYPE, null: false, method: :to_reference do + argument :full, GraphQL::BOOLEAN_TYPE, required: false, default_value: false + end + field :author, Types::UserType, null: false, resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find } @@ -37,7 +41,9 @@ module Types field :upvotes, GraphQL::INT_TYPE, null: false field :downvotes, GraphQL::INT_TYPE, null: false field :user_notes_count, GraphQL::INT_TYPE, null: false + field :web_path, GraphQL::STRING_TYPE, null: false, method: :issue_path field :web_url, GraphQL::STRING_TYPE, null: false + field :relative_position, GraphQL::INT_TYPE, null: true field :closed_at, Types::TimeType, null: true diff --git a/app/presenters/issue_presenter.rb b/app/presenters/issue_presenter.rb index c12a202efbc52f974984b8b8ace40a8db80728b8..c9dc0dbf443d1beea40d20fd628bda660497d827 100644 --- a/app/presenters/issue_presenter.rb +++ b/app/presenters/issue_presenter.rb @@ -4,6 +4,16 @@ class IssuePresenter < Gitlab::View::Presenter::Delegated presents :issue def web_url - Gitlab::UrlBuilder.build(issue) + url_builder.url + end + + def issue_path + url_builder.issue_path(issue) + end + + private + + def url_builder + @url_builder ||= Gitlab::UrlBuilder.new(issue) end end diff --git a/changelogs/unreleased/10795-add-epic-tree-BE-CE-epic-graphql-support.yml b/changelogs/unreleased/10795-add-epic-tree-BE-CE-epic-graphql-support.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c85d4f9acbbcd33f4a6a2abf76336cf74d7c188 --- /dev/null +++ b/changelogs/unreleased/10795-add-epic-tree-BE-CE-epic-graphql-support.yml @@ -0,0 +1,5 @@ +--- +title: Added reference, web_path, and relative_position fields to GraphQL Issue +merge_request: 28998 +author: +type: changed diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb index 4fe426e244753fbaec0b677b2f67a85e192de218..a7fb156d9a86c3a9025c23a77747836f5e58cea3 100644 --- a/spec/graphql/types/base_field_spec.rb +++ b/spec/graphql/types/base_field_spec.rb @@ -6,7 +6,7 @@ describe Types::BaseField do context 'when considering complexity' do let(:resolver) do Class.new(described_class) do - def self.resolver_complexity(args) + def self.resolver_complexity(args, child_complexity:) 2 if args[:foo] end diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb index dc37b15001fec79a45f91def289cc0d6f21abeb5..bae560829cce3e4c3f447c5005dad2a9bc324040 100644 --- a/spec/graphql/types/issue_type_spec.rb +++ b/spec/graphql/types/issue_type_spec.rb @@ -6,4 +6,10 @@ describe GitlabSchema.types['Issue'] do it { expect(described_class.graphql_name).to eq('Issue') } it { expect(described_class).to require_graphql_authorizations(:read_issue) } + + it 'has specific fields' do + %i[relative_position web_path web_url reference].each do |field_name| + expect(described_class).to have_graphql_field(field_name) + end + end end diff --git a/spec/presenters/issue_presenter_spec.rb b/spec/presenters/issue_presenter_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..8e24559341b2da646a3397b5aec592bad7c12d16 --- /dev/null +++ b/spec/presenters/issue_presenter_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe IssuePresenter do + include Gitlab::Routing.url_helpers + + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project) { create(:project, group: group) } + let(:issue) { create(:issue, project: project) } + let(:presenter) { described_class.new(issue, current_user: user) } + + before do + group.add_developer(user) + end + + describe '#web_url' do + it 'returns correct path' do + expect(presenter.web_url).to eq "http://localhost/#{group.name}/#{project.name}/issues/#{issue.iid}" + end + end + + describe '#issue_path' do + it 'returns correct path' do + expect(presenter.issue_path).to eq "/#{group.name}/#{project.name}/issues/#{issue.iid}" + end + end +end