Commit 5abc620d authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch '230903-graphql-fetch-single-list-under-board' into 'master'

Add option to query a single board list with GraphQL API

See merge request gitlab-org/gitlab!38216
parents 8d210259 e8be72d3
...@@ -6,12 +6,16 @@ module Resolvers ...@@ -6,12 +6,16 @@ module Resolvers
type Types::BoardListType, null: true type Types::BoardListType, null: true
argument :id, GraphQL::ID_TYPE,
required: false,
description: 'Find a list by its global ID'
alias_method :board, :object alias_method :board, :object
def resolve(lookahead: nil) def resolve(lookahead: nil, id: nil)
authorize!(board) authorize!(board)
lists = board_lists lists = board_lists(id)
if load_preferences?(lookahead) if load_preferences?(lookahead)
List.preload_preferences_for_user(lists, context[:current_user]) List.preload_preferences_for_user(lists, context[:current_user])
...@@ -22,8 +26,13 @@ module Resolvers ...@@ -22,8 +26,13 @@ module Resolvers
private private
def board_lists def board_lists(id)
service = Boards::Lists::ListService.new(board.resource_parent, context[:current_user]) service = Boards::Lists::ListService.new(
board.resource_parent,
context[:current_user],
list_id: extract_list_id(id)
)
service.execute(board, create_default_lists: false) service.execute(board, create_default_lists: false)
end end
...@@ -34,5 +43,11 @@ module Resolvers ...@@ -34,5 +43,11 @@ module Resolvers
def load_preferences?(lookahead) def load_preferences?(lookahead)
lookahead&.selection(:edges)&.selection(:node)&.selects?(:collapsed) lookahead&.selection(:edges)&.selection(:node)&.selects?(:collapsed)
end end
def extract_list_id(gid)
return unless gid.present?
GitlabSchema.parse_gid(gid, expected_type: ::List).model_id
end
end end
end end
...@@ -8,7 +8,8 @@ module Boards ...@@ -8,7 +8,8 @@ module Boards
board.lists.create(list_type: :backlog) board.lists.create(list_type: :backlog)
end end
board.lists.preload_associated_models lists = board.lists.preload_associated_models
params[:list_id].present? ? lists.where(id: params[:list_id]) : lists # rubocop: disable CodeReuse/ActiveRecord
end end
end end
end end
......
---
title: Add option to query a single board list with GraphQL API
merge_request: 38216
author:
type: added
...@@ -956,6 +956,11 @@ type Board { ...@@ -956,6 +956,11 @@ type Board {
""" """
first: Int first: Int
"""
Find a list by its global ID
"""
id: ID
""" """
Returns the last _n_ elements from the list. Returns the last _n_ elements from the list.
""" """
......
...@@ -2508,6 +2508,16 @@ ...@@ -2508,6 +2508,16 @@
"name": "lists", "name": "lists",
"description": "Lists of the board", "description": "Lists of the board",
"args": [ "args": [
{
"name": "id",
"description": "Find a list by its global ID",
"type": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
},
"defaultValue": null
},
{ {
"name": "after", "name": "after",
"description": "Returns the elements in the list that come after the specified cursor.", "description": "Returns the elements in the list that come after the specified cursor.",
...@@ -57,6 +57,30 @@ RSpec.describe Resolvers::BoardListsResolver do ...@@ -57,6 +57,30 @@ RSpec.describe Resolvers::BoardListsResolver do
expect(lists.count).to eq 3 expect(lists.count).to eq 3
end end
end end
context 'when querying for a single list' do
it 'returns specified list' do
list = resolve_board_lists(args: { id: global_id_of(label_list) }).items
expect(list).to eq [label_list]
end
it 'returns empty result if list is not found' do
external_group = create(:group, :private)
external_board = create(:board, resource_parent: external_group )
external_label = create(:group_label, group: group)
external_list = create(:list, board: external_board, label: external_label)
list = resolve_board_lists(args: { id: global_id_of(external_list) }).items
expect(list).to eq List.none
end
it 'raises an argument error if list ID is not valid' do
expect { resolve_board_lists(args: { id: 'test' }).items }
.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
end
end end
end end
......
...@@ -105,6 +105,20 @@ RSpec.describe 'get board lists' do ...@@ -105,6 +105,20 @@ RSpec.describe 'get board lists' do
end end
end end
end end
context 'when querying for a single list' do
before do
board_parent.add_reporter(user)
end
it 'finds the correct list' do
label_list = create(:list, board: board, label: label, position: 10)
post_graphql(query("id: \"#{global_id_of(label_list)}\""), current_user: user)
expect(lists_data[0]['node']['title']).to eq label_list.title
end
end
end end
describe 'for a project' do describe 'for a project' do
......
...@@ -6,12 +6,14 @@ RSpec.describe Boards::Lists::ListService do ...@@ -6,12 +6,14 @@ RSpec.describe Boards::Lists::ListService do
let(:user) { create(:user) } let(:user) { create(:user) }
describe '#execute' do describe '#execute' do
let(:service) { described_class.new(parent, user) }
context 'when board parent is a project' do context 'when board parent is a project' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:board) { create(:board, project: project) } let(:board) { create(:board, project: project) }
let(:label) { create(:label, project: project) } let(:label) { create(:label, project: project) }
let!(:list) { create(:list, board: board, label: label) } let!(:list) { create(:list, board: board, label: label) }
let(:service) { described_class.new(project, user) } let(:parent) { project }
it_behaves_like 'lists list service' it_behaves_like 'lists list service'
end end
...@@ -21,7 +23,7 @@ RSpec.describe Boards::Lists::ListService do ...@@ -21,7 +23,7 @@ RSpec.describe Boards::Lists::ListService do
let(:board) { create(:board, group: group) } let(:board) { create(:board, group: group) }
let(:label) { create(:group_label, group: group) } let(:label) { create(:group_label, group: group) }
let!(:list) { create(:list, board: board, label: label) } let!(:list) { create(:list, board: board, label: label) }
let(:service) { described_class.new(group, user) } let(:parent) { group }
it_behaves_like 'lists list service' it_behaves_like 'lists list service'
end end
......
...@@ -26,4 +26,22 @@ RSpec.shared_examples 'lists list service' do ...@@ -26,4 +26,22 @@ RSpec.shared_examples 'lists list service' do
expect(service.execute(board)).to eq [board.backlog_list, list, board.closed_list] expect(service.execute(board)).to eq [board.backlog_list, list, board.closed_list]
end end
end end
context 'when wanting a specific list' do
let!(:list1) { create(:list, board: board) }
it 'returns list specified by id' do
service = described_class.new(parent, user, list_id: list1.id)
expect(service.execute(board, create_default_lists: false)).to eq [list1]
end
it 'returns empty result when list is not found' do
external_board = create(:board, resource_parent: create(:project))
external_list = create(:list, board: external_board)
service = described_class.new(parent, user, list_id: external_list.id)
expect(service.execute(board, create_default_lists: false)).to eq(List.none)
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