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-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /spec/requests/api/graphql
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'spec/requests/api/graphql')
-rw-r--r--spec/requests/api/graphql/boards/board_list_issues_query_spec.rb101
-rw-r--r--spec/requests/api/graphql/boards/board_lists_query_spec.rb14
-rw-r--r--spec/requests/api/graphql/ci/groups_spec.rb55
-rw-r--r--spec/requests/api/graphql/ci/jobs_spec.rb93
-rw-r--r--spec/requests/api/graphql/ci/stages_spec.rb46
-rw-r--r--spec/requests/api/graphql/issue_status_counts_spec.rb58
-rw-r--r--spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb22
-rw-r--r--spec/requests/api/graphql/milestone_spec.rb47
-rw-r--r--spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb109
-rw-r--r--spec/requests/api/graphql/mutations/boards/lists/update_spec.rb57
-rw-r--r--spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/design_management/move_spec.rb122
-rw-r--r--spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb6
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb12
-rw-r--r--spec/requests/api/graphql/mutations/issues/update_spec.rb41
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/create_spec.rb1
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb57
-rw-r--r--spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/update/note_spec.rb39
-rw-r--r--spec/requests/api/graphql/mutations/snippets/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/snippets/update_spec.rb3
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb51
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb6
-rw-r--r--spec/requests/api/graphql/project/alert_management/alerts_spec.rb15
-rw-r--r--spec/requests/api/graphql/project/container_expiration_policy_spec.rb1
-rw-r--r--spec/requests/api/graphql/project/issue/designs/designs_spec.rb3
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb1
-rw-r--r--spec/requests/api/graphql/project/jira_import_spec.rb5
-rw-r--r--spec/requests/api/graphql/project/jira_projects_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb39
-rw-r--r--spec/requests/api/graphql/project/packages_spec.rb50
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb6
-rw-r--r--spec/requests/api/graphql/project/repository_spec.rb1
-rw-r--r--spec/requests/api/graphql/project/tree/tree_spec.rb1
-rw-r--r--spec/requests/api/graphql/project_query_spec.rb14
-rw-r--r--spec/requests/api/graphql/user_query_spec.rb6
37 files changed, 971 insertions, 121 deletions
diff --git a/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
new file mode 100644
index 00000000000..ae1abb50a40
--- /dev/null
+++ b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'get board lists' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:unauth_user) { create(:user) }
+ let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace ) }
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:project_label) { create(:label, project: project, name: 'Development') }
+ let_it_be(:project_label2) { create(:label, project: project, name: 'Testing') }
+ let_it_be(:group_label) { create(:group_label, group: group, name: 'Development') }
+ let_it_be(:group_label2) { create(:group_label, group: group, name: 'Testing') }
+
+ let(:params) { '' }
+ let(:board) { }
+ let(:board_parent_type) { board_parent.class.to_s.downcase }
+ let(:board_data) { graphql_data[board_parent_type]['boards']['nodes'][0] }
+ let(:lists_data) { board_data['lists']['nodes'][0] }
+ let(:issues_data) { lists_data['issues']['nodes'] }
+
+ def query(list_params = params)
+ graphql_query_for(
+ board_parent_type,
+ { 'fullPath' => board_parent.full_path },
+ <<~BOARDS
+ boards(first: 1) {
+ nodes {
+ lists {
+ nodes {
+ issues {
+ count
+ nodes {
+ #{all_graphql_fields_for('issues'.classify)}
+ }
+ }
+ }
+ }
+ }
+ }
+ BOARDS
+ )
+ end
+
+ def issue_titles
+ issues_data.map { |i| i['title'] }
+ end
+
+ shared_examples 'group and project board list issues query' do
+ let!(:board) { create(:board, resource_parent: board_parent) }
+ let!(:label_list) { create(:list, board: board, label: label, position: 10) }
+ let!(:issue1) { create(:issue, project: issue_project, labels: [label], relative_position: 9) }
+ let!(:issue2) { create(:issue, project: issue_project, labels: [label], relative_position: 2) }
+ let!(:issue3) { create(:issue, project: issue_project, labels: [label], relative_position: 9) }
+ let!(:issue4) { create(:issue, project: issue_project, labels: [label2], relative_position: 432) }
+
+ context 'when the user does not have access to the board' do
+ it 'returns nil' do
+ post_graphql(query, current_user: unauth_user)
+
+ expect(graphql_data[board_parent_type]).to be_nil
+ end
+ end
+
+ context 'when user can read the board' do
+ before do
+ board_parent.add_reporter(user)
+ end
+
+ it 'can access the issues' do
+ post_graphql(query("id: \"#{global_id_of(label_list)}\""), current_user: user)
+
+ expect(issue_titles).to eq([issue2.title, issue3.title, issue1.title])
+ end
+ end
+ end
+
+ describe 'for a project' do
+ let(:board_parent) { project }
+ let(:label) { project_label }
+ let(:label2) { project_label2 }
+ let(:issue_project) { project }
+
+ it_behaves_like 'group and project board list issues query'
+ end
+
+ describe 'for a group' do
+ let(:board_parent) { group }
+ let(:label) { group_label }
+ let(:label2) { group_label2 }
+ let(:issue_project) { create(:project, :private, group: group) }
+
+ before do
+ allow(board_parent).to receive(:multiple_issue_boards_available?).and_return(false)
+ end
+
+ it_behaves_like 'group and project board list issues query'
+ end
+end
diff --git a/spec/requests/api/graphql/boards/board_lists_query_spec.rb b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
index 8a89590c85a..0838900eaba 100644
--- a/spec/requests/api/graphql/boards/board_lists_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
@@ -105,6 +105,20 @@ RSpec.describe 'get board lists' do
end
end
end
+
+ context 'when querying for a single list' do
+ before do
+ board_parent.add_reporter(user)
+ end
+
+ it 'finds the correct list' do
+ label_list = create(:list, board: board, label: label, position: 10)
+
+ post_graphql(query("id: \"#{global_id_of(label_list)}\""), current_user: user)
+
+ expect(lists_data[0]['node']['title']).to eq label_list.title
+ end
+ end
end
describe 'for a project' do
diff --git a/spec/requests/api/graphql/ci/groups_spec.rb b/spec/requests/api/graphql/ci/groups_spec.rb
new file mode 100644
index 00000000000..9e81358a152
--- /dev/null
+++ b/spec/requests/api/graphql/ci/groups_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'Query.project.pipeline.stages.groups' do
+ include GraphqlHelpers
+
+ let(:project) { create(:project, :repository, :public) }
+ let(:user) { create(:user) }
+ let(:pipeline) { create(:ci_pipeline, project: project, user: user) }
+ let(:group_graphql_data) { graphql_data.dig('project', 'pipeline', 'stages', 'nodes', 0, 'groups', 'nodes') }
+
+ let(:params) { {} }
+
+ let(:fields) do
+ <<~QUERY
+ nodes {
+ #{all_graphql_fields_for('CiGroup')}
+ }
+ QUERY
+ end
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipeline(iid: "#{pipeline.iid}") {
+ stages {
+ nodes {
+ groups {
+ #{fields}
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ before do
+ create(:commit_status, pipeline: pipeline, name: 'rspec 0 2')
+ create(:commit_status, pipeline: pipeline, name: 'rspec 0 1')
+ create(:commit_status, pipeline: pipeline, name: 'spinach 0 1')
+ post_graphql(query, current_user: user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns a array of jobs belonging to a pipeline' do
+ expect(group_graphql_data.map { |g| g.slice('name', 'size') }).to eq([
+ { 'name' => 'rspec', 'size' => 2 },
+ { 'name' => 'spinach', 'size' => 1 }
+ ])
+ end
+end
diff --git a/spec/requests/api/graphql/ci/jobs_spec.rb b/spec/requests/api/graphql/ci/jobs_spec.rb
new file mode 100644
index 00000000000..7d416f4720b
--- /dev/null
+++ b/spec/requests/api/graphql/ci/jobs_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'Query.project.pipeline.stages.groups.jobs' do
+ include GraphqlHelpers
+
+ let(:project) { create(:project, :repository, :public) }
+ let(:user) { create(:user) }
+ let(:pipeline) do
+ pipeline = create(:ci_pipeline, project: project, user: user)
+ stage = create(:ci_stage_entity, pipeline: pipeline, name: 'first')
+ create(:commit_status, stage_id: stage.id, pipeline: pipeline, name: 'my test job')
+
+ pipeline
+ end
+
+ def first(field)
+ [field.pluralize, 'nodes', 0]
+ end
+
+ let(:jobs_graphql_data) { graphql_data.dig(*%w[project pipeline], *first('stage'), *first('group'), 'jobs', 'nodes') }
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipeline(iid: "#{pipeline.iid}") {
+ stages {
+ nodes {
+ name
+ groups {
+ nodes {
+ name
+ jobs {
+ nodes {
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'returns the jobs of a pipeline stage' do
+ post_graphql(query, current_user: user)
+
+ expect(jobs_graphql_data).to contain_exactly(a_hash_including('name' => 'my test job'))
+ end
+
+ context 'when fetching jobs from the pipeline' do
+ it 'avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: user)
+ end
+
+ build_stage = create(:ci_stage_entity, name: 'build', pipeline: pipeline)
+ test_stage = create(:ci_stage_entity, name: 'test', pipeline: pipeline)
+ create(:commit_status, pipeline: pipeline, stage_id: build_stage.id, name: 'docker 1 2')
+ create(:commit_status, pipeline: pipeline, stage_id: build_stage.id, name: 'docker 2 2')
+ create(:commit_status, pipeline: pipeline, stage_id: test_stage.id, name: 'rspec 1 2')
+ create(:commit_status, pipeline: pipeline, stage_id: test_stage.id, name: 'rspec 2 2')
+
+ expect do
+ post_graphql(query, current_user: user)
+ end.not_to exceed_query_limit(control_count)
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ build_stage = graphql_data.dig('project', 'pipeline', 'stages', 'nodes').find do |stage|
+ stage['name'] == 'build'
+ end
+ test_stage = graphql_data.dig('project', 'pipeline', 'stages', 'nodes').find do |stage|
+ stage['name'] == 'test'
+ end
+ docker_group = build_stage.dig('groups', 'nodes').first
+ rspec_group = test_stage.dig('groups', 'nodes').first
+
+ expect(docker_group['name']).to eq('docker')
+ expect(rspec_group['name']).to eq('rspec')
+
+ docker_jobs = docker_group.dig('jobs', 'nodes')
+ rspec_jobs = rspec_group.dig('jobs', 'nodes')
+
+ expect(docker_jobs).to eq([{ 'name' => 'docker 1 2' }, { 'name' => 'docker 2 2' }])
+ expect(rspec_jobs).to eq([{ 'name' => 'rspec 1 2' }, { 'name' => 'rspec 2 2' }])
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/ci/stages_spec.rb b/spec/requests/api/graphql/ci/stages_spec.rb
new file mode 100644
index 00000000000..cd48a24b9c8
--- /dev/null
+++ b/spec/requests/api/graphql/ci/stages_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'Query.project.pipeline.stages' do
+ include GraphqlHelpers
+
+ let(:project) { create(:project, :repository, :public) }
+ let(:user) { create(:user) }
+ let(:pipeline) { create(:ci_pipeline, project: project, user: user) }
+ let(:stage_graphql_data) { graphql_data['project']['pipeline']['stages'] }
+
+ let(:params) { {} }
+
+ let(:fields) do
+ <<~QUERY
+ nodes {
+ #{all_graphql_fields_for('CiStage')}
+ }
+ QUERY
+ end
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipeline(iid: "#{pipeline.iid}") {
+ stages {
+ #{fields}
+ }
+ }
+ }
+ }
+ )
+ end
+
+ before do
+ create(:ci_stage_entity, pipeline: pipeline, name: 'deploy')
+ post_graphql(query, current_user: user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns the stage of a pipeline' do
+ expect(stage_graphql_data['nodes'].first['name']).to eq('deploy')
+ end
+end
diff --git a/spec/requests/api/graphql/issue_status_counts_spec.rb b/spec/requests/api/graphql/issue_status_counts_spec.rb
new file mode 100644
index 00000000000..3d8817c3bc5
--- /dev/null
+++ b/spec/requests/api/graphql/issue_status_counts_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting Issue counts by status' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:issue_opened) { create(:issue, project: project) }
+ let_it_be(:issue_closed) { create(:issue, :closed, project: project) }
+ let_it_be(:other_project_issue) { create(:issue) }
+ let(:params) { {} }
+
+ let(:fields) do
+ <<~QUERY
+ #{all_graphql_fields_for('IssueStatusCountsType'.classify)}
+ QUERY
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('issueStatusCounts', params, fields)
+ )
+ end
+
+ context 'with issue count data' do
+ let(:issue_counts) { graphql_data.dig('project', 'issueStatusCounts') }
+
+ context 'without project permissions' do
+ let(:user) { create(:user) }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+ it { expect(issue_counts).to be nil }
+ end
+
+ context 'with project permissions' do
+ before do
+ project.add_developer(current_user)
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+ it 'returns the correct counts for each status' do
+ expect(issue_counts).to eq(
+ 'all' => 2,
+ 'opened' => 1,
+ 'closed' => 1
+ )
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
index c47920087dc..ca5a9165760 100644
--- a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
+++ b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
@@ -30,22 +30,22 @@ RSpec.describe 'Getting Metrics Dashboard Annotations' do
let(:query) do
%(
- query {
- project(fullPath:"#{project.full_path}") {
- environments(name: "#{environment.name}") {
- nodes {
- metricsDashboard(path: "#{path}"){
- annotations(#{args}){
- nodes {
- #{fields}
- }
- }
+ query {
+ project(fullPath: "#{project.full_path}") {
+ environments(name: "#{environment.name}") {
+ nodes {
+ metricsDashboard(path: "#{path}") {
+ annotations(#{args}) {
+ nodes {
+ #{fields}
}
}
}
}
}
- )
+ }
+ }
+ )
end
before do
diff --git a/spec/requests/api/graphql/milestone_spec.rb b/spec/requests/api/graphql/milestone_spec.rb
new file mode 100644
index 00000000000..59de116fa2b
--- /dev/null
+++ b/spec/requests/api/graphql/milestone_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Querying a Milestone' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:milestone) { create(:milestone, project: project) }
+
+ let(:query) do
+ graphql_query_for('milestone', { id: milestone.to_global_id.to_s }, 'title')
+ end
+
+ subject { graphql_data['milestone'] }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ context 'when the user has access to the milestone' do
+ before_all do
+ project.add_guest(current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it { is_expected.to include('title' => milestone.name) }
+ end
+
+ context 'when the user does not have access to the milestone' do
+ it_behaves_like 'a working graphql query'
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'when ID argument is missing' do
+ let(:query) do
+ graphql_query_for('milestone', {}, 'title')
+ end
+
+ it 'raises an exception' do
+ expect(graphql_errors).to include(a_hash_including('message' => "Field 'milestone' is missing required arguments: id"))
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb b/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb
new file mode 100644
index 00000000000..e24ab0b07f2
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Reposition and move issue within board lists' do
+ include GraphqlHelpers
+
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:board) { create(:board, group: group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:development) { create(:label, project: project, name: 'Development') }
+ let_it_be(:testing) { create(:label, project: project, name: 'Testing') }
+ let_it_be(:list1) { create(:list, board: board, label: development, position: 0) }
+ let_it_be(:list2) { create(:list, board: board, label: testing, position: 1) }
+ let_it_be(:existing_issue1) { create(:labeled_issue, project: project, labels: [testing], relative_position: 10) }
+ let_it_be(:existing_issue2) { create(:labeled_issue, project: project, labels: [testing], relative_position: 50) }
+ let_it_be(:issue1) { create(:labeled_issue, project: project, labels: [development]) }
+
+ let(:mutation_class) { Mutations::Boards::Issues::IssueMoveList }
+ let(:mutation_name) { mutation_class.graphql_name }
+ let(:mutation_result_identifier) { mutation_name.camelize(:lower) }
+ let(:current_user) { user }
+ let(:params) { { board_id: board.to_global_id.to_s, project_path: project.full_path, iid: issue1.iid.to_s } }
+ let(:issue_move_params) do
+ {
+ from_list_id: list1.id,
+ to_list_id: list2.id
+ }
+ end
+
+ before_all do
+ group.add_maintainer(user)
+ end
+
+ shared_examples 'returns an error' do
+ it 'fails with error' do
+ message = "The resource that you are attempting to access does not exist or you don't have "\
+ "permission to perform this action"
+
+ post_graphql_mutation(mutation(params), current_user: current_user)
+
+ expect(graphql_errors).to include(a_hash_including('message' => message))
+ end
+ end
+
+ context 'when user has access to resources' do
+ context 'when repositioning an issue' do
+ let(:issue_move_params) { { move_after_id: existing_issue1.id, move_before_id: existing_issue2.id } }
+
+ it 'repositions an issue' do
+ post_graphql_mutation(mutation(params), current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ response_issue = json_response['data'][mutation_result_identifier]['issue']
+ expect(response_issue['iid']).to eq(issue1.iid.to_s)
+ expect(response_issue['relativePosition']).to be > existing_issue1.relative_position
+ expect(response_issue['relativePosition']).to be < existing_issue2.relative_position
+ end
+ end
+
+ context 'when moving an issue to a different list' do
+ let(:issue_move_params) { { from_list_id: list1.id, to_list_id: list2.id } }
+
+ it 'moves issue to a different list' do
+ post_graphql_mutation(mutation(params), current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ response_issue = json_response['data'][mutation_result_identifier]['issue']
+ expect(response_issue['iid']).to eq(issue1.iid.to_s)
+ expect(response_issue['labels']['edges'][0]['node']['title']).to eq(testing.title)
+ end
+ end
+ end
+
+ context 'when user has no access to resources' do
+ context 'the user is not allowed to update the issue' do
+ let(:current_user) { create(:user) }
+
+ it_behaves_like 'returns an error'
+ end
+
+ context 'when the user can not read board' do
+ let(:board) { create(:board, group: create(:group, :private)) }
+
+ it_behaves_like 'returns an error'
+ end
+ end
+
+ def mutation(additional_params = {})
+ graphql_mutation(mutation_name, issue_move_params.merge(additional_params),
+ <<-QL.strip_heredoc
+ clientMutationId
+ issue {
+ iid,
+ relativePosition
+ labels {
+ edges {
+ node{
+ title
+ }
+ }
+ }
+ }
+ errors
+ QL
+ )
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb b/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb
new file mode 100644
index 00000000000..8a6d2cb3994
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Update of an existing board list' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:board) { create(:board, group: group) }
+ let_it_be(:list) { create(:list, board: board, position: 0) }
+ let_it_be(:list2) { create(:list, board: board) }
+ let_it_be(:input) { { list_id: list.to_global_id.to_s, position: 1, collapsed: true } }
+ let(:mutation) { graphql_mutation(:update_board_list, input) }
+ let(:mutation_response) { graphql_mutation_response(:update_board_list) }
+
+ context 'the user is not allowed to read board lists' do
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
+ end
+
+ before do
+ list.update_preferences_for(current_user, collapsed: false)
+ end
+
+ context 'when user has permissions to admin board lists' do
+ before do
+ group.add_reporter(current_user)
+ end
+
+ it 'updates the list position and collapsed state' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['list']).to include(
+ 'position' => 1,
+ 'collapsed' => true
+ )
+ end
+ end
+
+ context 'when user has permissions to read board lists' do
+ before do
+ group.add_guest(current_user)
+ end
+
+ it 'updates the list collapsed state but not the list position' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['list']).to include(
+ 'position' => 0,
+ 'collapsed' => true
+ )
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb b/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
index bc1b42d68e6..7bef812bfec 100644
--- a/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe 'Updating the container expiration policy' do
older_than: 'FOURTEEN_DAYS'
}
end
+
let(:mutation) do
graphql_mutation(:update_container_expiration_policy, params,
<<~QL
@@ -32,6 +33,7 @@ RSpec.describe 'Updating the container expiration policy' do
QL
)
end
+
let(:mutation_response) { graphql_mutation_response(:update_container_expiration_policy) }
let(:container_expiration_policy_response) { mutation_response['containerExpirationPolicy'] }
diff --git a/spec/requests/api/graphql/mutations/design_management/move_spec.rb b/spec/requests/api/graphql/mutations/design_management/move_spec.rb
new file mode 100644
index 00000000000..dd121ec733e
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/design_management/move_spec.rb
@@ -0,0 +1,122 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe "moving designs" do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:designs) { create_list(:design, 3, :with_versions, :with_relative_position, issue: issue) }
+ let_it_be(:developer) { create(:user, developer_projects: [issue.project]) }
+
+ let(:user) { developer }
+
+ let(:current_design) { designs.first }
+ let(:previous_design) { designs.second }
+ let(:next_design) { designs.third }
+ let(:mutation_name) { :design_management_move }
+
+ let(:mutation) do
+ input = {
+ id: current_design.to_global_id.to_s,
+ previous: previous_design&.to_global_id&.to_s,
+ next: next_design&.to_global_id&.to_s
+ }.compact
+
+ graphql_mutation(mutation_name, input, <<~FIELDS)
+ errors
+ designCollection {
+ designs {
+ nodes {
+ filename
+ }
+ }
+ }
+ FIELDS
+ end
+
+ let(:move_designs) { post_graphql_mutation(mutation, current_user: user) }
+ let(:mutation_response) { graphql_mutation_response(mutation_name) }
+
+ before do
+ enable_design_management
+ designs.each(&:reset)
+ issue.reset
+ end
+
+ shared_examples 'a successful move' do
+ it 'does not error, and reports the current order' do
+ move_designs
+
+ expect(graphql_errors).not_to be_present
+
+ expect(mutation_response).to eq(
+ 'errors' => [],
+ 'designCollection' => {
+ 'designs' => {
+ 'nodes' => new_order.map { |d| { 'filename' => d.filename } }
+ }
+ }
+ )
+ end
+ end
+
+ context 'the user is not allowed to move designs' do
+ let(:user) { create(:user) }
+
+ it 'returns an error' do
+ move_designs
+
+ expect(graphql_errors).to be_present
+ end
+ end
+
+ context 'the neighbors do not have positions' do
+ let!(:previous_design) { create(:design, :with_versions, issue: issue) }
+ let!(:next_design) { create(:design, :with_versions, issue: issue) }
+
+ let(:new_order) do
+ [
+ designs.second,
+ designs.third,
+ previous_design, current_design, next_design
+ ]
+ end
+
+ it_behaves_like 'a successful move'
+
+ it 'maintains the correct order in the presence of other unpositioned designs' do
+ other_design = create(:design, :with_versions, issue: issue)
+
+ move_designs
+ moved_designs = mutation_response.dig('designCollection', 'designs', 'nodes')
+
+ expect(moved_designs.map { |d| d['filename'] })
+ .to eq([*new_order.map(&:filename), other_design.filename])
+ end
+ end
+
+ context 'moving a design between two others' do
+ let(:new_order) { [designs.second, designs.first, designs.third] }
+
+ it_behaves_like 'a successful move'
+ end
+
+ context 'moving a design to the start' do
+ let(:current_design) { designs.last }
+ let(:next_design) { designs.first }
+ let(:previous_design) { nil }
+ let(:new_order) { [designs.last, designs.first, designs.second] }
+
+ it_behaves_like 'a successful move'
+ end
+
+ context 'moving a design to the end' do
+ let(:current_design) { designs.first }
+ let(:next_design) { nil }
+ let(:previous_design) { designs.last }
+ let(:new_order) { [designs.second, designs.third, designs.first] }
+
+ it_behaves_like 'a successful move'
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb b/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
index e83da830935..457c37e900b 100644
--- a/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
+++ b/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
@@ -10,9 +10,11 @@ RSpec.describe 'Toggling the resolve status of a discussion' do
let(:discussion) do
create(:diff_note_on_merge_request, noteable: noteable, project: project).to_discussion
end
+
let(:mutation) do
graphql_mutation(:discussion_toggle_resolve, { id: discussion.to_global_id.to_s, resolve: true })
end
+
let(:mutation_response) { graphql_mutation_response(:discussion_toggle_resolve) }
context 'when the user does not have permission' do
diff --git a/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb b/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb
index 3dd1225db5a..b3c9b9d4995 100644
--- a/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb
@@ -49,13 +49,13 @@ RSpec.describe 'Setting Due Date of an issue' do
expect(mutation_response['issue']['dueDate']).to eq(2.days.since.to_date.to_s)
end
- context 'when passing due date without a date value' do
+ context 'when the due date value is not a valid time' do
let(:input) { { due_date: 'test' } }
- it 'returns internal server error' do
+ it 'returns a coercion error' do
post_graphql_mutation(mutation, current_user: current_user)
- expect(graphql_errors).to include(a_hash_including('message' => 'Internal server error'))
+ expect(graphql_errors).to include(a_hash_including('message' => /provided invalid value for dueDate/))
end
end
end
diff --git a/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb b/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb
new file mode 100644
index 00000000000..1edc1e0553b
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Setting subscribed status of an issue' do
+ include GraphqlHelpers
+
+ it_behaves_like 'a subscribable resource api' do
+ let_it_be(:resource) { create(:issue) }
+ let(:mutation_name) { :issue_set_subscription }
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/issues/update_spec.rb b/spec/requests/api/graphql/mutations/issues/update_spec.rb
new file mode 100644
index 00000000000..fd983c683be
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/issues/update_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Update of an existing issue' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let(:input) do
+ {
+ project_path: project.full_path,
+ iid: issue.iid.to_s,
+ locked: true
+ }
+ end
+
+ let(:mutation) { graphql_mutation(:update_issue, input) }
+ let(:mutation_response) { graphql_mutation_response(:update_issue) }
+
+ context 'the user is not allowed to update issue' do
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
+ end
+
+ context 'when user has permissions to update issue' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'updates the issue' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['issue']).to include(
+ 'discussionLocked' => true
+ )
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
index d4ac639e226..9297ca054c7 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe 'Creation of a new merge request' do
target_branch: target_branch
}
end
+
let(:title) { 'MergeRequest' }
let(:source_branch) { 'new_branch' }
let(:target_branch) { 'master' }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb
index 6b3035fbf48..d90faa605c0 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb
@@ -5,59 +5,8 @@ require 'spec_helper'
RSpec.describe 'Setting subscribed status of a merge request' do
include GraphqlHelpers
- let(:current_user) { create(:user) }
- let(:merge_request) { create(:merge_request) }
- let(:project) { merge_request.project }
- let(:input) { { subscribed_state: true } }
-
- let(:mutation) do
- variables = {
- project_path: project.full_path,
- iid: merge_request.iid.to_s
- }
- graphql_mutation(:merge_request_set_subscription, variables.merge(input),
- <<-QL.strip_heredoc
- clientMutationId
- errors
- mergeRequest {
- id
- subscribed
- }
- QL
- )
- end
-
- def mutation_response
- graphql_mutation_response(:merge_request_set_subscription)['mergeRequest']['subscribed']
- end
-
- before do
- project.add_developer(current_user)
- end
-
- it 'returns an error if the user is not allowed to update the merge request' do
- post_graphql_mutation(mutation, current_user: create(:user))
-
- expect(graphql_errors).not_to be_empty
- end
-
- it 'marks the merge request as WIP' do
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(response).to have_gitlab_http_status(:success)
- expect(mutation_response).to eq(true)
- end
-
- context 'when passing subscribe false as input' do
- let(:input) { { subscribed_state: false } }
-
- it 'unmarks the merge request as subscribed' do
- merge_request.subscribe(current_user, project)
-
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(response).to have_gitlab_http_status(:success)
- expect(mutation_response).to eq(false)
- end
+ it_behaves_like 'a subscribable resource api' do
+ let_it_be(:resource) { create(:merge_request) }
+ let(:mutation_name) { :merge_request_set_subscription }
end
end
diff --git a/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
index f7be671e5f3..463a872d95d 100644
--- a/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
@@ -33,6 +33,7 @@ RSpec.describe 'Updating an image DiffNote' do
y: updated_y
}
end
+
let!(:diff_note) do
create(:image_diff_note_on_merge_request,
noteable: noteable,
@@ -40,6 +41,7 @@ RSpec.describe 'Updating an image DiffNote' do
note: original_body,
position: original_position)
end
+
let(:mutation) do
variables = {
id: GitlabSchema.id_from_object(diff_note).to_s,
diff --git a/spec/requests/api/graphql/mutations/notes/update/note_spec.rb b/spec/requests/api/graphql/mutations/notes/update/note_spec.rb
index 38378310d9f..0d93afe9434 100644
--- a/spec/requests/api/graphql/mutations/notes/update/note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/update/note_spec.rb
@@ -8,11 +8,9 @@ RSpec.describe 'Updating a Note' do
let!(:note) { create(:note, note: original_body) }
let(:original_body) { 'Initial body text' }
let(:updated_body) { 'Updated body text' }
+ let(:params) { { body: updated_body, confidential: true } }
let(:mutation) do
- variables = {
- id: GitlabSchema.id_from_object(note).to_s,
- body: updated_body
- }
+ variables = params.merge(id: GitlabSchema.id_from_object(note).to_s)
graphql_mutation(:update_note, variables)
end
@@ -31,6 +29,7 @@ RSpec.describe 'Updating a Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(note.reload.note).to eq(original_body)
+ expect(note.confidential).to be_falsey
end
end
@@ -43,12 +42,40 @@ RSpec.describe 'Updating a Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(note.reload.note).to eq(updated_body)
+ expect(note.confidential).to be_truthy
end
it 'returns the updated Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['note']['body']).to eq(updated_body)
+ expect(mutation_response['note']['confidential']).to be_truthy
+ end
+
+ context 'when only confidential param is present' do
+ let(:params) { { confidential: true } }
+
+ it 'updates only the note confidentiality' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(note.reload.note).to eq(original_body)
+ expect(note.confidential).to be_truthy
+ end
+ end
+
+ context 'when only body param is present' do
+ let(:params) { { body: updated_body } }
+
+ before do
+ note.update_column(:confidential, true)
+ end
+
+ it 'updates only the note body' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(note.reload.note).to eq(updated_body)
+ expect(note.confidential).to be_truthy
+ end
end
context 'when there are ActiveRecord validation errors' do
@@ -60,12 +87,14 @@ RSpec.describe 'Updating a Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(note.reload.note).to eq(original_body)
+ expect(note.confidential).to be_falsey
end
- it 'returns the Note with its original body' do
+ it 'returns the original Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['note']['body']).to eq(original_body)
+ expect(mutation_response['note']['confidential']).to be_falsey
end
end
diff --git a/spec/requests/api/graphql/mutations/snippets/create_spec.rb b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
index e2474e1bcce..56a5f4907c1 100644
--- a/spec/requests/api/graphql/mutations/snippets/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
@@ -149,7 +149,7 @@ RSpec.describe 'Creating a Snippet' do
visibility_level: visibility_level,
project_path: project_path,
title: title,
- files: actions
+ blob_actions: actions
}
end
diff --git a/spec/requests/api/graphql/mutations/snippets/update_spec.rb b/spec/requests/api/graphql/mutations/snippets/update_spec.rb
index 3b2f9dc0f19..3f39c0ab851 100644
--- a/spec/requests/api/graphql/mutations/snippets/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/update_spec.rb
@@ -26,6 +26,7 @@ RSpec.describe 'Updating a Snippet' do
title: updated_title
}
end
+
let(:mutation) do
graphql_mutation(:update_snippet, mutation_vars)
end
@@ -157,7 +158,7 @@ RSpec.describe 'Updating a Snippet' do
let(:mutation_vars) do
{
id: snippet_gid,
- files: [
+ blob_actions: [
{ action: :update, filePath: updated_file, content: updated_content },
{ action: :delete, filePath: deleted_file }
]
diff --git a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
new file mode 100644
index 00000000000..3a9077061ad
--- /dev/null
+++ b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'getting Alert Management Alert Assignees' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project) }
+ let_it_be(:other_alert) { create(:alert_management_alert, project: project) }
+ let_it_be(:todo) { create(:todo, :pending, target: alert, user: current_user, project: project) }
+ let_it_be(:other_todo) { create(:todo, :pending, target: other_alert, user: current_user, project: project) }
+
+ let(:fields) do
+ <<~QUERY
+ nodes {
+ iid
+ todos {
+ nodes {
+ id
+ }
+ }
+ }
+ QUERY
+ end
+
+ let(:graphql_query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('alertManagementAlerts', {}, fields)
+ )
+ end
+
+ let(:gql_alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
+ let(:gql_todos) { gql_alerts.map { |gql_alert| [gql_alert['iid'], gql_alert['todos']['nodes']] }.to_h }
+ let(:gql_alert_todo) { gql_todos[alert.iid.to_s].first }
+ let(:gql_other_alert_todo) { gql_todos[other_alert.iid.to_s].first }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'includes the correct metrics dashboard url' do
+ post_graphql(graphql_query, current_user: current_user)
+
+ expect(gql_alert_todo['id']).to eq(todo.to_global_id.to_s)
+ expect(gql_other_alert_todo['id']).to eq(other_todo.to_global_id.to_s)
+ end
+end
diff --git a/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb b/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
index b62215f43fb..9fbf5aaa41f 100644
--- a/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
@@ -6,8 +6,8 @@ RSpec.describe 'getting Alert Management Alert counts by status' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:current_user) { create(:user) }
- let_it_be(:alert_1) { create(:alert_management_alert, :resolved, project: project) }
- let_it_be(:alert_2) { create(:alert_management_alert, project: project) }
+ let_it_be(:alert_resolved) { create(:alert_management_alert, :resolved, project: project) }
+ let_it_be(:alert_triggered) { create(:alert_management_alert, project: project) }
let_it_be(:other_project_alert) { create(:alert_management_alert) }
let(:params) { {} }
@@ -58,7 +58,7 @@ RSpec.describe 'getting Alert Management Alert counts by status' do
end
context 'with search criteria' do
- let(:params) { { search: alert_1.title } }
+ let(:params) { { search: alert_resolved.title } }
it_behaves_like 'a working graphql query'
it 'returns the correct counts for each status' do
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 f050c6873f3..d3a2e6a1deb 100644
--- a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
@@ -4,12 +4,12 @@ require 'spec_helper'
RSpec.describe 'getting Alert Management Alerts' do
include GraphqlHelpers
- let_it_be(:payload) { { 'custom' => { 'alert' => 'payload' } } }
+ let_it_be(:payload) { { 'custom' => { 'alert' => 'payload' }, 'runbook' => 'runbook' } }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:current_user) { create(:user) }
- let_it_be(:resolved_alert) { create(:alert_management_alert, :all_fields, :resolved, project: project, issue: nil, severity: :low) }
- let_it_be(:triggered_alert) { create(:alert_management_alert, :all_fields, project: project, severity: :critical, payload: payload) }
- let_it_be(:other_project_alert) { create(:alert_management_alert, :all_fields) }
+ let_it_be(:resolved_alert) { create(:alert_management_alert, :all_fields, :resolved, project: project, issue: nil, severity: :low).present }
+ let_it_be(:triggered_alert) { create(:alert_management_alert, :all_fields, project: project, severity: :critical, payload: payload).present }
+ let_it_be(:other_project_alert) { create(:alert_management_alert, :all_fields).present }
let(:params) { {} }
@@ -71,10 +71,13 @@ RSpec.describe 'getting Alert Management Alerts' do
'eventCount' => triggered_alert.events,
'startedAt' => triggered_alert.started_at.strftime('%Y-%m-%dT%H:%M:%SZ'),
'endedAt' => nil,
- 'details' => { 'custom.alert' => 'payload' },
+ 'details' => { 'custom.alert' => 'payload', 'runbook' => 'runbook' },
'createdAt' => triggered_alert.created_at.strftime('%Y-%m-%dT%H:%M:%SZ'),
'updatedAt' => triggered_alert.updated_at.strftime('%Y-%m-%dT%H:%M:%SZ'),
- 'metricsDashboardUrl' => nil
+ 'metricsDashboardUrl' => nil,
+ 'detailsUrl' => triggered_alert.details_url,
+ 'prometheusAlert' => nil,
+ 'runbook' => 'runbook'
)
expect(second_alert).to include(
diff --git a/spec/requests/api/graphql/project/container_expiration_policy_spec.rb b/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
index b064e4d43e9..dc16847a669 100644
--- a/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
+++ b/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe 'getting a repository in a project' do
#{all_graphql_fields_for('container_expiration_policy'.classify)}
QUERY
end
+
let(:query) do
graphql_query_for(
'project',
diff --git a/spec/requests/api/graphql/project/issue/designs/designs_spec.rb b/spec/requests/api/graphql/project/issue/designs/designs_spec.rb
index e47c025f8b2..decab900a43 100644
--- a/spec/requests/api/graphql/project/issue/designs/designs_spec.rb
+++ b/spec/requests/api/graphql/project/issue/designs/designs_spec.rb
@@ -24,12 +24,14 @@ RSpec.describe 'Getting designs related to an issue' do
}
NODE
end
+
let(:issue) { design.issue }
let(:project) { issue.project }
let(:query) { make_query }
let(:design_collection) do
graphql_data_at(:project, :issue, :design_collection)
end
+
let(:design_response) do
design_collection.dig('designs', 'edges').first['node']
end
@@ -185,6 +187,7 @@ RSpec.describe 'Getting designs related to an issue' do
}
NODE
end
+
let(:design_response) do
design_collection['designs']['edges']
end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index cdfff2f50d4..06e613a09bc 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe 'getting an issue list for a project' do
[create(:issue, project: project, discussion_locked: true),
create(:issue, project: project)]
end
+
let(:fields) do
<<~QUERY
edges {
diff --git a/spec/requests/api/graphql/project/jira_import_spec.rb b/spec/requests/api/graphql/project/jira_import_spec.rb
index 814965262b6..1cc30b95162 100644
--- a/spec/requests/api/graphql/project/jira_import_spec.rb
+++ b/spec/requests/api/graphql/project/jira_import_spec.rb
@@ -53,6 +53,7 @@ RSpec.describe 'query Jira import data' do
}
)
end
+
let(:jira_imports) { graphql_data.dig('project', 'jiraImports', 'nodes')}
let(:jira_import_status) { graphql_data.dig('project', 'jiraImportStatus')}
@@ -106,7 +107,7 @@ RSpec.describe 'query Jira import data' do
let(:query) do
%(
query {
- project(fullPath:"#{project.full_path}") {
+ project(fullPath: "#{project.full_path}") {
jiraImports(first: 1) {
nodes {
jiraProjectKey
@@ -132,7 +133,7 @@ RSpec.describe 'query Jira import data' do
let(:query) do
%(
query {
- project(fullPath:"#{project.full_path}") {
+ project(fullPath: "#{project.full_path}") {
jiraImports(last: 1) {
nodes {
jiraProjectKey
diff --git a/spec/requests/api/graphql/project/jira_projects_spec.rb b/spec/requests/api/graphql/project/jira_projects_spec.rb
index d5f59711ab1..410d5b21505 100644
--- a/spec/requests/api/graphql/project/jira_projects_spec.rb
+++ b/spec/requests/api/graphql/project/jira_projects_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe 'query Jira projects' do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
- include_context 'jira projects request context'
+ include_context 'Jira projects request context'
let(:services) { graphql_data_at(:project, :services, :edges) }
let(:jira_projects) { services.first.dig('node', 'projects', 'nodes') }
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
index e2255fdb048..bb63a5994b0 100644
--- a/spec/requests/api/graphql/project/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -171,4 +171,43 @@ RSpec.describe 'getting merge request listings nested in a project' do
it_behaves_like 'searching with parameters'
end
+
+ describe 'fields' do
+ let(:requested_fields) { nil }
+ let(:extra_iid_for_second_query) { merge_request_c.iid.to_s }
+ let(:search_params) { { iids: [merge_request_a.iid.to_s, merge_request_b.iid.to_s] } }
+
+ def execute_query
+ query = query_merge_requests(requested_fields)
+ post_graphql(query, current_user: current_user)
+ end
+
+ context 'when requesting `commit_count`' do
+ let(:requested_fields) { [:commit_count] }
+
+ it 'exposes `commit_count`' do
+ merge_request_a.metrics.update!(commits_count: 5)
+
+ execute_query
+
+ expect(results).to include(a_hash_including('commitCount' => 5))
+ end
+
+ include_examples 'N+1 query check'
+ end
+
+ context 'when requesting `merged_at`' do
+ let(:requested_fields) { [:merged_at] }
+
+ before do
+ # make the MRs "merged"
+ [merge_request_a, merge_request_b, merge_request_c].each do |mr|
+ mr.update_column(:state_id, MergeRequest.available_states[:merged])
+ mr.metrics.update_column(:merged_at, Time.now)
+ end
+ end
+
+ include_examples 'N+1 query check'
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/packages_spec.rb b/spec/requests/api/graphql/project/packages_spec.rb
index 88f97f9256b..5df98ed1e6b 100644
--- a/spec/requests/api/graphql/project/packages_spec.rb
+++ b/spec/requests/api/graphql/project/packages_spec.rb
@@ -28,42 +28,40 @@ RSpec.describe 'getting a package list for a project' do
)
end
- context 'without the need for a license' do
- context 'when user has access to the project' do
- before do
- project.add_reporter(current_user)
- post_graphql(query, current_user: current_user)
- end
+ context 'when user has access to the project' do
+ before do
+ project.add_reporter(current_user)
+ post_graphql(query, current_user: current_user)
+ end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns packages successfully' do
- expect(packages_data[0]['node']['name']).to eq package.name
- end
+ it 'returns packages successfully' do
+ expect(packages_data[0]['node']['name']).to eq package.name
end
+ end
- context 'when the user does not have access to the project/packages' do
- before do
- post_graphql(query, current_user: current_user)
- end
+ context 'when the user does not have access to the project/packages' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns nil' do
- expect(graphql_data['project']).to be_nil
- end
+ it 'returns nil' do
+ expect(graphql_data['project']).to be_nil
end
+ end
- context 'when the user is not autenthicated' do
- before do
- post_graphql(query)
- end
+ context 'when the user is not autenthicated' do
+ before do
+ post_graphql(query)
+ end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns nil' do
- expect(graphql_data['project']).to be_nil
- end
+ it 'returns nil' do
+ expect(graphql_data['project']).to be_nil
end
end
end
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index 57b9de25c3d..fef0e7e160c 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -29,4 +29,10 @@ RSpec.describe 'getting pipeline information nested in a project' do
expect(pipeline_graphql_data).not_to be_nil
end
+
+ it 'contains configSource' do
+ post_graphql(query, current_user: current_user)
+
+ expect(pipeline_graphql_data.dig('configSource')).to eq('UNKNOWN_SOURCE')
+ end
end
diff --git a/spec/requests/api/graphql/project/repository_spec.rb b/spec/requests/api/graphql/project/repository_spec.rb
index bd719a69647..a4984688557 100644
--- a/spec/requests/api/graphql/project/repository_spec.rb
+++ b/spec/requests/api/graphql/project/repository_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe 'getting a repository in a project' do
#{all_graphql_fields_for('repository'.classify)}
QUERY
end
+
let(:query) do
graphql_query_for(
'project',
diff --git a/spec/requests/api/graphql/project/tree/tree_spec.rb b/spec/requests/api/graphql/project/tree/tree_spec.rb
index bce63d57c38..f4cd316da96 100644
--- a/spec/requests/api/graphql/project/tree/tree_spec.rb
+++ b/spec/requests/api/graphql/project/tree/tree_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe 'getting a tree in a project' do
}
QUERY
end
+
let(:query) do
graphql_query_for(
'project',
diff --git a/spec/requests/api/graphql/project_query_spec.rb b/spec/requests/api/graphql/project_query_spec.rb
index b115030afbc..c6049e098be 100644
--- a/spec/requests/api/graphql/project_query_spec.rb
+++ b/spec/requests/api/graphql/project_query_spec.rb
@@ -76,16 +76,16 @@ RSpec.describe 'getting project information' do
def run_query(number)
q = <<~GQL
- query {
- project(fullPath: "#{project.full_path}") {
- mergeRequests(first: #{number}) {
- nodes {
- assignees { nodes { username } }
- headPipeline { status }
+ query {
+ project(fullPath: "#{project.full_path}") {
+ mergeRequests(first: #{number}) {
+ nodes {
+ assignees { nodes { username } }
+ headPipeline { status }
+ }
}
}
}
- }
GQL
post_graphql(q, current_user: current_user)
diff --git a/spec/requests/api/graphql/user_query_spec.rb b/spec/requests/api/graphql/user_query_spec.rb
index 7ba1788a9ef..2f4dc0a9160 100644
--- a/spec/requests/api/graphql/user_query_spec.rb
+++ b/spec/requests/api/graphql/user_query_spec.rb
@@ -75,7 +75,9 @@ RSpec.describe 'getting user information' do
'name' => presenter.name,
'username' => presenter.username,
'webUrl' => presenter.web_url,
- 'avatarUrl' => presenter.avatar_url
+ 'avatarUrl' => presenter.avatar_url,
+ 'status' => presenter.status,
+ 'email' => presenter.email
))
end
@@ -83,6 +85,7 @@ RSpec.describe 'getting user information' do
let(:user_fields) do
query_graphql_field(:assigned_merge_requests, mr_args, 'nodes { id }')
end
+
let(:mr_args) { nil }
it_behaves_like 'a working graphql query'
@@ -145,6 +148,7 @@ RSpec.describe 'getting user information' do
let(:user_fields) do
query_graphql_field(:authored_merge_requests, mr_args, 'nodes { id }')
end
+
let(:mr_args) { nil }
it_behaves_like 'a working graphql query'