diff options
Diffstat (limited to 'spec/requests/api/graphql/mutations')
3 files changed, 213 insertions, 35 deletions
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 index 2da69509ad6..79d687a2bdb 100644 --- a/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb +++ b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb @@ -6,13 +6,18 @@ 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_it_be(:group) { create(:group, :crm_enabled) } + let_it_be(:subgroup) { create(:group, :crm_enabled, parent: group) } + let_it_be(:project) { create(:project, group: subgroup) } + let_it_be(:group_contacts) { create_list(:contact, 4, group: group) } + let_it_be(:subgroup_contacts) { create_list(:contact, 4, group: subgroup) } let(:issue) { create(:issue, project: project) } let(:operation_mode) { Types::MutationOperationModeEnum.default_mode } - let(:contact_ids) { [global_id_of(contacts[1]), global_id_of(contacts[2])] } + let(:contacts) { subgroup_contacts } + let(:initial_contacts) { contacts[0..1] } + let(:mutation_contacts) { contacts[1..2] } + let(:contact_ids) { contact_global_ids(mutation_contacts) } 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 @@ -42,9 +47,47 @@ RSpec.describe 'Setting issues crm contacts' do graphql_mutation_response(:issue_set_crm_contacts) end + def contact_global_ids(contacts) + contacts.map { |contact| global_id_of(contact) } + end + before do - create(:issue_customer_relations_contact, issue: issue, contact: contacts[0]) - create(:issue_customer_relations_contact, issue: issue, contact: contacts[1]) + initial_contacts.each { |contact| create(:issue_customer_relations_contact, issue: issue, contact: contact) } + end + + shared_examples 'successful mutation' do + 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(contact_global_ids(mutation_contacts)) + end + end + + context 'append' do + let(:mutation_contacts) { [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(contact_global_ids(initial_contacts + mutation_contacts)) + end + end + + context 'remove' do + let(:mutation_contacts) { [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(contact_global_ids(initial_contacts - mutation_contacts)) + end + end end context 'when the user has no permission' do @@ -73,37 +116,14 @@ RSpec.describe 'Setting issues crm contacts' do 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 'with issue group contacts' do + let(:contacts) { subgroup_contacts } - context 'append' do - let(: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 + it_behaves_like 'successful mutation' end - context 'remove' do - let(: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 + context 'with issue ancestor group contacts' do + it_behaves_like 'successful mutation' end context 'when the contact does not exist' do @@ -118,7 +138,7 @@ RSpec.describe 'Setting issues crm contacts' do end context 'when the contact belongs to a different group' do - let(:group2) { create(:group) } + let(:group2) { create(:group, :crm_enabled) } let(:contact) { create(:contact, group: group2) } let(:contact_ids) { [global_id_of(contact)] } @@ -158,4 +178,17 @@ RSpec.describe 'Setting issues crm contacts' do end end end + + context 'when crm_enabled is false' do + let(:issue) { create(:issue) } + let(:initial_contacts) { [] } + + it 'raises expected error' do + issue.project.add_reporter(user) + + post_graphql_mutation(mutation, current_user: user) + + expect(graphql_errors).to include(a_hash_including('message' => 'Feature disabled')) + end + end end diff --git a/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb b/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb new file mode 100644 index 00000000000..0166871502b --- /dev/null +++ b/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Setting the escalation status of an incident' do + include GraphqlHelpers + + let_it_be(:project) { create(:project) } + let_it_be(:issue) { create(:incident, project: project) } + let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: issue) } + let_it_be(:user) { create(:user) } + + let(:status) { 'ACKNOWLEDGED' } + let(:input) { { project_path: project.full_path, iid: issue.iid.to_s, status: status } } + + let(:current_user) { user } + let(:mutation) do + graphql_mutation(:issue_set_escalation_status, input) do + <<~QL + clientMutationId + errors + issue { + iid + escalationStatus + } + QL + end + end + + let(:mutation_response) { graphql_mutation_response(:issue_set_escalation_status) } + + before_all do + project.add_developer(user) + end + + context 'when user does not have permission to edit the escalation status' do + let(:current_user) { create(:user) } + + before_all do + project.add_reporter(user) + end + + it_behaves_like 'a mutation that returns a top-level access error' + end + + context 'with non-incident issue is provided' do + let_it_be(:issue) { create(:issue, project: project) } + + it_behaves_like 'a mutation that returns top-level errors', errors: ['Feature unavailable for provided issue'] + end + + context 'with feature disabled' do + before do + stub_feature_flags(incident_escalations: false) + end + + it_behaves_like 'a mutation that returns top-level errors', errors: ['Feature unavailable for provided issue'] + end + + it 'sets given escalation_policy to the escalation status for the issue' do + post_graphql_mutation(mutation, current_user: current_user) + + expect(response).to have_gitlab_http_status(:success) + expect(mutation_response['errors']).to be_empty + expect(mutation_response['issue']['escalationStatus']).to eq(status) + expect(escalation_status.reload.status_name).to eq(:acknowledged) + end + + context 'when status argument is not given' do + let(:input) { {} } + + it_behaves_like 'a mutation that returns top-level errors' do + let(:match_errors) { contain_exactly(include('status (Expected value to not be null)')) } + end + end + + context 'when status argument is invalid' do + let(:status) { 'INVALID' } + + it_behaves_like 'an invalid argument to the mutation', argument_name: :status + end +end diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb new file mode 100644 index 00000000000..e7a0c7753fb --- /dev/null +++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Create a work item' do + include GraphqlHelpers + + let_it_be(:project) { create(:project) } + let_it_be(:developer) { create(:user).tap { |user| project.add_developer(user) } } + + let(:input) do + { + 'title' => 'new title', + 'description' => 'new description', + 'workItemTypeId' => WorkItems::Type.default_by_type(:task).to_global_id.to_s + } + end + + let(:mutation) { graphql_mutation(:workItemCreate, input.merge('projectPath' => project.full_path)) } + + let(:mutation_response) { graphql_mutation_response(:work_item_create) } + + context 'the user is not allowed to create a work item' do + let(:current_user) { create(:user) } + + it_behaves_like 'a mutation that returns a top-level access error' + end + + context 'when user has permissions to create a work item' do + let(:current_user) { developer } + + it 'creates the work item' do + expect do + post_graphql_mutation(mutation, current_user: current_user) + end.to change(WorkItem, :count).by(1) + + created_work_item = WorkItem.last + + expect(response).to have_gitlab_http_status(:success) + expect(created_work_item.issue_type).to eq('task') + expect(created_work_item.work_item_type.base_type).to eq('task') + expect(mutation_response['workItem']).to include( + input.except('workItemTypeId').merge( + 'id' => created_work_item.to_global_id.to_s, + 'workItemType' => hash_including('name' => 'Task') + ) + ) + end + + it_behaves_like 'has spam protection' do + let(:mutation_class) { ::Mutations::WorkItems::Create } + end + + context 'when the work_items feature flag is disabled' do + before do + stub_feature_flags(work_items: false) + end + + it_behaves_like 'a mutation that returns top-level errors', + errors: ["Field 'workItemCreate' doesn't exist on type 'Mutation'", "Variable $workItemCreateInput is declared by anonymous mutation but not used"] + end + end +end |