Commit e8ee5559 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch '214583-add-ability-to-query-projects' into 'master'

Add ability to query projects in GraphQL API

See merge request gitlab-org/gitlab!30146
parents ab48660d 0da8fa97
# frozen_string_literal: true
module Resolvers
class ProjectsResolver < BaseResolver
type Types::ProjectType, null: true
argument :membership, GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Limit projects that the current user is a member of'
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search criteria'
def resolve(**args)
ProjectsFinder
.new(current_user: current_user, params: project_finder_params(args))
.execute
end
private
def project_finder_params(params)
{
without_deleted: true,
non_public: params[:membership],
search: params[:search]
}.compact
end
end
end
...@@ -9,6 +9,11 @@ module Types ...@@ -9,6 +9,11 @@ module Types
resolver: Resolvers::ProjectResolver, resolver: Resolvers::ProjectResolver,
description: "Find a project" description: "Find a project"
field :projects, Types::ProjectType.connection_type,
null: true,
resolver: Resolvers::ProjectsResolver,
description: "Find projects visible to the current user"
field :group, Types::GroupType, field :group, Types::GroupType,
null: true, null: true,
resolver: Resolvers::GroupResolver, resolver: Resolvers::GroupResolver,
......
---
title: Add ability to query Projects using GraphQL API
merge_request: 30146
author:
type: added
...@@ -8088,6 +8088,41 @@ type Query { ...@@ -8088,6 +8088,41 @@ type Query {
fullPath: ID! fullPath: ID!
): Project ): Project
"""
Find projects visible to the current user
"""
projects(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
"""
Limit projects that the current user is a member of
"""
membership: Boolean
"""
Search criteria
"""
search: String
): ProjectConnection
""" """
Find Snippets visible to the current user Find Snippets visible to the current user
""" """
......
...@@ -23887,6 +23887,79 @@ ...@@ -23887,6 +23887,79 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "projects",
"description": "Find projects visible to the current user",
"args": [
{
"name": "membership",
"description": "Limit projects that the current user is a member of",
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": null
},
{
"name": "search",
"description": "Search criteria",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ProjectConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "snippets", "name": "snippets",
"description": "Find Snippets visible to the current user", "description": "Find Snippets visible to the current user",
......
# frozen_string_literal: true
require 'spec_helper'
describe Resolvers::ProjectsResolver do
include GraphqlHelpers
describe '#resolve' do
subject { resolve(described_class, obj: nil, args: filters, ctx: { current_user: current_user }) }
let_it_be(:project) { create(:project, :public) }
let_it_be(:other_project) { create(:project, :public) }
let_it_be(:private_project) { create(:project, :private) }
let_it_be(:other_private_project) { create(:project, :private) }
let_it_be(:user) { create(:user) }
let(:filters) { {} }
before_all do
project.add_developer(user)
private_project.add_developer(user)
end
context 'when user is not logged in' do
let(:current_user) { nil }
context 'when no filters are applied' do
it 'returns all public projects' do
is_expected.to contain_exactly(project, other_project)
end
context 'when search filter is provided' do
let(:filters) { { search: project.name } }
it 'returns matching project' do
is_expected.to contain_exactly(project)
end
end
context 'when membership filter is provided' do
let(:filters) { { membership: true } }
it 'returns empty list' do
is_expected.to be_empty
end
end
end
end
context 'when user is logged in' do
let(:current_user) { user }
context 'when no filters are applied' do
it 'returns all visible projects for the user' do
is_expected.to contain_exactly(project, other_project, private_project)
end
context 'when search filter is provided' do
let(:filters) { { search: project.name } }
it 'returns matching project' do
is_expected.to contain_exactly(project)
end
end
context 'when membership filter is provided' do
let(:filters) { { membership: true } }
it 'returns projects that user is member of' do
is_expected.to contain_exactly(project, private_project)
end
end
end
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