Commit 98e6883a authored by Sean McGivern's avatar Sean McGivern

Merge branch '239562-graphql-add-starredprojects-to-user' into 'master'

Expose a list of projects starred by the user to GraphQL API

Closes #239562

See merge request gitlab-org/gitlab!41076
parents 5b63ea38 1be3d5e6
# frozen_string_literal: true
module Resolvers
class UserStarredProjectsResolver < BaseResolver
type Types::ProjectType, null: true
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search query'
alias_method :user, :object
def resolve(**args)
StarredProjectsFinder.new(user, params: args, current_user: current_user).execute
end
end
end
......@@ -37,6 +37,9 @@ module Types
field :project_memberships, Types::ProjectMemberType.connection_type, null: true,
description: 'Project memberships of the user',
method: :project_members
field :starred_projects, Types::ProjectType.connection_type, null: true,
description: 'Projects starred by the user',
resolver: Resolvers::UserStarredProjectsResolver
# Merge request field: MRs can be either authored or assigned:
field :authored_merge_requests, Types::MergeRequestType.connection_type, null: true,
......
---
title: Expose a list of projects starred by the user to GraphQL API
author: Pavel Kuznetsov
merge_request: 41076
type: added
......@@ -17557,6 +17557,36 @@ type User {
visibility: VisibilityScopesEnum
): SnippetConnection
"""
Projects starred by the user
"""
starredProjects(
"""
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
"""
Search query
"""
search: String
): ProjectConnection
"""
State of the user
"""
......
......@@ -51381,6 +51381,69 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "starredProjects",
"description": "Projects starred by the user",
"args": [
{
"name": "search",
"description": "Search query",
"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": "state",
"description": "State of the user",
......@@ -25,6 +25,7 @@ RSpec.describe GitlabSchema.types['User'] do
assignedMergeRequests
groupMemberships
projectMemberships
starredProjects
]
expect(described_class).to have_graphql_fields(*expected_fields)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Getting starredProjects of the user' do
include GraphqlHelpers
let(:query) do
graphql_query_for(:user, user_params, user_fields)
end
let(:user_params) { { username: user.username } }
let_it_be(:project_a) { create(:project, :public) }
let_it_be(:project_b) { create(:project, :private) }
let_it_be(:project_c) { create(:project, :private) }
let_it_be(:user, reload: true) { create(:user) }
let(:user_fields) { 'starredProjects { nodes { id } }' }
let(:starred_projects) { graphql_data_at(:user, :starred_projects, :nodes) }
before do
project_b.add_reporter(user)
project_c.add_reporter(user)
user.toggle_star(project_a)
user.toggle_star(project_b)
user.toggle_star(project_c)
post_graphql(query)
end
it_behaves_like 'a working graphql query'
it 'found only public project' do
expect(starred_projects).to contain_exactly(
a_hash_including('id' => global_id_of(project_a))
)
end
context 'the current user is the user' do
let(:current_user) { user }
before do
post_graphql(query, current_user: current_user)
end
it 'found all projects' do
expect(starred_projects).to contain_exactly(
a_hash_including('id' => global_id_of(project_a)),
a_hash_including('id' => global_id_of(project_b)),
a_hash_including('id' => global_id_of(project_c))
)
end
end
context 'the current user is a member of a private project the user starred' do
let_it_be(:other_user) { create(:user) }
before do
project_b.add_reporter(other_user)
post_graphql(query, current_user: other_user)
end
it 'finds public and member projects' do
expect(starred_projects).to contain_exactly(
a_hash_including('id' => global_id_of(project_a)),
a_hash_including('id' => global_id_of(project_b))
)
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