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-09-20 16:18:24 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 16:18:24 +0300
commit0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch)
tree4dcc884cf6d81db44adae4aa99f8ec1233a41f55 /spec/requests/api/graphql
parent744144d28e3e7fddc117924fef88de5d9674fe4c (diff)
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
Diffstat (limited to 'spec/requests/api/graphql')
-rw-r--r--spec/requests/api/graphql/boards/board_list_issues_query_spec.rb14
-rw-r--r--spec/requests/api/graphql/ci/stages_spec.rb46
-rw-r--r--spec/requests/api/graphql/current_user/groups_query_spec.rb112
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb127
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb78
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb77
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb119
-rw-r--r--spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb73
-rw-r--r--spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb70
-rw-r--r--spec/requests/api/graphql/mutations/issues/create_spec.rb5
-rw-r--r--spec/requests/api/graphql/mutations/issues/update_spec.rb13
-rw-r--r--spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb53
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb28
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb12
15 files changed, 785 insertions, 44 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
index 3628171fcc1..008241b8055 100644
--- a/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
@@ -48,13 +48,18 @@ RSpec.describe 'get board lists' do
issues_data.map { |i| i['title'] }
end
+ def issue_relative_positions
+ issues_data.map { |i| i['relativePosition'] }
+ 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, label2], relative_position: 9) }
let!(:issue2) { create(:issue, project: issue_project, labels: [label, label2], 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) }
+ let!(:issue3) { create(:issue, project: issue_project, labels: [label, label2], relative_position: nil) }
+ let!(:issue4) { create(:issue, project: issue_project, labels: [label], relative_position: 9) }
+ let!(:issue5) { 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
@@ -69,10 +74,11 @@ RSpec.describe 'get board lists' do
board_parent.add_reporter(user)
end
- it 'can access the issues' do
+ it 'can access the issues', :aggregate_failures do
post_graphql(query("id: \"#{global_id_of(label_list)}\""), current_user: user)
- expect(issue_titles).to eq([issue2.title, issue1.title])
+ expect(issue_titles).to eq([issue2.title, issue1.title, issue3.title])
+ expect(issue_relative_positions).not_to include(nil)
end
end
end
diff --git a/spec/requests/api/graphql/ci/stages_spec.rb b/spec/requests/api/graphql/ci/stages_spec.rb
index cd48a24b9c8..50d2cf75097 100644
--- a/spec/requests/api/graphql/ci/stages_spec.rb
+++ b/spec/requests/api/graphql/ci/stages_spec.rb
@@ -4,11 +4,13 @@ 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'] }
+ subject(:post_query) { post_graphql(query, current_user: user) }
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user) }
+
+ let(:stage_nodes) { graphql_data_at(:project, :pipeline, :stages, :nodes) }
let(:params) { {} }
let(:fields) do
@@ -33,14 +35,42 @@ RSpec.describe 'Query.project.pipeline.stages' do
)
end
- before do
+ before_all do
create(:ci_stage_entity, pipeline: pipeline, name: 'deploy')
- post_graphql(query, current_user: user)
+ create_list(:ci_build, 2, pipeline: pipeline, stage: 'deploy')
end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_query
+ end
+ end
it 'returns the stage of a pipeline' do
- expect(stage_graphql_data['nodes'].first['name']).to eq('deploy')
+ post_query
+
+ expect(stage_nodes.first['name']).to eq('deploy')
+ end
+
+ describe 'job pagination' do
+ let(:job_nodes) { graphql_dig_at(stage_nodes, :jobs, :nodes) }
+
+ it 'returns up to default limit jobs per stage' do
+ post_query
+
+ expect(job_nodes.count).to eq(2)
+ end
+
+ context 'when the limit is manually set' do
+ before do
+ stub_application_setting(jobs_per_stage_page_size: 1)
+ end
+
+ it 'returns up to custom limit jobs per stage' do
+ post_query
+
+ expect(job_nodes.count).to eq(1)
+ end
+ end
end
end
diff --git a/spec/requests/api/graphql/current_user/groups_query_spec.rb b/spec/requests/api/graphql/current_user/groups_query_spec.rb
new file mode 100644
index 00000000000..39f323b21a3
--- /dev/null
+++ b/spec/requests/api/graphql/current_user/groups_query_spec.rb
@@ -0,0 +1,112 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Query current user groups' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:guest_group) { create(:group, name: 'public guest', path: 'public-guest') }
+ let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer') }
+ let_it_be(:public_developer_group) { create(:group, :private, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer') }
+ let_it_be(:public_maintainer_group) { create(:group, :private, name: 'a public maintainer', path: 'a-public-maintainer') }
+
+ let(:group_arguments) { {} }
+ let(:current_user) { user }
+
+ let(:fields) do
+ <<~GRAPHQL
+ nodes { id path fullPath name }
+ GRAPHQL
+ end
+
+ let(:query) do
+ graphql_query_for('currentUser', {}, query_graphql_field('groups', group_arguments, fields))
+ end
+
+ before_all do
+ guest_group.add_guest(user)
+ private_maintainer_group.add_maintainer(user)
+ public_developer_group.add_developer(user)
+ public_maintainer_group.add_maintainer(user)
+ end
+
+ subject { graphql_data.dig('currentUser', 'groups', 'nodes') }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'avoids N+1 queries', :request_store do
+ control = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
+
+ new_group = create(:group, :private)
+ new_group.add_maintainer(current_user)
+
+ expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(control)
+ end
+
+ it 'returns all groups where the user is a direct member' do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group,
+ guest_group
+ )
+ )
+ end
+
+ context 'when permission_scope is CREATE_PROJECTS' do
+ let(:group_arguments) { { permission_scope: :CREATE_PROJECTS } }
+
+ specify do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group,
+ public_developer_group
+ )
+ )
+ end
+
+ context 'when search is provided' do
+ let(:group_arguments) { { permission_scope: :CREATE_PROJECTS, search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group
+ )
+ )
+ end
+ end
+ end
+
+ context 'when search is provided' do
+ let(:group_arguments) { { search: 'maintainer' } }
+
+ specify do
+ is_expected.to match(
+ expected_group_hash(
+ public_maintainer_group,
+ private_maintainer_group
+ )
+ )
+ end
+ end
+
+ def expected_group_hash(*groups)
+ groups.map do |group|
+ {
+ 'id' => group.to_global_id.to_s,
+ 'name' => group.name,
+ 'path' => group.path,
+ 'fullPath' => group.full_path
+ }
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
new file mode 100644
index 00000000000..cdb21512894
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy blobs in a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:owner) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be(:blob) { create(:dependency_proxy_blob, group: group) }
+ let_it_be(:blob2) { create(:dependency_proxy_blob, file_name: 'blob2.json', group: group) }
+ let_it_be(:blobs) { [blob, blob2].flatten }
+
+ let(:dependency_proxy_blob_fields) do
+ <<~GQL
+ edges {
+ node {
+ #{all_graphql_fields_for('dependency_proxy_blobs'.classify, max_depth: 1)}
+ }
+ }
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_blobs', {}, dependency_proxy_blob_fields)}
+ dependencyProxyBlobCount
+ dependencyProxyTotalSize
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:user) { owner }
+ let(:variables) { {} }
+ let(:dependency_proxy_blobs_response) { graphql_data.dig('group', 'dependencyProxyBlobs', 'edges') }
+ let(:dependency_proxy_blob_count_response) { graphql_data.dig('group', 'dependencyProxyBlobCount') }
+ let(:dependency_proxy_total_size_response) { graphql_data.dig('group', 'dependencyProxyTotalSize') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.add_owner(owner)
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ let_it_be(:user) { create(:user) }
+
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_blobs_response.size).to eq(blobs.size)
+ else
+ expect(dependency_proxy_blobs_response).to be_blank
+ end
+ end
+ end
+ end
+
+ context 'limiting the number of blobs' do
+ let(:limit) { 1 }
+ let(:variables) do
+ { path: group.full_path, n: limit }
+ end
+
+ let(:query) do
+ <<~GQL
+ query($path: ID!, $n: Int) {
+ group(fullPath: $path) {
+ dependencyProxyBlobs(first: $n) { #{dependency_proxy_blob_fields} }
+ }
+ }
+ GQL
+ end
+
+ it 'only returns N blobs' do
+ subject
+
+ expect(dependency_proxy_blobs_response.size).to eq(limit)
+ end
+ end
+
+ it 'returns the total count of blobs' do
+ subject
+
+ expect(dependency_proxy_blob_count_response).to eq(blobs.size)
+ end
+
+ it 'returns the total size' do
+ subject
+ expected_size = blobs.inject(0) { |sum, blob| sum + blob.size }
+ expect(dependency_proxy_total_size_response).to eq(ActiveSupport::NumberHelper.number_to_human_size(expected_size))
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
new file mode 100644
index 00000000000..c5c6d85d1e6
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy settings for a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+
+ let(:dependency_proxy_group_setting_fields) do
+ <<~GQL
+ #{all_graphql_fields_for('dependency_proxy_setting'.classify, max_depth: 1)}
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_setting', {}, dependency_proxy_group_setting_fields)}
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:variables) { {} }
+ let(:dependency_proxy_group_setting_response) { graphql_data.dig('group', 'dependencyProxySetting') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.create_dependency_proxy_setting!(enabled: true)
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_group_setting_response).to eq('enabled' => true)
+ else
+ expect(dependency_proxy_group_setting_response).to be_blank
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
new file mode 100644
index 00000000000..c8797d84906
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy image ttl policy for a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+
+ let(:dependency_proxy_image_ttl_policy_fields) do
+ <<~GQL
+ #{all_graphql_fields_for('dependency_proxy_image_ttl_group_policy'.classify, max_depth: 1)}
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_image_ttl_policy', {}, dependency_proxy_image_ttl_policy_fields)}
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:variables) { {} }
+ let(:dependency_proxy_image_ttl_policy_response) { graphql_data.dig('group', 'dependencyProxyImageTtlPolicy') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_image_ttl_policy_response).to eq("createdAt" => nil, "enabled" => false, "ttl" => 90, "updatedAt" => nil)
+ else
+ expect(dependency_proxy_image_ttl_policy_response).to be_blank
+ end
+ end
+ end
+ end
+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
new file mode 100644
index 00000000000..30e704adb92
--- /dev/null
+++ b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
@@ -0,0 +1,119 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'getting dependency proxy manifests in a group' do
+ using RSpec::Parameterized::TableSyntax
+ include GraphqlHelpers
+
+ let_it_be(:owner) { create(:user) }
+ let_it_be_with_reload(:group) { create(:group) }
+ let_it_be(:manifest) { create(:dependency_proxy_manifest, group: group) }
+ let_it_be(:manifest2) { create(:dependency_proxy_manifest, file_name: 'image2.json', group: group) }
+ let_it_be(:manifests) { [manifest, manifest2].flatten }
+
+ let(:dependency_proxy_manifest_fields) do
+ <<~GQL
+ edges {
+ node {
+ #{all_graphql_fields_for('dependency_proxy_manifests'.classify, max_depth: 1)}
+ }
+ }
+ GQL
+ end
+
+ let(:fields) do
+ <<~GQL
+ #{query_graphql_field('dependency_proxy_manifests', {}, dependency_proxy_manifest_fields)}
+ dependencyProxyImageCount
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'group',
+ { 'fullPath' => group.full_path },
+ fields
+ )
+ end
+
+ let(:user) { owner }
+ let(:variables) { {} }
+ let(:dependency_proxy_manifests_response) { graphql_data.dig('group', 'dependencyProxyManifests', 'edges') }
+ let(:dependency_proxy_image_count_response) { graphql_data.dig('group', 'dependencyProxyImageCount') }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ group.add_owner(owner)
+ end
+
+ subject { post_graphql(query, current_user: user, variables: variables) }
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ subject
+ end
+ end
+
+ context 'with different permissions' do
+ let_it_be(:user) { create(:user) }
+
+ where(:group_visibility, :role, :access_granted) do
+ :private | :maintainer | true
+ :private | :developer | true
+ :private | :reporter | true
+ :private | :guest | true
+ :private | :anonymous | false
+ :public | :maintainer | true
+ :public | :developer | true
+ :public | :reporter | true
+ :public | :guest | true
+ :public | :anonymous | false
+ end
+
+ with_them do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
+ group.add_user(user, role) unless role == :anonymous
+ end
+
+ it 'return the proper response' do
+ subject
+
+ if access_granted
+ expect(dependency_proxy_manifests_response.size).to eq(manifests.size)
+ else
+ expect(dependency_proxy_manifests_response).to be_blank
+ end
+ end
+ end
+ end
+
+ context 'limiting the number of manifests' do
+ let(:limit) { 1 }
+ let(:variables) do
+ { path: group.full_path, n: limit }
+ end
+
+ let(:query) do
+ <<~GQL
+ query($path: ID!, $n: Int) {
+ group(fullPath: $path) {
+ dependencyProxyManifests(first: $n) { #{dependency_proxy_manifest_fields} }
+ }
+ }
+ GQL
+ end
+
+ it 'only returns N manifests' do
+ subject
+
+ expect(dependency_proxy_manifests_response.size).to eq(limit)
+ end
+ end
+
+ it 'returns the total count of manifests' do
+ subject
+
+ expect(dependency_proxy_image_count_response).to eq(manifests.size)
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb b/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
index 1692cfbcf84..f992e46879f 100644
--- a/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
+++ b/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Deleting Sidekiq jobs', :clean_gitlab_redis_queues do
let(:queue) { 'authorized_projects' }
- let(:variables) { { user: admin.username, queue_name: queue } }
+ let(:variables) { { user: admin.username, worker_class: 'AuthorizedProjectsWorker', queue_name: queue } }
let(:mutation) { graphql_mutation(:admin_sidekiq_queues_delete_jobs, variables) }
def mutation_response
diff --git a/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb b/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
new file mode 100644
index 00000000000..07fd57a2cee
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Deletion of custom emoji' do
+ include GraphqlHelpers
+
+ let_it_be(:group) { create(:group) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be_with_reload(:custom_emoji) { create(:custom_emoji, group: group, creator: user2) }
+
+ let(:mutation) do
+ variables = {
+ id: GitlabSchema.id_from_object(custom_emoji).to_s
+ }
+
+ graphql_mutation(:destroy_custom_emoji, variables)
+ end
+
+ shared_examples 'does not delete custom emoji' do
+ it 'does not change count' do
+ expect { post_graphql_mutation(mutation, current_user: current_user) }.not_to change(CustomEmoji, :count)
+ end
+ end
+
+ shared_examples 'deletes custom emoji' do
+ it 'changes count' do
+ expect { post_graphql_mutation(mutation, current_user: current_user) }.to change(CustomEmoji, :count).by(-1)
+ end
+ end
+
+ context 'when the user' do
+ context 'has no permissions' do
+ it_behaves_like 'does not delete custom emoji'
+ end
+
+ context 'when the user is developer and not creator of custom emoji' do
+ before do
+ group.add_developer(current_user)
+ end
+
+ it_behaves_like 'does not delete custom emoji'
+ end
+ end
+
+ context 'when user' do
+ context 'is maintainer' do
+ before do
+ group.add_maintainer(current_user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+
+ context 'is owner' do
+ before do
+ group.add_owner(current_user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+
+ context 'is developer and creator of the emoji' do
+ before do
+ group.add_developer(current_user)
+ custom_emoji.update_attribute(:creator, current_user)
+ end
+
+ it_behaves_like 'deletes custom emoji'
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb b/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
new file mode 100644
index 00000000000..c9e9a22ee0b
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Updating the dependency proxy image ttl policy' do
+ include GraphqlHelpers
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:user) { create(:user) }
+
+ let(:params) do
+ {
+ group_path: group.full_path,
+ enabled: false,
+ ttl: 2
+ }
+ end
+
+ let(:mutation) do
+ graphql_mutation(:update_dependency_proxy_image_ttl_group_policy, params) do
+ <<~QL
+ dependencyProxyImageTtlPolicy {
+ enabled
+ ttl
+ }
+ errors
+ QL
+ end
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:update_dependency_proxy_image_ttl_group_policy) }
+ let(:ttl_policy_response) { mutation_response['dependencyProxyImageTtlPolicy'] }
+
+ before do
+ stub_config(dependency_proxy: { enabled: true })
+ end
+
+ describe 'post graphql mutation' do
+ subject { post_graphql_mutation(mutation, current_user: user) }
+
+ let_it_be(:ttl_policy, reload: true) { create(:image_ttl_group_policy) }
+ let_it_be(:group, reload: true) { ttl_policy.group }
+
+ context 'without permission' do
+ it 'returns no response' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response).to be_nil
+ end
+ end
+
+ context 'with permission' do
+ before do
+ group.add_developer(user)
+ end
+
+ it 'returns the updated dependency proxy image ttl policy', :aggregate_failures do
+ subject
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['errors']).to be_empty
+ expect(ttl_policy_response).to include(
+ 'enabled' => params[:enabled],
+ 'ttl' => params[:ttl]
+ )
+ end
+ end
+ 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 66450f8c604..886f3140086 100644
--- a/spec/requests/api/graphql/mutations/issues/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/create_spec.rb
@@ -39,11 +39,14 @@ RSpec.describe 'Create an issue' do
end
it 'creates the issue' do
- post_graphql_mutation(mutation, current_user: current_user)
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to change(Issue, :count).by(1)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['issue']).to include(input)
expect(mutation_response['issue']).to include('discussionLocked' => true)
+ expect(Issue.last.work_item_type.base_type).to eq('issue')
end
end
end
diff --git a/spec/requests/api/graphql/mutations/issues/update_spec.rb b/spec/requests/api/graphql/mutations/issues/update_spec.rb
index c3aaf090703..0f2eeb90894 100644
--- a/spec/requests/api/graphql/mutations/issues/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/update_spec.rb
@@ -44,6 +44,19 @@ RSpec.describe 'Update of an existing issue' do
expect(mutation_response['issue']).to include('discussionLocked' => true)
end
+ context 'when issue_type is updated' do
+ let(:input) { { 'iid' => issue.iid.to_s, 'type' => 'INCIDENT' } }
+
+ it 'updates issue_type and work_item_type' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ issue.reload
+ end.to change { issue.work_item_type.base_type }.from('issue').to('incident').and(
+ change(issue, :issue_type).from('issue').to('incident')
+ )
+ end
+ end
+
context 'setting labels' do
let(:mutation) do
graphql_mutation(:update_issue, input_params) do
diff --git a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
index 80376f56ee8..a540386a9de 100644
--- a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
+++ b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe 'sentry errors requests' do
include GraphqlHelpers
+
let_it_be(:project) { create(:project, :repository) }
let_it_be(:project_setting) { create(:project_error_tracking_setting, project: project) }
let_it_be(:current_user) { project.owner }
@@ -30,7 +31,7 @@ RSpec.describe 'sentry errors requests' do
let(:error_data) { graphql_data.dig('project', 'sentryErrors', 'detailedError') }
- it 'returns a successful response', :aggregate_failures, :quarantine do
+ it 'returns a successful response', :aggregate_failures do
post_graphql(query, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
@@ -48,11 +49,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'reactive cache returns data' do
+ context 'when reactive cache returns data' do
before do
- allow_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_details)
- .and_return(issue: sentry_detailed_error)
+ stub_setting_for(:issue_details, issue: sentry_detailed_error)
post_graphql(query, current_user: current_user)
end
@@ -72,7 +71,7 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'user does not have permission' do
+ context 'when user does not have permission' do
let(:current_user) { create(:user) }
it 'is expected to return an empty error' do
@@ -81,11 +80,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'sentry api returns an error' do
+ context 'when sentry api returns an error' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_details)
- .and_return(error: 'error message')
+ stub_setting_for(:issue_details, error: 'error message')
post_graphql(query, current_user: current_user)
end
@@ -140,11 +137,11 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'reactive cache returns data' do
+ context 'when reactive cache returns data' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:list_sentry_issues)
- .and_return(issues: [sentry_error], pagination: pagination)
+ stub_setting_for(:list_sentry_issues,
+ issues: [sentry_error],
+ pagination: pagination)
post_graphql(query, current_user: current_user)
end
@@ -177,11 +174,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'sentry api itself errors out' do
+ context 'when sentry api itself errors out' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:list_sentry_issues)
- .and_return(error: 'error message')
+ stub_setting_for(:list_sentry_issues, error: 'error message')
post_graphql(query, current_user: current_user)
end
@@ -223,18 +218,16 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'reactive cache returns data' do
+ context 'when reactive cache returns data' do
before do
- allow_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_latest_event)
- .and_return(latest_event: sentry_stack_trace)
+ stub_setting_for(:issue_latest_event, latest_event: sentry_stack_trace)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'setting stack trace error'
- context 'user does not have permission' do
+ context 'when user does not have permission' do
let(:current_user) { create(:user) }
it 'is expected to return an empty error' do
@@ -243,11 +236,9 @@ RSpec.describe 'sentry errors requests' do
end
end
- context 'sentry api returns an error' do
+ context 'when sentry api returns an error' do
before do
- expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
- .to receive(:issue_latest_event)
- .and_return(error: 'error message')
+ stub_setting_for(:issue_latest_event, error: 'error message')
post_graphql(query, current_user: current_user)
end
@@ -257,4 +248,12 @@ RSpec.describe 'sentry errors requests' do
end
end
end
+
+ private
+
+ def stub_setting_for(method, **return_value)
+ allow_next_found_instance_of(ErrorTracking::ProjectErrorTrackingSetting) do |setting|
+ allow(setting).to receive(method).and_return(**return_value)
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index ff0d7ecceb5..c6b4d82bf15 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -61,6 +61,34 @@ RSpec.describe 'getting an issue list for a project' do
end
end
+ context 'filtering by my_reaction_emoji' do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:upvote_award) { create(:award_emoji, :upvote, user: current_user, awardable: issue_a) }
+
+ let(:issue_a_gid) { issue_a.to_global_id.to_s }
+ let(:issue_b_gid) { issue_b.to_global_id.to_s }
+
+ where(:value, :gids) do
+ 'thumbsup' | lazy { [issue_a_gid] }
+ 'ANY' | lazy { [issue_a_gid] }
+ 'any' | lazy { [issue_a_gid] }
+ 'AnY' | lazy { [issue_a_gid] }
+ 'NONE' | lazy { [issue_b_gid] }
+ 'thumbsdown' | lazy { [] }
+ end
+
+ with_them do
+ let(:issue_filter_params) { { my_reaction_emoji: value } }
+
+ it 'returns correctly filtered issues' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_dig_at(issues_data, :node, :id)).to eq(gids)
+ end
+ end
+ end
+
context 'when limiting the number of results' do
let(:query) do
<<~GQL
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index cb6755640a9..d46ef313563 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -311,6 +311,10 @@ RSpec.describe 'getting pipeline information nested in a project' do
end
it 'does not generate N+1 queries', :request_store, :use_sql_query_cache do
+ # create extra statuses
+ create(:generic_commit_status, :pending, name: 'generic-build-a', pipeline: pipeline, stage_idx: 0, stage: 'build')
+ create(:ci_bridge, :failed, name: 'deploy-a', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
+
# warm up
post_graphql(query, current_user: current_user)
@@ -318,9 +322,11 @@ RSpec.describe 'getting pipeline information nested in a project' do
post_graphql(query, current_user: current_user)
end
- create(:ci_build, name: 'test-a', pipeline: pipeline, stage_idx: 1, stage: 'test')
- create(:ci_build, name: 'test-b', pipeline: pipeline, stage_idx: 1, stage: 'test')
- create(:ci_build, name: 'deploy-a', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
+ create(:generic_commit_status, :pending, name: 'generic-build-b', pipeline: pipeline, stage_idx: 0, stage: 'build')
+ create(:ci_build, :failed, name: 'test-a', pipeline: pipeline, stage_idx: 1, stage: 'test')
+ create(:ci_build, :running, name: 'test-b', pipeline: pipeline, stage_idx: 1, stage: 'test')
+ create(:ci_build, :pending, name: 'deploy-b', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
+ create(:ci_bridge, :failed, name: 'deploy-c', pipeline: pipeline, stage_idx: 2, stage: 'deploy')
expect do
post_graphql(query, current_user: current_user)