Commit a9da2b10 authored by Brett Walker's avatar Brett Walker

Add request spec for Board gaphql query

includes testing of sorting / pagination
parent d3131b11
......@@ -159,6 +159,61 @@ enum BlobViewersType {
simple
}
"""
Represents a project or group board
"""
type Board {
"""
ID (global ID) of the board
"""
id: ID!
"""
Name of the board
"""
name: String
"""
Weight of the board
"""
weight: Int
}
"""
The connection type for Board.
"""
type BoardConnection {
"""
A list of edges.
"""
edges: [BoardEdge]
"""
A list of nodes.
"""
nodes: [Board]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type BoardEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: Board
}
type Commit {
"""
Author of the commit
......@@ -2715,6 +2770,31 @@ type Group {
"""
avatarUrl: String
"""
Boards of the group
"""
boards(
"""
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
): BoardConnection
"""
Description of the namespace
"""
......@@ -5174,6 +5254,31 @@ type Project {
"""
avatarUrl: String
"""
Boards of the project
"""
boards(
"""
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
): BoardConnection
"""
Indicates if the project stores Docker container images in a container registry
"""
......
......@@ -4543,7 +4543,7 @@
{
"kind": "OBJECT",
"name": "Board",
"description": null,
"description": "Represents a project or group board",
"fields": [
{
"name": "id",
......
# frozen_string_literal: true
require 'spec_helper'
describe 'get list of boards' do
include GraphqlHelpers
include_context 'group and project boards query context'
before do
stub_licensed_features(multiple_group_issue_boards: true)
end
describe 'for a group' do
let(:board_parent) { create(:group, :private) }
let(:boards_data) { graphql_data['group']['boards']['edges'] }
it_behaves_like 'group and project boards query'
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'get list of boards' do
include GraphqlHelpers
include_context 'group and project boards query context'
describe 'for a project' do
let(:board_parent) { create(:project, :repository, :private) }
let(:boards_data) { graphql_data['project']['boards']['edges'] }
it_behaves_like 'group and project boards query'
end
describe 'for a group' do
let(:board_parent) { create(:group, :private) }
let(:boards_data) { graphql_data['group']['boards']['edges'] }
before do
allow(board_parent).to receive(:multiple_issue_boards_available?).and_return(false)
end
it_behaves_like 'group and project boards query'
end
end
# frozen_string_literal: true
RSpec.shared_context 'group and project boards query context' do
let_it_be(:user) { create :user }
let(:current_user) { user }
let(:params) { '' }
let(:board_parent_type) { board_parent.class.to_s.downcase }
let(:start_cursor) { graphql_data[board_parent_type]['boards']['pageInfo']['startCursor'] }
let(:end_cursor) { graphql_data[board_parent_type]['boards']['pageInfo']['endCursor'] }
def query(board_params = params)
graphql_query_for(
board_parent_type,
{ 'fullPath' => board_parent.full_path },
<<~BOARDS
boards(#{board_params}) {
pageInfo {
startCursor
endCursor
}
edges {
node {
#{all_graphql_fields_for('boards'.classify)}
}
}
}
BOARDS
)
end
def grab_names(data = boards_data)
data.map do |board|
board.dig('node', 'name')
end
end
end
# frozen_string_literal: true
RSpec.shared_examples 'group and project boards query' do
include GraphqlHelpers
it_behaves_like 'a working graphql query' do
before do
post_graphql(query, current_user: current_user)
end
end
context 'when the user does not have access to the board parent' do
it 'returns nil' do
create(:board, resource_parent: board_parent, name: 'A')
post_graphql(query)
expect(graphql_data[board_parent_type]).to be_nil
end
end
context 'when no permission to read board' do
it 'does not return any boards' do
board_parent.add_guest(current_user)
board = create(:board, resource_parent: board_parent, name: 'A')
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :read_board, board).and_return(false)
post_graphql(query, current_user: current_user)
expect(boards_data).to be_empty
end
end
context 'when user can read the board parent' do
before do
board_parent.add_reporter(current_user)
end
it 'does not create a default board' do
post_graphql(query, current_user: current_user)
expect(boards_data).to be_empty
end
describe 'sorting and pagination' do
context 'when using default sorting' do
let!(:board_B) { create(:board, resource_parent: board_parent, name: 'B') }
let!(:board_C) { create(:board, resource_parent: board_parent, name: 'C') }
let!(:board_a) { create(:board, resource_parent: board_parent, name: 'a') }
let!(:board_A) { create(:board, resource_parent: board_parent, name: 'A') }
before do
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
context 'when ascending' do
let(:boards) { [board_a, board_A, board_B, board_C] }
let(:expected_boards) do
if board_parent.multiple_issue_boards_available?
boards
else
[boards.first]
end
end
it 'sorts boards' do
expect(grab_names).to eq expected_boards.map(&:name)
end
context 'when paginating' do
let(:params) { 'first: 2' }
it 'sorts boards' do
expect(grab_names).to eq expected_boards.first(2).map(&:name)
cursored_query = query("after: \"#{end_cursor}\"")
post_graphql(cursored_query, current_user: current_user)
response_data = JSON.parse(response.body)['data'][board_parent_type]['boards']['edges']
expect(grab_names(response_data)).to eq expected_boards.drop(2).first(2).map(&:name)
end
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