summaryrefslogtreecommitdiff
path: root/spec/requests/api/graphql/project/merge_requests_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api/graphql/project/merge_requests_spec.rb')
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb174
1 files changed, 174 insertions, 0 deletions
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
new file mode 100644
index 00000000000..49fdfe29874
--- /dev/null
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -0,0 +1,174 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting merge request listings nested in a project' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:current_user) { create(:user) }
+
+ let_it_be(:label) { create(:label) }
+ let_it_be(:merge_request_a) { create(:labeled_merge_request, :unique_branches, source_project: project, labels: [label]) }
+ let_it_be(:merge_request_b) { create(:merge_request, :closed, :unique_branches, source_project: project) }
+ let_it_be(:merge_request_c) { create(:labeled_merge_request, :closed, :unique_branches, source_project: project, labels: [label]) }
+ let_it_be(:merge_request_d) { create(:merge_request, :locked, :unique_branches, source_project: project) }
+
+ let(:results) { graphql_data.dig('project', 'mergeRequests', 'nodes') }
+
+ let(:search_params) { nil }
+
+ def query_merge_requests(fields)
+ graphql_query_for(
+ :project,
+ { full_path: project.full_path },
+ query_graphql_field(:merge_requests, search_params, [
+ query_graphql_field(:nodes, nil, fields)
+ ])
+ )
+ end
+
+ let(:query) do
+ query_merge_requests(all_graphql_fields_for('MergeRequest', max_depth: 1))
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ # The following tests are needed to guarantee that we have correctly annotated
+ # all the gitaly calls. Selecting combinations of fields may mask this due to
+ # memoization.
+ context 'requesting a single field' do
+ let_it_be(:fresh_mr) { create(:merge_request, :unique_branches, source_project: project) }
+ let(:search_params) { { iids: [fresh_mr.iid.to_s] } }
+
+ before do
+ project.repository.expire_branches_cache
+ end
+
+ context 'selecting any single scalar field' do
+ where(:field) do
+ scalar_fields_of('MergeRequest').map { |name| [name] }
+ end
+
+ with_them do
+ it_behaves_like 'a working graphql query' do
+ let(:query) do
+ query_merge_requests([:iid, field].uniq)
+ end
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'selects the correct MR' do
+ expect(results).to contain_exactly(a_hash_including('iid' => fresh_mr.iid.to_s))
+ end
+ end
+ end
+ end
+
+ context 'selecting any single nested field' do
+ where(:field, :subfield, :is_connection) do
+ nested_fields_of('MergeRequest').flat_map do |name, field|
+ type = field_type(field)
+ is_connection = type.name.ends_with?('Connection')
+ type = field_type(type.fields['nodes']) if is_connection
+
+ type.fields
+ .select { |_, field| !nested_fields?(field) && !required_arguments?(field) }
+ .map(&:first)
+ .map { |subfield| [name, subfield, is_connection] }
+ end
+ end
+
+ with_them do
+ it_behaves_like 'a working graphql query' do
+ let(:query) do
+ fld = is_connection ? query_graphql_field(:nodes, nil, [subfield]) : subfield
+ query_merge_requests([:iid, query_graphql_field(field, nil, [fld])])
+ end
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'selects the correct MR' do
+ expect(results).to contain_exactly(a_hash_including('iid' => fresh_mr.iid.to_s))
+ end
+ end
+ end
+ end
+ end
+
+ shared_examples 'searching with parameters' do
+ let(:expected) do
+ mrs.map { |mr| a_hash_including('iid' => mr.iid.to_s, 'title' => mr.title) }
+ end
+
+ it 'finds the right mrs' do
+ post_graphql(query, current_user: current_user)
+
+ expect(results).to match_array(expected)
+ end
+ end
+
+ context 'there are no search params' do
+ let(:search_params) { nil }
+ let(:mrs) { [merge_request_a, merge_request_b, merge_request_c, merge_request_d] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'the search params do not match anything' do
+ let(:search_params) { { iids: %w(foo bar baz) } }
+ let(:mrs) { [] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by iids' do
+ let(:search_params) { { iids: mrs.map(&:iid).map(&:to_s) } }
+ let(:mrs) { [merge_request_a, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by state' do
+ let(:search_params) { { state: :closed } }
+ let(:mrs) { [merge_request_b, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by source_branch' do
+ let(:search_params) { { source_branches: mrs.map(&:source_branch) } }
+ let(:mrs) { [merge_request_b, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by target_branch' do
+ let(:search_params) { { target_branches: mrs.map(&:target_branch) } }
+ let(:mrs) { [merge_request_a, merge_request_d] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by label' do
+ let(:search_params) { { labels: [label.title] } }
+ let(:mrs) { [merge_request_a, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by combination' do
+ let(:search_params) { { state: :closed, labels: [label.title] } }
+ let(:mrs) { [merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+end