Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb')
-rw-r--r--spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb93
1 files changed, 62 insertions, 31 deletions
diff --git a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
index 7627a7b4d59..f78ea364147 100644
--- a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
@@ -16,80 +16,111 @@
#
# Example:
# describe 'sorting and pagination' do
-# let(:sort_project) { create(:project, :public) }
+# let_it_be(: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 },
-# query_graphql_field('issues', params, "#{page_info} edges { node { id } }")
+# def pagination_query(arguments)
+# graphql_query_for(:project, { full_path: sort_project.full_path },
+# query_nodes(:issues, :iid, include_pagination_info: true, args: arguments)
# )
# end
#
-# def pagination_results_data(data)
-# data.map { |issue| issue.dig('node', 'iid').to_i }
+# # A method transforming nodes to data to match against
+# # default: the identity function
+# def pagination_results_data(issues)
+# issues.map { |issue| issue['iid].to_i }
# end
#
# context 'when sorting by weight' do
-# ...
+# let_it_be(:issues) { make_some_issues_with_weights }
+#
# context 'when ascending' do
+# let(:ordered_issues) { issues.sort_by(&:weight) }
+#
# it_behaves_like 'sorted paginated query' do
-# let(:sort_param) { 'WEIGHT_ASC' }
+# 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] }
+# let(:expected_results) { ordered_issues.map(&:iid) }
# end
# end
#
RSpec.shared_examples 'sorted paginated query' do
+ # Provided as a convenience when constructing queries using string concatenation
+ let(:page_info) { 'pageInfo { startCursor endCursor }' }
+ # Convenience for using default implementation of pagination_results_data
+ let(:node_path) { ['id'] }
+
it_behaves_like 'requires variables' do
let(:required_variables) { [:sort_param, :first_param, :expected_results, :data_path, :current_user] }
end
describe do
- let(:sort_argument) { "sort: #{sort_param}" if sort_param.present? }
- let(:first_argument) { "first: #{first_param}" if first_param.present? }
+ let(:sort_argument) { graphql_args(sort: sort_param) }
let(:params) { sort_argument }
- 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)
+ # Convenience helper for the large number of queries defined as a projection
+ # from some root value indexed by full_path to a collection of objects with IID
+ def nested_internal_id_query(root_field, parent, field, args, selection: :iid)
+ graphql_query_for(root_field, { full_path: parent.full_path },
+ query_nodes(field, selection, args: args, include_pagination_info: true)
+ )
+ end
+
+ def pagination_query(params)
+ raise('pagination_query(params) 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)
+ def pagination_results_data(nodes)
+ if defined?(super)
+ super(nodes)
+ else
+ nodes.map { |n| n.dig(*node_path) }
+ end
+ end
+
+ def results
+ nodes = graphql_dig_at(graphql_data(fresh_response_data), *data_path, :nodes)
+ pagination_results_data(nodes)
+ end
+
+ def end_cursor
+ graphql_dig_at(graphql_data(fresh_response_data), *data_path, :page_info, :end_cursor)
+ end
- super(data)
+ def start_cursor
+ graphql_dig_at(graphql_data(fresh_response_data), *data_path, :page_info, :start_cursor)
end
+ let(:query) { pagination_query(params) }
+
before do
- post_graphql(pagination_query(params, page_info), current_user: current_user)
+ post_graphql(query, current_user: current_user)
end
context 'when sorting' do
it 'sorts correctly' do
- expect(pagination_results_data(sorted_edges)).to eq expected_results
+ expect(results).to eq expected_results
end
context 'when paginating' do
- let(:params) { [sort_argument, first_argument].compact.join(',') }
+ let(:params) { sort_argument.merge(first: first_param) }
+ let(:first_page) { expected_results.first(first_param) }
+ let(:rest) { expected_results.drop(first_param) }
it 'paginates correctly' do
- expect(pagination_results_data(sorted_edges)).to eq expected_results.first(first_param)
+ expect(results).to eq first_page
- cursored_query = pagination_query([sort_argument, "after: \"#{end_cursor}\""].compact.join(','), page_info)
- post_graphql(cursored_query, current_user: current_user)
+ fwds = pagination_query(sort_argument.merge(after: end_cursor))
+ post_graphql(fwds, current_user: current_user)
- expect(response).to have_gitlab_http_status(:ok)
+ expect(results).to eq rest
- response_data = graphql_dig_at(Gitlab::Json.parse(response.body), :data, *data_path, :edges)
+ bwds = pagination_query(sort_argument.merge(before: start_cursor))
+ post_graphql(bwds, current_user: current_user)
- expect(pagination_results_data(response_data)).to eq expected_results.drop(first_param)
+ expect(results).to eq first_page
end
end
end