From 78a7ca9961c39b3ef055419a62e17f18b2660c40 Mon Sep 17 00:00:00 2001 From: Lee Tickett Date: Thu, 16 Feb 2023 15:59:39 +0000 Subject: [PATCH] Expose project visibleForks in GraphQL Changelog: added --- app/graphql/types/project_type.rb | 18 +++++++++ doc/api/graphql/reference/index.md | 20 ++++++++++ spec/graphql/types/project_type_spec.rb | 53 ++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 6fc76699590029..47690171bf2c6f 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -571,6 +571,16 @@ class ProjectType < BaseObject resolver: Resolvers::DataTransferResolver.project, description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.' + field :visible_forks, Types::ProjectType.connection_type, + null: true, + alpha: { milestone: '15.10' }, + description: "Visible forks of the project." do + argument :minimum_access_level, + type: ::Types::AccessLevelEnum, + required: false, + description: 'Minimum access level.' + end + def timelog_categories object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories) end @@ -659,6 +669,14 @@ def languages ::Projects::RepositoryLanguagesService.new(project, current_user).execute end + def visible_forks(minimum_access_level: nil) + if minimum_access_level.nil? + object.forks.public_or_visible_to_user(current_user) + else + object.forks.visible_to_user_and_access_level(current_user, minimum_access_level) + end + end + private def project diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 74e8035232bd80..055fb72dd75040 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -18933,6 +18933,26 @@ four standard [pagination arguments](#connection-pagination-arguments): | `startTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or after startTime. | | `username` | [`String`](#string) | List timelogs for a user. | +##### `Project.visibleForks` + +Visible forks of the project. + +WARNING: +**Introduced** in 15.10. +This feature is in Alpha. It can be changed or removed at any time. + +Returns [`ProjectConnection`](#projectconnection). + +This field returns a [connection](#connections). It accepts the +four standard [pagination arguments](#connection-pagination-arguments): +`before: String`, `after: String`, `first: Int`, `last: Int`. + +###### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `minimumAccessLevel` | [`AccessLevelEnum`](#accesslevelenum) | Minimum access level. | + ##### `Project.vulnerabilities` Vulnerabilities reported on the project. diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb index ea8018d4413313..7f26190830e3cf 100644 --- a/spec/graphql/types/project_type_spec.rb +++ b/spec/graphql/types/project_type_spec.rb @@ -4,6 +4,7 @@ RSpec.describe GitlabSchema.types['Project'] do include GraphqlHelpers + include ProjectForksHelper specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Project) } @@ -37,7 +38,7 @@ ci_template timelogs merge_commit_template squash_commit_template work_item_types recent_issue_boards ci_config_path_or_default packages_cleanup_policy ci_variables timelog_categories fork_targets branch_rules ci_config_variables pipeline_schedules languages - incident_management_timeline_event_tags + incident_management_timeline_event_tags visible_forks ] expect(described_class).to include_graphql_fields(*expected_fields) @@ -859,4 +860,54 @@ end end end + + describe 'visible_forks' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:fork_reporter) { fork_project(project, nil, { repository: true }) } + let_it_be(:fork_developer) { fork_project(project, nil, { repository: true }) } + let_it_be(:fork_group_developer) { fork_project(project, nil, { repository: true }) } + let_it_be(:fork_public) { fork_project(project, nil, { repository: true }) } + let_it_be(:fork_private) { fork_project(project, nil, { repository: true }) } + + let(:minimum_access_level) { '' } + let(:query) do + %( + query { + project(fullPath: "#{project.full_path}") { + visibleForks#{minimum_access_level} { + nodes { + fullPath + } + } + } + } + ) + end + + let(:forks) do + subject.dig('data', 'project', 'visibleForks', 'nodes') + end + + subject { GitlabSchema.execute(query, context: { current_user: user }).as_json } + + before do + fork_reporter.add_reporter(user) + fork_developer.add_developer(user) + fork_group_developer.group.add_developer(user) + end + + it 'contains all forks' do + expect(forks.count).to eq(5) + end + + context 'with minimum_access_level DEVELOPER' do + let(:minimum_access_level) { '(minimumAccessLevel: DEVELOPER)' } + + it 'contains forks with developer access' do + expect(forks).to contain_exactly(a_hash_including('fullPath' => fork_developer.full_path), +a_hash_including('fullPath' => fork_group_developer.full_path)) + end + end + end end -- GitLab