diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-09-20 16:18:24 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-09-20 16:18:24 +0300 |
commit | 0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch) | |
tree | 4dcc884cf6d81db44adae4aa99f8ec1233a41f55 /spec/requests/api/graphql | |
parent | 744144d28e3e7fddc117924fef88de5d9674fe4c (diff) |
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
Diffstat (limited to 'spec/requests/api/graphql')
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) |