Commit ba9abda3 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera Committed by Alex Kalderimis

Add new group_packages_resolver

- source
- tests
parent 8361d840
# frozen_string_literal: true
module Resolvers
class GroupPackagesResolver < BaseResolver
type Types::Packages::PackageType.connection_type, null: true
def ready?(**args)
context[self.class] ||= { executions: 0 }
context[self.class][:executions] += 1
raise GraphQL::ExecutionError, "Packages can be requested only for one group at a time" if context[self.class][:executions] > 1
super
end
def resolve(**args)
return unless packages_available?
::Packages::GroupPackagesFinder.new(current_user, object).execute
end
private
def packages_available?
::Gitlab.config.packages.enabled
end
end
end
# frozen_string_literal: true
module Resolvers
class PackagesResolver < BaseResolver
class ProjectPackagesResolver < BaseResolver
type Types::Packages::PackageType.connection_type, null: true
def resolve(**args)
......
......@@ -95,6 +95,10 @@ module Types
field :container_repositories_count, GraphQL::INT_TYPE, null: false,
description: 'Number of container repositories in the group.'
field :packages,
description: 'Packages of the group.',
resolver: Resolvers::GroupPackagesResolver
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
LabelsFinder
......
......@@ -181,7 +181,7 @@ module Types
field :packages,
description: 'Packages of the project.',
resolver: Resolvers::PackagesResolver
resolver: Resolvers::ProjectPackagesResolver
field :pipelines,
null: true,
......
---
title: Add package list to group graphql type
merge_request: 54672
author:
type: added
......@@ -2215,6 +2215,7 @@ Autogenerated return type of GitlabSubscriptionActivate.
| `milestones` | MilestoneConnection | Milestones of the group. |
| `name` | String! | Name of the namespace. |
| `packageSettings` | PackageSettings | The package settings for the namespace. |
| `packages` | PackageConnection | Packages of the group. |
| `parent` | Group | Parent group. |
| `path` | String! | Path of the namespace. |
| `projectCreationLevel` | String | The permission level required to create projects in the group. |
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::GroupPackagesResolver do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, group: group) }
let_it_be(:package) { create(:package, project: project) }
describe '#resolve' do
subject(:packages) { resolve(described_class, ctx: { current_user: user }, obj: group) }
it { is_expected.to contain_exactly(package) }
end
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Resolvers::PackagesResolver do
RSpec.describe Resolvers::ProjectPackagesResolver do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
......
......@@ -18,6 +18,7 @@ RSpec.describe GitlabSchema.types['Group'] do
two_factor_grace_period auto_devops_enabled emails_disabled
mentions_disabled parent boards milestones group_members
merge_requests container_repositories container_repositories_count
packages
]
expect(described_class).to include_graphql_fields(*expected_fields)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'getting a package list for a group' do
include GraphqlHelpers
let_it_be(:resource) { create(:group, :private) }
let_it_be(:group_two) { create(:group, :private) }
let_it_be(:project) { create(:project, :repository, group: resource) }
let_it_be(:another_project) { create(:project, :repository, group: resource) }
let_it_be(:group_two_project) { create(:project, :repository, group: group_two) }
let_it_be(:current_user) { create(:user) }
let_it_be(:package) { create(:package, project: project) }
let_it_be(:npm_package) { create(:npm_package, project: group_two_project) }
let_it_be(:maven_package) { create(:maven_package, project: project) }
let_it_be(:debian_package) { create(:debian_package, project: another_project) }
let_it_be(:composer_package) { create(:composer_package, project: another_project) }
let_it_be(:composer_metadatum) do
create(:composer_metadatum, package: composer_package,
target_sha: 'afdeh',
composer_json: { name: 'x', type: 'y', license: 'z', version: 1 })
end
let(:package_names) { graphql_data_at(:group, :packages, :nodes, :name) }
let(:target_shas) { graphql_data_at(:group, :packages, :nodes, :metadata, :target_sha) }
let(:packages) { graphql_data_at(:group, :packages, :nodes) }
let(:fields) do
<<~QUERY
nodes {
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
metadata { #{query_graphql_fragment('ComposerMetadata')} }
}
QUERY
end
let(:query) do
graphql_query_for(
'group',
{ 'fullPath' => resource.full_path },
query_graphql_field('packages', {}, fields)
)
end
it_behaves_like 'group and project packages query'
context 'with a batched query' do
let(:batch_query) do
<<~QUERY
{
a: group(fullPath: "#{resource.full_path}") { packages { nodes { name } } }
b: group(fullPath: "#{group_two.full_path}") { packages { nodes { name } } }
}
QUERY
end
let(:a_packages_names) { graphql_data_at(:a, :packages, :nodes, :name) }
before do
resource.add_reporter(current_user)
group_two.add_reporter(current_user)
post_graphql(batch_query, current_user: current_user)
end
it 'returns an error for the second group and data for the first' do
expect(a_packages_names).to contain_exactly(
package.name,
maven_package.name,
debian_package.name,
composer_package.name
)
expect_graphql_errors_to_include [/Packages can be requested only for one group at a time/]
expect(graphql_data_at(:b, :packages)).to be(nil)
end
end
end
......@@ -5,84 +5,39 @@ require 'spec_helper'
RSpec.describe 'getting a package list for a project' do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
let_it_be(:resource) { create(:project, :repository) }
let_it_be(:current_user) { create(:user) }
let_it_be(:package) { create(:package, project: project) }
let_it_be(:maven_package) { create(:maven_package, project: project) }
let_it_be(:debian_package) { create(:debian_package, project: project) }
let_it_be(:composer_package) { create(:composer_package, project: project) }
let_it_be(:package) { create(:package, project: resource) }
let_it_be(:maven_package) { create(:maven_package, project: resource) }
let_it_be(:debian_package) { create(:debian_package, project: resource) }
let_it_be(:composer_package) { create(:composer_package, project: resource) }
let_it_be(:composer_metadatum) do
create(:composer_metadatum, package: composer_package,
target_sha: 'afdeh',
composer_json: { name: 'x', type: 'y', license: 'z', version: 1 })
end
let(:package_names) { graphql_data_at(:project, :packages, :edges, :node, :name) }
let(:package_names) { graphql_data_at(:project, :packages, :nodes, :name) }
let(:target_shas) { graphql_data_at(:project, :packages, :nodes, :metadata, :target_sha) }
let(:packages) { graphql_data_at(:project, :packages, :nodes) }
let(:fields) do
<<~QUERY
edges {
node {
nodes {
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
metadata { #{query_graphql_fragment('ComposerMetadata')} }
}
}
QUERY
end
let(:query) do
graphql_query_for(
'project',
{ 'fullPath' => project.full_path },
{ 'fullPath' => resource.full_path },
query_graphql_field('packages', {}, fields)
)
end
context 'when user has access to the project' do
before do
project.add_reporter(current_user)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'returns packages successfully' do
expect(package_names).to contain_exactly(
package.name,
maven_package.name,
debian_package.name,
composer_package.name
)
end
it 'deals with metadata' do
target_shas = graphql_data_at(:project, :packages, :edges, :node, :metadata, :target_sha)
expect(target_shas).to contain_exactly(composer_metadatum.target_sha)
end
end
context 'when the user does not have access to the project/packages' do
before do
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'returns nil' do
expect(graphql_data['project']).to be_nil
end
end
context 'when the user is not authenticated' do
before do
post_graphql(query)
end
it_behaves_like 'a working graphql query'
it 'returns nil' do
expect(graphql_data['project']).to be_nil
end
end
it_behaves_like 'group and project packages query'
end
# frozen_string_literal: true
RSpec.shared_examples 'group and project packages query' do
include GraphqlHelpers
context 'when user has access to the resource' do
before do
resource.add_reporter(current_user)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'returns packages successfully' do
expect(package_names).to contain_exactly(
package.name,
maven_package.name,
debian_package.name,
composer_package.name
)
end
it 'deals with metadata' do
expect(target_shas).to contain_exactly(composer_metadatum.target_sha)
end
end
context 'when the user does not have access to the resource' do
before do
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'returns nil' do
expect(packages).to be_nil
end
end
context 'when the user is not authenticated' do
before do
post_graphql(query)
end
it_behaves_like 'a working graphql query'
it 'returns nil' do
expect(packages).to be_nil
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