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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 10:08:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 10:08:36 +0300
commit48aff82709769b098321c738f3444b9bdaa694c6 (patch)
treee00c7c43e2d9b603a5a6af576b1685e400410dee /spec/requests/api/graphql/project
parent879f5329ee916a948223f8f43d77fba4da6cd028 (diff)
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/requests/api/graphql/project')
-rw-r--r--spec/requests/api/graphql/project/alert_management/alerts_spec.rb13
-rw-r--r--spec/requests/api/graphql/project/issue/designs/notes_spec.rb16
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb35
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb75
-rw-r--r--spec/requests/api/graphql/project/milestones_spec.rb202
5 files changed, 321 insertions, 20 deletions
diff --git a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
index d3a2e6a1deb..8deed75a466 100644
--- a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
@@ -139,6 +139,19 @@ RSpec.describe 'getting Alert Management Alerts' do
it { expect(alerts.size).to eq(0) }
end
end
+
+ context 'assignee_username' do
+ let(:alert) { triggered_alert }
+ let(:assignee) { alert.assignees.first! }
+ let(:params) { { assignee_username: assignee.username } }
+
+ it_behaves_like 'a working graphql query'
+
+ specify do
+ expect(alerts.size).to eq(1)
+ expect(first_alert['iid']).to eq(alert.iid.to_s)
+ end
+ end
end
end
end
diff --git a/spec/requests/api/graphql/project/issue/designs/notes_spec.rb b/spec/requests/api/graphql/project/issue/designs/notes_spec.rb
index 65191e057c7..e25453510d5 100644
--- a/spec/requests/api/graphql/project/issue/designs/notes_spec.rb
+++ b/spec/requests/api/graphql/project/issue/designs/notes_spec.rb
@@ -31,8 +31,8 @@ RSpec.describe 'Getting designs related to an issue' do
post_graphql(query(note_fields), current_user: nil)
designs_data = graphql_data['project']['issue']['designs']['designs']
- design_data = designs_data['edges'].first['node']
- note_data = design_data['notes']['edges'].first['node']
+ design_data = designs_data['nodes'].first
+ note_data = design_data['notes']['nodes'].first
expect(note_data['id']).to eq(note.to_global_id.to_s)
end
@@ -40,14 +40,10 @@ RSpec.describe 'Getting designs related to an issue' do
def query(note_fields = all_graphql_fields_for(Note))
design_node = <<~NODE
designs {
- edges {
- node {
- notes {
- edges {
- node {
- #{note_fields}
- }
- }
+ nodes {
+ notes {
+ nodes {
+ #{note_fields}
}
}
}
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index 5d4276f47ca..40fec6ba068 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -53,16 +53,37 @@ RSpec.describe 'getting an issue list for a project' do
context 'when limiting the number of results' do
let(:query) do
- graphql_query_for(
- 'project',
- { 'fullPath' => project.full_path },
- "issues(first: 1) { #{fields} }"
- )
+ <<~GQL
+ query($path: ID!, $n: Int) {
+ project(fullPath: $path) {
+ issues(first: $n) { #{fields} }
+ }
+ }
+ GQL
+ end
+
+ let(:issue_limit) { 1 }
+ let(:variables) do
+ { path: project.full_path, n: issue_limit }
end
it_behaves_like 'a working graphql query' do
before do
- post_graphql(query, current_user: current_user)
+ post_graphql(query, current_user: current_user, variables: variables)
+ end
+
+ it 'only returns N issues' do
+ expect(issues_data.size).to eq(issue_limit)
+ end
+ end
+
+ context 'no limit is provided' do
+ let(:issue_limit) { nil }
+
+ it 'returns all issues' do
+ post_graphql(query, current_user: current_user, variables: variables)
+
+ expect(issues_data.size).to be > 1
end
end
@@ -71,7 +92,7 @@ RSpec.describe 'getting an issue list for a project' do
# Newest first, we only want to see the newest checked
expect(Ability).not_to receive(:allowed?).with(current_user, :read_issue, issues.first)
- post_graphql(query, current_user: current_user)
+ post_graphql(query, current_user: current_user, variables: variables)
end
end
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
index 22b003501a1..c737e0b8caf 100644
--- a/spec/requests/api/graphql/project/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe 'getting merge request listings nested in a project' do
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_it_be(:merge_request_e) { create(:merge_request, :unique_branches, source_project: project) }
let(:results) { graphql_data.dig('project', 'mergeRequests', 'nodes') }
@@ -118,7 +119,7 @@ RSpec.describe 'getting merge request listings nested in a project' do
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] }
+ let(:mrs) { [merge_request_a, merge_request_b, merge_request_c, merge_request_d, merge_request_e] }
it_behaves_like 'searching with parameters'
end
@@ -172,6 +173,28 @@ RSpec.describe 'getting merge request listings nested in a project' do
it_behaves_like 'searching with parameters'
end
+ context 'when requesting `approved_by`' do
+ let(:search_params) { { iids: [merge_request_a.iid.to_s, merge_request_b.iid.to_s] } }
+ let(:extra_iid_for_second_query) { merge_request_c.iid.to_s }
+ let(:requested_fields) { query_graphql_field(:approved_by, nil, query_graphql_field(:nodes, nil, [:username])) }
+
+ def execute_query
+ query = query_merge_requests(requested_fields)
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'exposes approver username' do
+ merge_request_a.approved_by_users << current_user
+
+ execute_query
+
+ user_data = { 'username' => current_user.username }
+ expect(results).to include(a_hash_including('approvedBy' => { 'nodes' => array_including(user_data) }))
+ end
+
+ include_examples 'N+1 query check'
+ end
+
describe 'fields' do
let(:requested_fields) { nil }
let(:extra_iid_for_second_query) { merge_request_c.iid.to_s }
@@ -209,7 +232,19 @@ RSpec.describe 'getting merge request listings nested in a project' do
include_examples 'N+1 query check'
end
+
+ context 'when requesting `user_notes_count`' do
+ let(:requested_fields) { [:user_notes_count] }
+
+ before do
+ create_list(:note_on_merge_request, 2, noteable: merge_request_a, project: project)
+ create(:note_on_merge_request, noteable: merge_request_c, project: project)
+ end
+
+ include_examples 'N+1 query check'
+ end
end
+
describe 'sorting and pagination' do
let(:data_path) { [:project, :mergeRequests] }
@@ -241,16 +276,50 @@ RSpec.describe 'getting merge request listings nested in a project' do
let(:expected_results) do
[
merge_request_b,
- merge_request_c,
merge_request_d,
+ merge_request_c,
+ merge_request_e,
merge_request_a
].map(&:to_gid).map(&:to_s)
end
before do
- merge_request_c.metrics.update!(merged_at: 5.days.ago)
+ five_days_ago = 5.days.ago
+
+ merge_request_d.metrics.update!(merged_at: five_days_ago)
+
+ # same merged_at, the second order column will decide (merge_request.id)
+ merge_request_c.metrics.update!(merged_at: five_days_ago)
+
merge_request_b.metrics.update!(merged_at: 1.day.ago)
end
+
+ context 'when paginating backwards' do
+ let(:params) { 'first: 2, sort: MERGED_AT_DESC' }
+ let(:page_info) { 'pageInfo { startCursor endCursor }' }
+
+ before do
+ post_graphql(pagination_query(params, page_info), current_user: current_user)
+ end
+
+ it 'paginates backwards correctly' do
+ # first page
+ first_page_response_data = graphql_dig_at(Gitlab::Json.parse(response.body), :data, *data_path, :edges)
+ end_cursor = graphql_dig_at(Gitlab::Json.parse(response.body), :data, :project, :mergeRequests, :pageInfo, :endCursor)
+
+ # second page
+ params = "first: 2, after: \"#{end_cursor}\", sort: MERGED_AT_DESC"
+ post_graphql(pagination_query(params, page_info), current_user: current_user)
+ start_cursor = graphql_dig_at(Gitlab::Json.parse(response.body), :data, :project, :mergeRequests, :pageInfo, :start_cursor)
+
+ # going back to the first page
+
+ params = "last: 2, before: \"#{start_cursor}\", sort: MERGED_AT_DESC"
+ post_graphql(pagination_query(params, page_info), current_user: current_user)
+ backward_paginated_response_data = graphql_dig_at(Gitlab::Json.parse(response.body), :data, *data_path, :edges)
+ expect(first_page_response_data).to eq(backward_paginated_response_data)
+ end
+ end
end
end
end
diff --git a/spec/requests/api/graphql/project/milestones_spec.rb b/spec/requests/api/graphql/project/milestones_spec.rb
new file mode 100644
index 00000000000..2fede4c7285
--- /dev/null
+++ b/spec/requests/api/graphql/project/milestones_spec.rb
@@ -0,0 +1,202 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'getting milestone listings nested in a project' do
+ include GraphqlHelpers
+
+ let_it_be(:today) { Time.now.utc.to_date }
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:current_user) { create(:user) }
+
+ let_it_be(:no_dates) { create(:milestone, project: project, title: 'no dates') }
+ let_it_be(:no_end) { create(:milestone, project: project, title: 'no end', start_date: today - 10.days) }
+ let_it_be(:no_start) { create(:milestone, project: project, title: 'no start', due_date: today - 5.days) }
+ let_it_be(:fully_past) { create(:milestone, project: project, title: 'past', start_date: today - 10.days, due_date: today - 5.days) }
+ let_it_be(:covers_today) { create(:milestone, project: project, title: 'present', start_date: today - 5.days, due_date: today + 5.days) }
+ let_it_be(:fully_future) { create(:milestone, project: project, title: 'future', start_date: today + 5.days, due_date: today + 10.days) }
+ let_it_be(:closed) { create(:milestone, :closed, project: project) }
+
+ let(:results) { graphql_data_at(:project, :milestones, :nodes) }
+
+ let(:search_params) { nil }
+
+ def query_milestones(fields)
+ graphql_query_for(
+ :project,
+ { full_path: project.full_path },
+ query_graphql_field(:milestones, search_params, [
+ query_graphql_field(:nodes, nil, %i[id title])
+ ])
+ )
+ end
+
+ def result_list(expected)
+ expected.map do |milestone|
+ a_hash_including('id' => global_id_of(milestone))
+ end
+ end
+
+ let(:query) do
+ query_milestones(all_graphql_fields_for('Milestone', max_depth: 1))
+ end
+
+ let(:all_milestones) do
+ [no_dates, no_end, no_start, fully_past, fully_future, covers_today, closed]
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ shared_examples 'searching with parameters' do
+ it 'finds the right milestones' do
+ post_graphql(query, current_user: current_user)
+
+ expect(results).to match_array(result_list(expected))
+ end
+ end
+
+ context 'there are no search params' do
+ let(:search_params) { nil }
+ let(:expected) { all_milestones }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'the search params do not match anything' do
+ let(:search_params) { { title: 'wibble' } }
+ let(:expected) { [] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by state:closed' do
+ let(:search_params) { { state: :closed } }
+ let(:expected) { [closed] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by state:active' do
+ let(:search_params) { { state: :active } }
+ let(:expected) { all_milestones - [closed] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by title' do
+ let(:search_params) { { title: 'no start' } }
+ let(:expected) { [no_start] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by search_title' do
+ let(:search_params) { { search_title: 'no' } }
+ let(:expected) { [no_dates, no_start, no_end] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by containing_date' do
+ let(:search_params) { { containing_date: (today - 7.days).iso8601 } }
+ let(:expected) { [no_start, no_end, fully_past] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by containing_date = today' do
+ let(:search_params) { { containing_date: today.iso8601 } }
+ let(:expected) { [no_end, covers_today] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by custom range' do
+ let(:expected) { [no_end, fully_future] }
+ let(:search_params) do
+ {
+ start_date: (today + 6.days).iso8601,
+ end_date: (today + 7.days).iso8601
+ }
+ end
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'using timeframe argument' do
+ let(:expected) { [no_end, fully_future] }
+ let(:search_params) do
+ {
+ timeframe: {
+ start: (today + 6.days).iso8601,
+ end: (today + 7.days).iso8601
+ }
+ }
+ end
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ describe 'timeframe validations' do
+ let(:vars) do
+ {
+ path: project.full_path,
+ start: (today + 6.days).iso8601,
+ end: (today + 7.days).iso8601
+ }
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ query = <<~GQL
+ query($path: ID!, $start: Date!, $end: Date!) {
+ project(fullPath: $path) {
+ milestones(timeframe: { start: $start, end: $end }) {
+ nodes { id }
+ }
+ }
+ }
+ GQL
+
+ post_graphql(query, current_user: current_user, variables: vars)
+ end
+ end
+
+ it 'is invalid to provide timeframe and start_date/end_date' do
+ query = <<~GQL
+ query($path: ID!, $tstart: Date!, $tend: Date!, $start: Time!, $end: Time!) {
+ project(fullPath: $path) {
+ milestones(timeframe: { start: $tstart, end: $tend }, startDate: $start, endDate: $end) {
+ nodes { id }
+ }
+ }
+ }
+ GQL
+
+ post_graphql(query, current_user: current_user,
+ variables: vars.merge(vars.transform_keys { |k| :"t#{k}" }))
+
+ expect(graphql_errors).to contain_exactly(a_hash_including('message' => include('deprecated in favor of timeframe')))
+ end
+
+ it 'is invalid to invert the timeframe arguments' do
+ query = <<~GQL
+ query($path: ID!, $start: Date!, $end: Date!) {
+ project(fullPath: $path) {
+ milestones(timeframe: { start: $end, end: $start }) {
+ nodes { id }
+ }
+ }
+ }
+ GQL
+
+ post_graphql(query, current_user: current_user, variables: vars)
+
+ expect(graphql_errors).to contain_exactly(a_hash_including('message' => include('start must be before end')))
+ end
+ end
+end