Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
6eac7ebd
Commit
6eac7ebd
authored
Apr 24, 2020
by
Brett Walker
Committed by
Michael Kozono
Apr 24, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor GraphQL sorting and pagination specs
for issues into shared_examples
parent
e934aee7
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
136 additions
and
76 deletions
+136
-76
ee/spec/requests/api/graphql/project/issues_spec.rb
ee/spec/requests/api/graphql/project/issues_spec.rb
+23
-75
spec/support/helpers/graphql_helpers.rb
spec/support/helpers/graphql_helpers.rb
+8
-1
spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
...xamples/graphql/sorted_paginated_query_shared_examples.rb
+92
-0
spec/support/shared_examples/requires_variables_shared_example.rb
...port/shared_examples/requires_variables_shared_example.rb
+13
-0
No files found.
ee/spec/requests/api/graphql/project/issues_spec.rb
View file @
6eac7ebd
...
@@ -5,98 +5,46 @@ require 'spec_helper'
...
@@ -5,98 +5,46 @@ require 'spec_helper'
describe
'getting an issue list for a project'
do
describe
'getting an issue list for a project'
do
include
GraphqlHelpers
include
GraphqlHelpers
let
(
:project
)
{
create
(
:project
,
:repository
,
:public
)
}
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:issues_data
)
{
graphql_data
[
'project'
][
'issues'
][
'edges'
]
}
describe
'sorting and pagination'
do
describe
'sorting and pagination'
do
let
(
:start_cursor
)
{
graphql_data
[
'project'
][
'issues'
][
'pageInfo'
][
'startCursor'
]
}
let
(
:end_cursor
)
{
graphql_data
[
'project'
][
'issues'
][
'pageInfo'
][
'endCursor'
]
}
context
'when sorting by weight'
do
let
(
:sort_project
)
{
create
(
:project
,
:public
)
}
let
(
:sort_project
)
{
create
(
:project
,
:public
)
}
let
(
:data_path
)
{
[
:project
,
:issues
]
}
let!
(
:weight_issue1
)
{
create
(
:issue
,
project:
sort_project
,
weight:
5
)
}
def
pagination_query
(
params
,
page_info
)
let!
(
:weight_issue2
)
{
create
(
:issue
,
project:
sort_project
,
weight:
nil
)
}
let!
(
:weight_issue3
)
{
create
(
:issue
,
project:
sort_project
,
weight:
1
)
}
let!
(
:weight_issue4
)
{
create
(
:issue
,
project:
sort_project
,
weight:
nil
)
}
let!
(
:weight_issue5
)
{
create
(
:issue
,
project:
sort_project
,
weight:
3
)
}
let
(
:params
)
{
'sort: WEIGHT_ASC'
}
def
query
(
issue_params
=
params
)
graphql_query_for
(
graphql_query_for
(
'project'
,
'project'
,
{
'fullPath'
=>
sort_project
.
full_path
},
{
'fullPath'
=>
sort_project
.
full_path
},
<<~
ISSUES
"issues(
#{
params
}
) {
#{
page_info
}
edges { node { iid weight } } }"
issues(
#{
issue_params
}
) {
pageInfo {
endCursor
}
edges {
node {
iid
weight
}
}
}
ISSUES
)
)
end
end
before
do
def
pagination_results_data
(
data
)
post_graphql
(
query
,
current_user:
current_user
)
data
.
map
{
|
issue
|
issue
.
dig
(
'node'
,
'iid'
).
to_i
}
end
end
it_behaves_like
'a working graphql query'
context
'when sorting by weight'
do
let!
(
:weight_issue1
)
{
create
(
:issue
,
project:
sort_project
,
weight:
5
)
}
let!
(
:weight_issue2
)
{
create
(
:issue
,
project:
sort_project
,
weight:
nil
)
}
let!
(
:weight_issue3
)
{
create
(
:issue
,
project:
sort_project
,
weight:
1
)
}
let!
(
:weight_issue4
)
{
create
(
:issue
,
project:
sort_project
,
weight:
nil
)
}
let!
(
:weight_issue5
)
{
create
(
:issue
,
project:
sort_project
,
weight:
3
)
}
context
'when ascending'
do
context
'when ascending'
do
it
'sorts issues'
do
it_behaves_like
'sorted paginated query'
do
expect
(
grab_iids
).
to
eq
[
weight_issue3
.
iid
,
weight_issue5
.
iid
,
weight_issue1
.
iid
,
weight_issue4
.
iid
,
weight_issue2
.
iid
]
let
(
:sort_param
)
{
'WEIGHT_ASC'
}
end
let
(
:first_param
)
{
2
}
let
(
:expected_results
)
{
[
weight_issue3
.
iid
,
weight_issue5
.
iid
,
weight_issue1
.
iid
,
weight_issue4
.
iid
,
weight_issue2
.
iid
]
}
context
'when paginating'
do
let
(
:params
)
{
'sort: WEIGHT_ASC, first: 2'
}
it
'sorts issues'
do
expect
(
grab_iids
).
to
eq
[
weight_issue3
.
iid
,
weight_issue5
.
iid
]
cursored_query
=
query
(
"sort: WEIGHT_ASC, after:
\"
#{
end_cursor
}
\"
"
)
post_graphql
(
cursored_query
,
current_user:
current_user
)
response_data
=
JSON
.
parse
(
response
.
body
)[
'data'
][
'project'
][
'issues'
][
'edges'
]
expect
(
grab_iids
(
response_data
)).
to
eq
[
weight_issue1
.
iid
,
weight_issue4
.
iid
,
weight_issue2
.
iid
]
end
end
end
end
end
context
'when descending'
do
context
'when descending'
do
let
(
:params
)
{
'sort: WEIGHT_DESC'
}
it_behaves_like
'sorted paginated query'
do
let
(
:sort_param
)
{
'WEIGHT_DESC'
}
it
'sorts issues'
do
let
(
:first_param
)
{
2
}
expect
(
grab_iids
).
to
eq
[
weight_issue1
.
iid
,
weight_issue5
.
iid
,
weight_issue3
.
iid
,
weight_issue4
.
iid
,
weight_issue2
.
iid
]
let
(
:expected_results
)
{
[
weight_issue1
.
iid
,
weight_issue5
.
iid
,
weight_issue3
.
iid
,
weight_issue4
.
iid
,
weight_issue2
.
iid
]
}
end
context
'when paginating'
do
let
(
:params
)
{
'sort: WEIGHT_DESC, first: 2'
}
it
'sorts issues'
do
expect
(
grab_iids
).
to
eq
[
weight_issue1
.
iid
,
weight_issue5
.
iid
]
cursored_query
=
query
(
"sort: WEIGHT_DESC, after:
\"
#{
end_cursor
}
\"
"
)
post_graphql
(
cursored_query
,
current_user:
current_user
)
response_data
=
JSON
.
parse
(
response
.
body
)[
'data'
][
'project'
][
'issues'
][
'edges'
]
expect
(
grab_iids
(
response_data
)).
to
eq
[
weight_issue3
.
iid
,
weight_issue4
.
iid
,
weight_issue2
.
iid
]
end
end
end
end
end
end
end
end
end
def
grab_iids
(
data
=
issues_data
)
data
.
map
do
|
issue
|
issue
.
dig
(
'node'
,
'iid'
).
to_i
end
end
end
end
spec/support/helpers/graphql_helpers.rb
View file @
6eac7ebd
...
@@ -246,12 +246,19 @@ module GraphqlHelpers
...
@@ -246,12 +246,19 @@ module GraphqlHelpers
# Raises an error if no data is found
# Raises an error if no data is found
def
graphql_data
def
graphql_data
# Note that `json_response` is defined as `let(:json_response)` and
# therefore, in a spec with multiple queries, will only contain data
# from the _first_ query, not subsequent ones
json_response
[
'data'
]
||
(
raise
NoData
,
graphql_errors
)
json_response
[
'data'
]
||
(
raise
NoData
,
graphql_errors
)
end
end
def
graphql_data_at
(
*
path
)
def
graphql_data_at
(
*
path
)
graphql_dig_at
(
graphql_data
,
*
path
)
end
def
graphql_dig_at
(
data
,
*
path
)
keys
=
path
.
map
{
|
segment
|
GraphqlHelpers
.
fieldnamerize
(
segment
)
}
keys
=
path
.
map
{
|
segment
|
GraphqlHelpers
.
fieldnamerize
(
segment
)
}
graphql_
data
.
dig
(
*
keys
)
data
.
dig
(
*
keys
)
end
end
def
graphql_errors
def
graphql_errors
...
...
spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
0 → 100644
View file @
6eac7ebd
# frozen_string_literal: true
# Use this for testing how a GraphQL query handles sorting and pagination.
# This is particularly important when using keyset pagination connection,
# which is the default for ActiveRecord relations, as certain sort keys
# might not be supportable.
#
# sort_param: the value to specify the sort
# data_path: the keys necessary to dig into the return GraphQL data to get the
# returned results
# first_param: number of items expected (like a page size)
# expected_results: array of comparison data of all items sorted correctly
# pagination_query: method that specifies the GraphQL query
# pagination_results_data: method that extracts the sorted data used to compare against
# the expected results
#
# Example:
# describe 'sorting and pagination' do
# let(:sort_project) { create(:project, :public) }
# let(:data_path) { [:project, :issues] }
#
# def pagination_query(params, page_info)
# graphql_query_for(
# 'project',
# { 'fullPath' => sort_project.full_path },
# "issues(#{params}) { #{page_info} edges { node { iid weight } } }"
# )
# end
#
# def pagination_results_data(data)
# data.map { |issue| issue.dig('node', 'iid').to_i }
# end
#
# context 'when sorting by weight' do
# ...
# context 'when ascending' do
# it_behaves_like 'sorted paginated query' do
# let(:sort_param) { 'WEIGHT_ASC' }
# let(:first_param) { 2 }
# let(:expected_results) { [weight_issue3.iid, weight_issue5.iid, weight_issue1.iid, weight_issue4.iid, weight_issue2.iid] }
# end
# end
#
RSpec
.
shared_examples
'sorted paginated query'
do
it_behaves_like
'requires variables'
do
let
(
:required_variables
)
{
[
:sort_param
,
:first_param
,
:expected_results
,
:data_path
,
:current_user
]
}
end
describe
do
let
(
:params
)
{
"sort:
#{
sort_param
}
"
}
let
(
:start_cursor
)
{
graphql_data_at
(
*
data_path
,
:pageInfo
,
:startCursor
)
}
let
(
:end_cursor
)
{
graphql_data_at
(
*
data_path
,
:pageInfo
,
:endCursor
)
}
let
(
:sorted_edges
)
{
graphql_data_at
(
*
data_path
,
:edges
)
}
let
(
:page_info
)
{
"pageInfo { startCursor endCursor }"
}
def
pagination_query
(
params
,
page_info
)
raise
(
'pagination_query(params, page_info) must be defined in the test, see example in comment'
)
unless
defined?
(
super
)
super
end
def
pagination_results_data
(
data
)
raise
(
'pagination_results_data(data) must be defined in the test, see example in comment'
)
unless
defined?
(
super
)
super
(
data
)
end
before
do
post_graphql
(
pagination_query
(
params
,
page_info
),
current_user:
current_user
)
end
context
'when sorting'
do
it
'sorts correctly'
do
expect
(
pagination_results_data
(
sorted_edges
)).
to
eq
expected_results
end
context
'when paginating'
do
let
(
:params
)
{
"sort:
#{
sort_param
}
, first:
#{
first_param
}
"
}
it
'paginates correctly'
do
expect
(
pagination_results_data
(
sorted_edges
)).
to
eq
expected_results
.
first
(
first_param
)
cursored_query
=
pagination_query
(
"sort:
#{
sort_param
}
, after:
\"
#{
end_cursor
}
\"
"
,
page_info
)
post_graphql
(
cursored_query
,
current_user:
current_user
)
response_data
=
graphql_dig_at
(
JSON
.
parse
(
response
.
body
),
:data
,
*
data_path
,
:edges
)
expect
(
pagination_results_data
(
response_data
)).
to
eq
expected_results
.
drop
(
first_param
)
end
end
end
end
end
spec/support/shared_examples/requires_variables_shared_example.rb
0 → 100644
View file @
6eac7ebd
# frozen_string_literal: true
RSpec
.
shared_examples
'requires variables'
do
it
'shared example requires variables to be set'
,
:aggregate_failures
do
variables
=
Array
.
wrap
(
required_variables
)
variables
.
each
do
|
variable_name
|
expect
{
send
(
variable_name
)
}.
not_to
(
raise_error
,
"The following variable must be set to use this shared example:
#{
variable_name
}
"
)
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment