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>2021-11-18 16:16:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-18 16:16:36 +0300
commit311b0269b4eb9839fa63f80c8d7a58f32b8138a0 (patch)
tree07e7870bca8aed6d61fdcc810731c50d2c40af47 /spec/requests/api/graphql
parent27909cef6c4170ed9205afa7426b8d3de47cbb0c (diff)
Add latest changes from gitlab-org/gitlab@14-5-stable-eev14.5.0-rc42
Diffstat (limited to 'spec/requests/api/graphql')
-rw-r--r--spec/requests/api/graphql/ci/pipelines_spec.rb63
-rw-r--r--spec/requests/api/graphql/gitlab_schema_spec.rb23
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb22
-rw-r--r--spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/design_management/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/create_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/issues/move_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb161
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_severity_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb (renamed from spec/requests/api/graphql/mutations/merge_requests/set_wip_spec.rb)8
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/update_reviewer_state_spec.rb65
-rw-r--r--spec/requests/api/graphql/mutations/releases/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/releases/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/releases/update_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb26
-rw-r--r--spec/requests/api/graphql/namespace_query_spec.rb86
-rw-r--r--spec/requests/api/graphql/packages/helm_spec.rb59
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb4
-rw-r--r--spec/requests/api/graphql/project/merge_request_spec.rb16
-rw-r--r--spec/requests/api/graphql/project/release_spec.rb186
-rw-r--r--spec/requests/api/graphql/project/releases_spec.rb15
23 files changed, 718 insertions, 40 deletions
diff --git a/spec/requests/api/graphql/ci/pipelines_spec.rb b/spec/requests/api/graphql/ci/pipelines_spec.rb
index 6587061094d..1f47f678898 100644
--- a/spec/requests/api/graphql/ci/pipelines_spec.rb
+++ b/spec/requests/api/graphql/ci/pipelines_spec.rb
@@ -186,6 +186,69 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
end
end
+ describe '.job_artifacts' do
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ let_it_be(:pipeline_job_1) { create(:ci_build, pipeline: pipeline, name: 'Job 1') }
+ let_it_be(:pipeline_job_artifact_1) { create(:ci_job_artifact, job: pipeline_job_1) }
+ let_it_be(:pipeline_job_2) { create(:ci_build, pipeline: pipeline, name: 'Job 2') }
+ let_it_be(:pipeline_job_artifact_2) { create(:ci_job_artifact, job: pipeline_job_2) }
+
+ let(:path) { %i[project pipelines nodes jobArtifacts] }
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipelines {
+ nodes {
+ jobArtifacts {
+ name
+ downloadPath
+ fileType
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ before do
+ post_graphql(query, current_user: user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns the job_artifacts of a pipeline' do
+ job_artifacts_graphql_data = graphql_data_at(*path).flatten
+
+ expect(
+ job_artifacts_graphql_data.map { |pip| pip['name'] }
+ ).to contain_exactly(pipeline_job_artifact_1.filename, pipeline_job_artifact_2.filename)
+ end
+
+ it 'avoids N+1 queries' do
+ first_user = create(:user)
+ second_user = create(:user)
+
+ control_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: first_user)
+ end
+
+ pipeline_2 = create(:ci_pipeline, project: project)
+ pipeline_2_job_1 = create(:ci_build, pipeline: pipeline_2, name: 'Pipeline 2 Job 1')
+ create(:ci_job_artifact, job: pipeline_2_job_1)
+ pipeline_2_job_2 = create(:ci_build, pipeline: pipeline_2, name: 'Pipeline 2 Job 2')
+ create(:ci_job_artifact, job: pipeline_2_job_2)
+
+ expect do
+ post_graphql(query, current_user: second_user)
+ end.not_to exceed_query_limit(control_count)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
describe '.jobs(securityReportTypes)' do
let_it_be(:query) do
%(
diff --git a/spec/requests/api/graphql/gitlab_schema_spec.rb b/spec/requests/api/graphql/gitlab_schema_spec.rb
index b41d851439b..8bbeae97f57 100644
--- a/spec/requests/api/graphql/gitlab_schema_spec.rb
+++ b/spec/requests/api/graphql/gitlab_schema_spec.rb
@@ -190,19 +190,18 @@ RSpec.describe 'GitlabSchema configurations' do
let(:query) { File.read(Rails.root.join('spec/fixtures/api/graphql/introspection.graphql')) }
it 'logs the query complexity and depth' do
- analyzer_memo = {
- query_string: query,
- variables: {}.to_s,
- complexity: 181,
- depth: 13,
- duration_s: 7,
- operation_name: 'IntrospectionQuery',
- used_fields: an_instance_of(Array),
- used_deprecated_fields: an_instance_of(Array)
- }
-
expect_any_instance_of(Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer).to receive(:duration).and_return(7)
- expect(Gitlab::GraphqlLogger).to receive(:info).with(analyzer_memo)
+
+ expect(Gitlab::GraphqlLogger).to receive(:info).with(
+ hash_including(
+ trace_type: 'execute_query',
+ "query_analysis.duration_s" => 7,
+ "query_analysis.complexity" => 181,
+ "query_analysis.depth" => 13,
+ "query_analysis.used_deprecated_fields" => an_instance_of(Array),
+ "query_analysis.used_fields" => an_instance_of(Array)
+ )
+ )
post_graphql(query, current_user: nil)
end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
index 30e704adb92..3527c8183f6 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
@@ -116,4 +116,26 @@ RSpec.describe 'getting dependency proxy manifests in a group' do
expect(dependency_proxy_image_count_response).to eq(manifests.size)
end
+
+ describe 'sorting and pagination' do
+ let(:data_path) { ['group', :dependencyProxyManifests] }
+ let(:current_user) { owner }
+
+ context 'with default sorting' do
+ let_it_be(:descending_manifests) { manifests.reverse.map { |manifest| global_id_of(manifest)} }
+
+ it_behaves_like 'sorted paginated query' do
+ let(:sort_param) { '' }
+ let(:first_param) { 2 }
+ let(:all_records) { descending_manifests }
+ end
+ end
+
+ def pagination_query(params)
+ # remove sort since the type does not accept sorting, but be future proof
+ graphql_query_for('group', { 'fullPath' => group.full_path },
+ query_nodes(:dependencyProxyManifests, :id, include_pagination_info: true, args: params.merge(sort: nil))
+ )
+ end
+ end
end
diff --git a/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb b/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb
index 0fd8fdc3f59..322706be119 100644
--- a/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'RunnersRegistrationTokenReset' do
subject
expect(graphql_errors).not_to be_empty
- expect(graphql_errors).to include(a_hash_including('message' => "The resource that you are attempting to access does not exist or you don't have permission to perform this action"))
+ expect(graphql_errors).to include(a_hash_including('message' => Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR))
expect(mutation_response).to be_nil
end
end
diff --git a/spec/requests/api/graphql/mutations/design_management/delete_spec.rb b/spec/requests/api/graphql/mutations/design_management/delete_spec.rb
index e329416faee..1dffb86b344 100644
--- a/spec/requests/api/graphql/mutations/design_management/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/design_management/delete_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe "deleting designs" do
context 'the designs list contains filenames we cannot find' do
it_behaves_like 'a failed request' do
- let(:designs) { %w/foo bar baz/.map { |fn| OpenStruct.new(filename: fn) } }
+ let(:designs) { %w/foo bar baz/.map { |fn| instance_double('file', filename: fn) } }
let(:the_error) { a_string_matching %r/filenames were not found/ }
end
end
diff --git a/spec/requests/api/graphql/mutations/issues/create_spec.rb b/spec/requests/api/graphql/mutations/issues/create_spec.rb
index 886f3140086..6baed352b37 100644
--- a/spec/requests/api/graphql/mutations/issues/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/create_spec.rb
@@ -48,5 +48,9 @@ RSpec.describe 'Create an issue' do
expect(mutation_response['issue']).to include('discussionLocked' => true)
expect(Issue.last.work_item_type.base_type).to eq('issue')
end
+
+ it_behaves_like 'has spam protection' do
+ let(:mutation_class) { ::Mutations::Issues::Create }
+ end
end
end
diff --git a/spec/requests/api/graphql/mutations/issues/move_spec.rb b/spec/requests/api/graphql/mutations/issues/move_spec.rb
index 5bbaff61edd..20ed16879f6 100644
--- a/spec/requests/api/graphql/mutations/issues/move_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/move_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe 'Moving an issue' do
context 'when the user is not allowed to read source project' do
it 'returns an error' do
- error = "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
post_graphql_mutation(mutation, current_user: user)
expect(response).to have_gitlab_http_status(:success)
diff --git a/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb b/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb
index 3f804a46992..12ab504da14 100644
--- a/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe 'Setting an issue as confidential' do
end
it 'returns an error if the user is not allowed to update the issue' do
- error = "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
post_graphql_mutation(mutation, current_user: create(:user))
expect(graphql_errors).to include(a_hash_including('message' => error))
diff --git a/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
new file mode 100644
index 00000000000..3da702c55d7
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
@@ -0,0 +1,161 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Setting issues crm contacts' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:contacts) { create_list(:contact, 4, group: group) }
+
+ let(:issue) { create(:issue, project: project) }
+ let(:operation_mode) { Types::MutationOperationModeEnum.default_mode }
+ let(:crm_contact_ids) { [global_id_of(contacts[1]), global_id_of(contacts[2])] }
+ let(:does_not_exist_or_no_permission) { "The resource that you are attempting to access does not exist or you don't have permission to perform this action" }
+
+ let(:mutation) do
+ variables = {
+ project_path: issue.project.full_path,
+ iid: issue.iid.to_s,
+ operation_mode: operation_mode,
+ crm_contact_ids: crm_contact_ids
+ }
+
+ graphql_mutation(:issue_set_crm_contacts, variables,
+ <<-QL.strip_heredoc
+ clientMutationId
+ errors
+ issue {
+ customerRelationsContacts {
+ nodes {
+ id
+ }
+ }
+ }
+ QL
+ )
+ end
+
+ def mutation_response
+ graphql_mutation_response(:issue_set_crm_contacts)
+ end
+
+ before do
+ create(:issue_customer_relations_contact, issue: issue, contact: contacts[0])
+ create(:issue_customer_relations_contact, issue: issue, contact: contacts[1])
+ end
+
+ context 'when the user has no permission' do
+ it 'returns expected error' do
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_errors).to include(a_hash_including('message' => error))
+ end
+ end
+
+ context 'when the user has permission' do
+ before do
+ group.add_reporter(user)
+ end
+
+ context 'when the feature is disabled' do
+ before do
+ stub_feature_flags(customer_relations: false)
+ end
+
+ it 'raises expected error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_errors).to include(a_hash_including('message' => 'Feature disabled'))
+ end
+ end
+
+ context 'replace' do
+ it 'updates the issue with correct contacts' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
+ .to match_array([global_id_of(contacts[1]), global_id_of(contacts[2])])
+ end
+ end
+
+ context 'append' do
+ let(:crm_contact_ids) { [global_id_of(contacts[3])] }
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:append] }
+
+ it 'updates the issue with correct contacts' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
+ .to match_array([global_id_of(contacts[0]), global_id_of(contacts[1]), global_id_of(contacts[3])])
+ end
+ end
+
+ context 'remove' do
+ let(:crm_contact_ids) { [global_id_of(contacts[0])] }
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:remove] }
+
+ it 'updates the issue with correct contacts' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :issue, :customer_relations_contacts, :nodes, :id))
+ .to match_array([global_id_of(contacts[1])])
+ end
+ end
+
+ context 'when the contact does not exist' do
+ let(:crm_contact_ids) { ["gid://gitlab/CustomerRelations::Contact/#{non_existing_record_id}"] }
+
+ it 'returns expected error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :errors))
+ .to match_array(["Issue customer relations contacts #{non_existing_record_id}: #{does_not_exist_or_no_permission}"])
+ end
+ end
+
+ context 'when the contact belongs to a different group' do
+ let(:group2) { create(:group) }
+ let(:contact) { create(:contact, group: group2) }
+ let(:crm_contact_ids) { [global_id_of(contact)] }
+
+ before do
+ group2.add_reporter(user)
+ end
+
+ it 'returns expected error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :errors))
+ .to match_array(["Issue customer relations contacts #{contact.id}: #{does_not_exist_or_no_permission}"])
+ end
+ end
+
+ context 'when attempting to add more than 6' do
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:append] }
+ let(:gid) { global_id_of(contacts[0]) }
+ let(:crm_contact_ids) { [gid, gid, gid, gid, gid, gid, gid] }
+
+ it 'returns expected error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :errors))
+ .to match_array(["You can only add up to 6 contacts at one time"])
+ end
+ end
+
+ context 'when trying to remove non-existent contact' do
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:remove] }
+ let(:crm_contact_ids) { ["gid://gitlab/CustomerRelations::Contact/#{non_existing_record_id}"] }
+
+ it 'raises expected error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_data_at(:issue_set_crm_contacts, :errors)).to be_empty
+ end
+ end
+ end
+end
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 72e47a98373..8e223b6fdaf 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
@@ -36,7 +36,7 @@ RSpec.describe 'Setting Due Date of an issue' do
end
it 'returns an error if the user is not allowed to update the issue' do
- error = "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
post_graphql_mutation(mutation, current_user: create(:user))
expect(graphql_errors).to include(a_hash_including('message' => error))
diff --git a/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb b/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb
index 41997f151a2..cd9d695bd2c 100644
--- a/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe 'Setting severity level of an incident' do
context 'when the user is not allowed to update the incident' do
it 'returns an error' do
- error = "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
post_graphql_mutation(mutation, current_user: user)
expect(response).to have_gitlab_http_status(:success)
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_wip_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb
index 2143abd3031..bea2365eaa6 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_wip_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb
@@ -8,14 +8,14 @@ RSpec.describe 'Setting Draft status of a merge request' do
let(:current_user) { create(:user) }
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project }
- let(:input) { { wip: true } }
+ let(:input) { { draft: true } }
let(:mutation) do
variables = {
project_path: project.full_path,
iid: merge_request.iid.to_s
}
- graphql_mutation(:merge_request_set_wip, variables.merge(input),
+ graphql_mutation(:merge_request_set_draft, variables.merge(input),
<<-QL.strip_heredoc
clientMutationId
errors
@@ -28,7 +28,7 @@ RSpec.describe 'Setting Draft status of a merge request' do
end
def mutation_response
- graphql_mutation_response(:merge_request_set_wip)
+ graphql_mutation_response(:merge_request_set_draft)
end
before do
@@ -58,7 +58,7 @@ RSpec.describe 'Setting Draft status of a merge request' do
end
context 'when passing Draft false as input' do
- let(:input) { { wip: false } }
+ let(:input) { { draft: false } }
it 'does not do anything if the merge reqeust was not marked draft' do
post_graphql_mutation(mutation, current_user: current_user)
diff --git a/spec/requests/api/graphql/mutations/merge_requests/update_reviewer_state_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/update_reviewer_state_spec.rb
new file mode 100644
index 00000000000..cf497cb2579
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/merge_requests/update_reviewer_state_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Toggle attention requested for reviewer' do
+ include GraphqlHelpers
+
+ let(:current_user) { create(:user) }
+ let(:merge_request) { create(:merge_request, reviewers: [user]) }
+ let(:project) { merge_request.project }
+ let(:user) { create(:user) }
+ let(:input) { { user_id: global_id_of(user) } }
+
+ let(:mutation) do
+ variables = {
+ project_path: project.full_path,
+ iid: merge_request.iid.to_s
+ }
+ graphql_mutation(:merge_request_toggle_attention_requested, variables.merge(input),
+ <<-QL.strip_heredoc
+ clientMutationId
+ errors
+ QL
+ )
+ end
+
+ def mutation_response
+ graphql_mutation_response(:merge_request_toggle_attention_requested)
+ end
+
+ def mutation_errors
+ mutation_response['errors']
+ end
+
+ before do
+ project.add_developer(current_user)
+ project.add_developer(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
+
+ describe 'reviewer does not exist' do
+ let(:input) { { user_id: global_id_of(create(:user)) } }
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_errors).not_to be_empty
+ end
+ end
+
+ describe 'reviewer exists' do
+ it 'does not return an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_errors).to be_empty
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/releases/create_spec.rb b/spec/requests/api/graphql/mutations/releases/create_spec.rb
index a4918cd560c..86995c10f10 100644
--- a/spec/requests/api/graphql/mutations/releases/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/create_spec.rb
@@ -342,7 +342,7 @@ RSpec.describe 'Creation of a new release' do
end
context "when the current user doesn't have access to create releases" do
- expected_error_message = "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ expected_error_message = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
context 'when the current user is a Reporter' do
let(:current_user) { reporter }
diff --git a/spec/requests/api/graphql/mutations/releases/delete_spec.rb b/spec/requests/api/graphql/mutations/releases/delete_spec.rb
index 40063156609..eb4f0b594ea 100644
--- a/spec/requests/api/graphql/mutations/releases/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/delete_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe 'Deleting a release' do
expect(mutation_response).to be_nil
expect(graphql_errors.count).to eq(1)
- expect(graphql_errors.first['message']).to eq("The resource that you are attempting to access does not exist or you don't have permission to perform this action")
+ expect(graphql_errors.first['message']).to eq(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
end
end
diff --git a/spec/requests/api/graphql/mutations/releases/update_spec.rb b/spec/requests/api/graphql/mutations/releases/update_spec.rb
index c9a6c3abd57..0fa3d7de299 100644
--- a/spec/requests/api/graphql/mutations/releases/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/update_spec.rb
@@ -218,13 +218,13 @@ RSpec.describe 'Updating an existing release' do
context 'when the project does not exist' do
let(:mutation_arguments) { super().merge(projectPath: 'not/a/real/path') }
- it_behaves_like 'top-level error with message', "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ it_behaves_like 'top-level error with message', Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
end
end
end
context "when the current user doesn't have access to update releases" do
- expected_error_message = "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ expected_error_message = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
context 'when the current user is a Reporter' do
let(:current_user) { reporter }
diff --git a/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb b/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb
new file mode 100644
index 00000000000..929609d4160
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'ConfigureSastIac' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :test_repo) }
+
+ let(:variables) { { project_path: project.full_path } }
+ let(:mutation) { graphql_mutation(:configure_sast_iac, variables) }
+ let(:mutation_response) { graphql_mutation_response(:configureSastIac) }
+
+ context 'when authorized' do
+ let_it_be(:user) { project.owner }
+
+ it 'creates a branch with sast iac configured' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['errors']).to be_empty
+ expect(mutation_response['branch']).not_to be_empty
+ expect(mutation_response['successPath']).not_to be_empty
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/namespace_query_spec.rb b/spec/requests/api/graphql/namespace_query_spec.rb
new file mode 100644
index 00000000000..f7ee2bcb55d
--- /dev/null
+++ b/spec/requests/api/graphql/namespace_query_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Query' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:other_user) { create(:user) }
+
+ let_it_be(:group_namespace) { create(:group) }
+ let_it_be(:user_namespace) { create(:user_namespace, owner: user) }
+ let_it_be(:project_namespace) { create(:project_namespace, parent: group_namespace) }
+
+ describe '.namespace' do
+ subject { post_graphql(query, current_user: current_user) }
+
+ let(:current_user) { user }
+
+ let(:query) { graphql_query_for(:namespace, { 'fullPath' => target_namespace.full_path }, all_graphql_fields_for('Namespace')) }
+ let(:query_result) { graphql_data['namespace'] }
+
+ shared_examples 'retrieving a namespace' do
+ context 'authorised query' do
+ before do
+ subject
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'fetches the expected data' do
+ expect(query_result).to include(
+ 'fullPath' => target_namespace.full_path,
+ 'name' => target_namespace.name
+ )
+ end
+ end
+
+ context 'unauthorised query' do
+ before do
+ subject
+ end
+
+ context 'anonymous user' do
+ let(:current_user) { nil }
+
+ it 'does not retrieve the record' do
+ expect(query_result).to be_nil
+ end
+ end
+
+ context 'the current user does not have permission' do
+ let(:current_user) { other_user }
+
+ it 'does not retrieve the record' do
+ expect(query_result).to be_nil
+ end
+ end
+ end
+ end
+
+ it_behaves_like 'retrieving a namespace' do
+ let(:target_namespace) { group_namespace }
+
+ before do
+ group_namespace.add_developer(user)
+ end
+ end
+
+ it_behaves_like 'retrieving a namespace' do
+ let(:target_namespace) { user_namespace }
+ end
+
+ context 'does not retrieve project namespace' do
+ let(:target_namespace) { project_namespace }
+
+ before do
+ subject
+ end
+
+ it 'does not retrieve the record' do
+ expect(query_result).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/packages/helm_spec.rb b/spec/requests/api/graphql/packages/helm_spec.rb
new file mode 100644
index 00000000000..397096f70db
--- /dev/null
+++ b/spec/requests/api/graphql/packages/helm_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'helm package details' do
+ include GraphqlHelpers
+ include_context 'package details setup'
+
+ let_it_be(:package) { create(:helm_package, project: project) }
+
+ let(:package_files_metadata) {query_graphql_fragment('HelmFileMetadata')}
+
+ let(:query) do
+ graphql_query_for(:package, { id: package_global_id }, <<~FIELDS)
+ #{all_graphql_fields_for('PackageDetailsType', max_depth: depth, excluded: excluded)}
+ packageFiles {
+ nodes {
+ #{package_files}
+ fileMetadata {
+ #{package_files_metadata}
+ }
+ }
+ }
+ FIELDS
+ end
+
+ subject { post_graphql(query, current_user: user) }
+
+ before do
+ subject
+ end
+
+ it_behaves_like 'a package detail'
+ it_behaves_like 'a package with files'
+
+ it 'has the correct file metadata' do
+ expect(first_file_response_metadata).to include(
+ 'channel' => first_file.helm_file_metadatum.channel
+ )
+ expect(first_file_response_metadata['metadata']).to include(
+ 'name' => first_file.helm_file_metadatum.metadata['name'],
+ 'home' => first_file.helm_file_metadatum.metadata['home'],
+ 'sources' => first_file.helm_file_metadatum.metadata['sources'],
+ 'version' => first_file.helm_file_metadatum.metadata['version'],
+ 'description' => first_file.helm_file_metadatum.metadata['description'],
+ 'keywords' => first_file.helm_file_metadatum.metadata['keywords'],
+ 'maintainers' => first_file.helm_file_metadatum.metadata['maintainers'],
+ 'icon' => first_file.helm_file_metadatum.metadata['icon'],
+ 'apiVersion' => first_file.helm_file_metadatum.metadata['apiVersion'],
+ 'condition' => first_file.helm_file_metadatum.metadata['condition'],
+ 'tags' => first_file.helm_file_metadatum.metadata['tags'],
+ 'appVersion' => first_file.helm_file_metadatum.metadata['appVersion'],
+ 'deprecated' => first_file.helm_file_metadatum.metadata['deprecated'],
+ 'annotations' => first_file.helm_file_metadatum.metadata['annotations'],
+ 'kubeVersion' => first_file.helm_file_metadatum.metadata['kubeVersion'],
+ 'dependencies' => first_file.helm_file_metadatum.metadata['dependencies'],
+ 'type' => first_file.helm_file_metadatum.metadata['type']
+ )
+ end
+end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index 1c6d6ce4707..b3e91afb5b3 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -429,11 +429,11 @@ RSpec.describe 'getting an issue list for a project' do
end
it 'avoids N+1 queries' do
- create(:contact, group_id: group.id, issues: [issue_a])
+ create(:issue_customer_relations_contact, :for_issue, issue: issue_a)
control = ActiveRecord::QueryRecorder.new(skip_cached: false) { clean_state_query }
- create(:contact, group_id: group.id, issues: [issue_a])
+ create(:issue_customer_relations_contact, :for_issue, issue: issue_a)
expect { clean_state_query }.not_to exceed_all_query_limit(control)
end
diff --git a/spec/requests/api/graphql/project/merge_request_spec.rb b/spec/requests/api/graphql/project/merge_request_spec.rb
index 438ea9bb4c1..353bf0356f6 100644
--- a/spec/requests/api/graphql/project/merge_request_spec.rb
+++ b/spec/requests/api/graphql/project/merge_request_spec.rb
@@ -347,7 +347,7 @@ RSpec.describe 'getting merge request information nested in a project' do
expect(interaction_data).to contain_exactly a_hash_including(
'canMerge' => false,
'canUpdate' => can_update,
- 'reviewState' => unreviewed,
+ 'reviewState' => attention_requested,
'reviewed' => false,
'approved' => false
)
@@ -380,8 +380,8 @@ RSpec.describe 'getting merge request information nested in a project' do
describe 'scalability' do
let_it_be(:other_users) { create_list(:user, 3) }
- let(:unreviewed) do
- { 'reviewState' => 'UNREVIEWED' }
+ let(:attention_requested) do
+ { 'reviewState' => 'ATTENTION_REQUESTED' }
end
let(:reviewed) do
@@ -413,9 +413,9 @@ RSpec.describe 'getting merge request information nested in a project' do
expect { post_graphql(query) }.not_to exceed_query_limit(baseline)
expect(interaction_data).to contain_exactly(
- include(unreviewed),
- include(unreviewed),
- include(unreviewed),
+ include(attention_requested),
+ include(attention_requested),
+ include(attention_requested),
include(reviewed)
)
end
@@ -444,7 +444,7 @@ RSpec.describe 'getting merge request information nested in a project' do
it_behaves_like 'when requesting information about MR interactions' do
let(:field) { :reviewers }
- let(:unreviewed) { 'UNREVIEWED' }
+ let(:attention_requested) { 'ATTENTION_REQUESTED' }
let(:can_update) { false }
def assign_user(user)
@@ -454,7 +454,7 @@ RSpec.describe 'getting merge request information nested in a project' do
it_behaves_like 'when requesting information about MR interactions' do
let(:field) { :assignees }
- let(:unreviewed) { nil }
+ let(:attention_requested) { nil }
let(:can_update) { true } # assignees can update MRs
def assign_user(user)
diff --git a/spec/requests/api/graphql/project/release_spec.rb b/spec/requests/api/graphql/project/release_spec.rb
index 7f24d051457..77abac4ef04 100644
--- a/spec/requests/api/graphql/project/release_spec.rb
+++ b/spec/requests/api/graphql/project/release_spec.rb
@@ -228,6 +228,189 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
end
end
+ shared_examples 'restricted access to release fields' do
+ describe 'scalar fields' do
+ let(:path) { path_prefix }
+
+ let(:release_fields) do
+ %{
+ tagName
+ tagPath
+ description
+ descriptionHtml
+ name
+ createdAt
+ releasedAt
+ upcomingRelease
+ }
+ end
+
+ before do
+ post_query
+ end
+
+ it 'finds all release data' do
+ expect(data).to eq({
+ 'tagName' => release.tag,
+ 'tagPath' => nil,
+ 'description' => release.description,
+ 'descriptionHtml' => release.description_html,
+ 'name' => release.name,
+ 'createdAt' => release.created_at.iso8601,
+ 'releasedAt' => release.released_at.iso8601,
+ 'upcomingRelease' => false
+ })
+ end
+ end
+
+ describe 'milestones' do
+ let(:path) { path_prefix + %w[milestones nodes] }
+
+ let(:release_fields) do
+ query_graphql_field(:milestones, nil, 'nodes { id title }')
+ end
+
+ it 'finds milestones associated to a release' do
+ post_query
+
+ expected = release.milestones.order_by_dates_and_title.map do |milestone|
+ { 'id' => global_id_of(milestone), 'title' => milestone.title }
+ end
+
+ expect(data).to eq(expected)
+ end
+ end
+
+ describe 'author' do
+ let(:path) { path_prefix + %w[author] }
+
+ let(:release_fields) do
+ query_graphql_field(:author, nil, 'id username')
+ end
+
+ it 'finds the author of the release' do
+ post_query
+
+ expect(data).to eq(
+ 'id' => global_id_of(release.author),
+ 'username' => release.author.username
+ )
+ end
+ end
+
+ describe 'commit' do
+ let(:path) { path_prefix + %w[commit] }
+
+ let(:release_fields) do
+ query_graphql_field(:commit, nil, 'sha')
+ end
+
+ it 'restricts commit associated with the release' do
+ post_query
+
+ expect(data).to eq(nil)
+ end
+ end
+
+ describe 'assets' do
+ describe 'count' do
+ let(:path) { path_prefix + %w[assets] }
+
+ let(:release_fields) do
+ query_graphql_field(:assets, nil, 'count')
+ end
+
+ it 'returns non source release links count' do
+ post_query
+
+ expect(data).to eq('count' => release.assets_count(except: [:sources]))
+ end
+ end
+
+ describe 'links' do
+ let(:path) { path_prefix + %w[assets links nodes] }
+
+ let(:release_fields) do
+ query_graphql_field(:assets, nil,
+ query_graphql_field(:links, nil, 'nodes { id name url external, directAssetUrl }'))
+ end
+
+ it 'finds all non source external release links' do
+ post_query
+
+ expected = release.links.map do |link|
+ {
+ 'id' => global_id_of(link),
+ 'name' => link.name,
+ 'url' => link.url,
+ 'external' => true,
+ 'directAssetUrl' => link.filepath ? Gitlab::Routing.url_helpers.project_release_url(project, release) << "/downloads#{link.filepath}" : link.url
+ }
+ end
+
+ expect(data).to match_array(expected)
+ end
+ end
+
+ describe 'sources' do
+ let(:path) { path_prefix + %w[assets sources nodes] }
+
+ let(:release_fields) do
+ query_graphql_field(:assets, nil,
+ query_graphql_field(:sources, nil, 'nodes { format url }'))
+ end
+
+ it 'restricts release sources' do
+ post_query
+
+ expect(data).to match_array([])
+ end
+ end
+ end
+
+ describe 'links' do
+ let(:path) { path_prefix + %w[links] }
+
+ let(:release_fields) do
+ query_graphql_field(:links, nil, %{
+ selfUrl
+ openedMergeRequestsUrl
+ mergedMergeRequestsUrl
+ closedMergeRequestsUrl
+ openedIssuesUrl
+ closedIssuesUrl
+ })
+ end
+
+ it 'finds only selfUrl' do
+ post_query
+
+ expect(data).to eq(
+ 'selfUrl' => project_release_url(project, release),
+ 'openedMergeRequestsUrl' => nil,
+ 'mergedMergeRequestsUrl' => nil,
+ 'closedMergeRequestsUrl' => nil,
+ 'openedIssuesUrl' => nil,
+ 'closedIssuesUrl' => nil
+ )
+ end
+ end
+
+ describe 'evidences' do
+ let(:path) { path_prefix + %w[evidences] }
+
+ let(:release_fields) do
+ query_graphql_field(:evidences, nil, 'nodes { id sha filepath collectedAt }')
+ end
+
+ it 'restricts all evidence fields' do
+ post_query
+
+ expect(data).to eq('nodes' => [])
+ end
+ end
+ end
+
shared_examples 'no access to the release field' do
describe 'repository-related fields' do
let(:path) { path_prefix }
@@ -302,7 +485,8 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
context 'when the user has Guest permissions' do
let(:current_user) { guest }
- it_behaves_like 'no access to the release field'
+ it_behaves_like 'restricted access to release fields'
+ it_behaves_like 'no access to editUrl'
end
context 'when the user has Reporter permissions' do
diff --git a/spec/requests/api/graphql/project/releases_spec.rb b/spec/requests/api/graphql/project/releases_spec.rb
index 2816ce90a6b..c28a6fa7666 100644
--- a/spec/requests/api/graphql/project/releases_spec.rb
+++ b/spec/requests/api/graphql/project/releases_spec.rb
@@ -129,10 +129,12 @@ RSpec.describe 'Query.project(fullPath).releases()' do
end
it 'does not return data for fields that expose repository information' do
+ tag_name = release.tag
+ release_name = release.name
expect(data).to eq(
- 'tagName' => nil,
+ 'tagName' => tag_name,
'tagPath' => nil,
- 'name' => "Release-#{release.id}",
+ 'name' => release_name,
'commit' => nil,
'assets' => {
'count' => release.assets_count(except: [:sources]),
@@ -143,7 +145,14 @@ RSpec.describe 'Query.project(fullPath).releases()' do
'evidences' => {
'nodes' => []
},
- 'links' => nil
+ 'links' => {
+ 'closedIssuesUrl' => nil,
+ 'closedMergeRequestsUrl' => nil,
+ 'mergedMergeRequestsUrl' => nil,
+ 'openedIssuesUrl' => nil,
+ 'openedMergeRequestsUrl' => nil,
+ 'selfUrl' => project_release_url(project, release)
+ }
)
end
end