diff options
Diffstat (limited to 'spec/graphql/mutations')
8 files changed, 270 insertions, 17 deletions
diff --git a/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb new file mode 100644 index 00000000000..f47f1b9869e --- /dev/null +++ b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Ci::Runner::BulkDelete do + include GraphqlHelpers + + let_it_be(:admin_user) { create(:user, :admin) } + let_it_be(:user) { create(:user) } + + let(:current_ctx) { { current_user: user } } + + let(:mutation_params) do + {} + end + + describe '#resolve' do + subject(:response) do + sync(resolve(described_class, args: mutation_params, ctx: current_ctx)) + end + + context 'when the user cannot admin the runner' do + let(:runner) { create(:ci_runner) } + let(:mutation_params) do + { ids: [runner.to_global_id] } + end + + it 'generates an error' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) { response } + end + end + + context 'when user can delete runners' do + let(:user) { admin_user } + let!(:runners) do + create_list(:ci_runner, 2, :instance) + end + + context 'when required arguments are missing' do + let(:mutation_params) { {} } + + context 'when admin mode is enabled', :enable_admin_mode do + it 'does not return an error' do + is_expected.to match a_hash_including(errors: []) + end + end + end + + context 'with runners specified by id' do + let(:mutation_params) do + { ids: runners.map(&:to_global_id) } + end + + context 'when admin mode is enabled', :enable_admin_mode do + it 'deletes runners', :aggregate_failures do + expect_next_instance_of( + ::Ci::Runners::BulkDeleteRunnersService, { runners: runners } + ) do |service| + expect(service).to receive(:execute).once.and_call_original + end + + expect { response }.to change { Ci::Runner.count }.by(-2) + expect(response[:errors]).to be_empty + end + + context 'when runner list is is above limit' do + before do + stub_const('::Ci::Runners::BulkDeleteRunnersService::RUNNER_LIMIT', 1) + end + + it 'only deletes up to the defined limit', :aggregate_failures do + expect { response }.to change { Ci::Runner.count } + .by(-::Ci::Runners::BulkDeleteRunnersService::RUNNER_LIMIT) + expect(response[:errors]).to be_empty + end + end + end + + context 'when admin mode is disabled', :aggregate_failures do + it 'returns error', :aggregate_failures do + expect do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + response + end + end.not_to change { Ci::Runner.count } + end + end + end + end + end +end diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb index ffaa6e93d1b..b8efd4213fa 100644 --- a/spec/graphql/mutations/ci/runner/update_spec.rb +++ b/spec/graphql/mutations/ci/runner/update_spec.rb @@ -2,12 +2,11 @@ require 'spec_helper' -RSpec.describe 'Mutations::Ci::Runner::Update' do +RSpec.describe Mutations::Ci::Runner::Update do include GraphqlHelpers let_it_be(:user) { create(:user) } let_it_be(:runner) { create(:ci_runner, active: true, locked: false, run_untagged: true) } - let_it_be(:described_class) { Mutations::Ci::Runner::Update } let(:current_ctx) { { current_user: user } } let(:mutated_runner) { subject[:runner] } diff --git a/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb index 8296e5c6c15..102d33378c6 100644 --- a/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb +++ b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb @@ -57,17 +57,40 @@ RSpec.describe Mutations::IncidentManagement::TimelineEvent::Update do end context 'when there is a validation error' do - let(:occurred_at) { 'invalid date' } + context 'when note is blank' do + let(:note) { '' } - it 'does not update the timeline event' do - expect { resolve }.not_to change { timeline_event.reload.updated_at } + it 'does not update the timeline event' do + expect { resolve }.not_to change { timeline_event.reload.updated_at } + end + + it 'responds with error' do + expect(resolve).to eq(timeline_event: nil, errors: ["Note can't be blank"]) + end end - it 'responds with error' do - expect(resolve).to eq( - timeline_event: nil, - errors: ["Occurred at can't be blank"] - ) + context 'when occurred_at is blank' do + let(:occurred_at) { '' } + + it 'does not update the timeline event' do + expect { resolve }.not_to change { timeline_event.reload.updated_at } + end + + it 'responds with error' do + expect(resolve).to eq(timeline_event: nil, errors: ["Occurred at can't be blank"]) + end + end + + context 'when occurred_at is invalid' do + let(:occurred_at) { 'invalid date' } + + it 'does not update the timeline event' do + expect { resolve }.not_to change { timeline_event.reload.updated_at } + end + + it 'responds with error' do + expect(resolve).to eq(timeline_event: nil, errors: ["Occurred at can't be blank"]) + end end end end diff --git a/spec/graphql/mutations/merge_requests/set_labels_spec.rb b/spec/graphql/mutations/merge_requests/set_labels_spec.rb index 1bb303cf99b..44bd9342b8e 100644 --- a/spec/graphql/mutations/merge_requests/set_labels_spec.rb +++ b/spec/graphql/mutations/merge_requests/set_labels_spec.rb @@ -64,7 +64,7 @@ RSpec.describe Mutations::MergeRequests::SetLabels do end context 'when passing operation_mode as REMOVE' do - subject { mutation.resolve(project_path: merge_request.project.full_path, iid: merge_request.iid, label_ids: label_ids, operation_mode: Types::MutationOperationModeEnum.enum[:remove])} + subject { mutation.resolve(project_path: merge_request.project.full_path, iid: merge_request.iid, label_ids: label_ids, operation_mode: Types::MutationOperationModeEnum.enum[:remove]) } it 'removes the labels, without removing others' do merge_request.update!(labels: [label, label2]) diff --git a/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb b/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb new file mode 100644 index 00000000000..df4aa885bbf --- /dev/null +++ b/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::MergeRequests::SetReviewers do + let_it_be(:user) { create(:user) } + let_it_be(:merge_request, reload: true) { create(:merge_request) } + let_it_be(:reviewer) { create(:user) } + let_it_be(:reviewer2) { create(:user) } + + subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) } + + describe '#resolve' do + let(:reviewer_usernames) { [reviewer.username] } + let(:mutated_merge_request) { subject[:merge_request] } + let(:mode) { described_class.arguments['operationMode'].default_value } + + subject do + mutation.resolve(project_path: merge_request.project.full_path, + iid: merge_request.iid, + operation_mode: mode, + reviewer_usernames: reviewer_usernames) + end + + it 'does not change reviewers if the merge_request is not accessible to the reviewers' do + merge_request.project.add_developer(user) + + expect { subject }.not_to change { merge_request.reload.reviewer_ids } + end + + it 'returns an operational error if the merge_request is not accessible to the reviewers' do + merge_request.project.add_developer(user) + + result = subject + + expect(result[:errors]).to include a_string_matching(/Cannot assign/) + end + + context 'when the user does not have permissions' do + it_behaves_like 'permission level for merge request mutation is correctly verified' + end + + context 'when the user can update the merge_request' do + before do + merge_request.project.add_developer(reviewer) + merge_request.project.add_developer(reviewer2) + merge_request.project.add_developer(user) + end + + it 'replaces the reviewer' do + merge_request.reviewers = [reviewer2] + merge_request.save! + + expect(mutated_merge_request).to eq(merge_request) + expect(mutated_merge_request.reviewers).to contain_exactly(reviewer) + expect(subject[:errors]).to be_empty + end + + it 'returns errors when merge_request could not be updated' do + allow(merge_request).to receive(:errors_on_object).and_return(['foo']) + + expect(subject[:errors]).not_to match_array(['foo']) + end + + context 'when passing an empty reviewer list' do + let(:reviewer_usernames) { [] } + + before do + merge_request.reviewers = [reviewer] + merge_request.save! + end + + it 'removes all reviewers' do + expect(mutated_merge_request).to eq(merge_request) + expect(mutated_merge_request.reviewers).to eq([]) + expect(subject[:errors]).to be_empty + end + end + + context 'when passing "append" as true' do + subject do + mutation.resolve( + project_path: merge_request.project.full_path, + iid: merge_request.iid, + reviewer_usernames: reviewer_usernames, + operation_mode: Types::MutationOperationModeEnum.enum[:append] + ) + end + + before do + merge_request.reviewers = [reviewer2] + merge_request.save! + + # In CE, APPEND is a NOOP as you can't have multiple reviewers + # We test multiple assignment in EE specs + stub_licensed_features(multiple_merge_request_reviewers: false) + end + + it 'is a NO-OP in FOSS' do + expect(mutated_merge_request).to eq(merge_request) + expect(mutated_merge_request.reviewers).to contain_exactly(reviewer2) + expect(subject[:errors]).to be_empty + end + end + + context 'when passing "remove" as true' do + before do + merge_request.reviewers = [reviewer] + merge_request.save! + end + + it 'removes named reviewer' do + mutated_merge_request = mutation.resolve( + project_path: merge_request.project.full_path, + iid: merge_request.iid, + reviewer_usernames: reviewer_usernames, + operation_mode: Types::MutationOperationModeEnum.enum[:remove] + )[:merge_request] + + expect(mutated_merge_request).to eq(merge_request) + expect(mutated_merge_request.reviewers).to eq([]) + expect(subject[:errors]).to be_empty + end + + it 'does not remove unnamed reviewer' do + mutated_merge_request = mutation.resolve( + project_path: merge_request.project.full_path, + iid: merge_request.iid, + reviewer_usernames: [reviewer2.username], + operation_mode: Types::MutationOperationModeEnum.enum[:remove] + )[:merge_request] + + expect(mutated_merge_request).to eq(merge_request) + expect(mutated_merge_request.reviewers).to contain_exactly(reviewer) + expect(subject[:errors]).to be_empty + end + end + end + end +end diff --git a/spec/graphql/mutations/releases/create_spec.rb b/spec/graphql/mutations/releases/create_spec.rb index 1f2c3ed537f..b6b9449aa39 100644 --- a/spec/graphql/mutations/releases/create_spec.rb +++ b/spec/graphql/mutations/releases/create_spec.rb @@ -11,9 +11,9 @@ RSpec.describe Mutations::Releases::Create do let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) } - let(:tag) { 'v1.1.0'} - let(:ref) { 'master'} - let(:name) { 'Version 1.0'} + let(:tag) { 'v1.1.0' } + let(:ref) { 'master' } + let(:name) { 'Version 1.0' } let(:description) { 'The first release :rocket:' } let(:released_at) { Time.parse('2018-12-10') } let(:milestones) { [milestone_12_3.title, milestone_12_4.title] } diff --git a/spec/graphql/mutations/releases/delete_spec.rb b/spec/graphql/mutations/releases/delete_spec.rb index 9934aea0031..09b420fe1ea 100644 --- a/spec/graphql/mutations/releases/delete_spec.rb +++ b/spec/graphql/mutations/releases/delete_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Mutations::Releases::Delete do let_it_be(:reporter) { create(:user) } let_it_be(:developer) { create(:user) } let_it_be(:maintainer) { create(:user) } - let_it_be(:tag) { 'v1.1.0'} + let_it_be(:tag) { 'v1.1.0' } let_it_be(:release) { create(:release, project: project, tag: tag) } let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) } diff --git a/spec/graphql/mutations/releases/update_spec.rb b/spec/graphql/mutations/releases/update_spec.rb index 9fae703b85a..15b10ea0648 100644 --- a/spec/graphql/mutations/releases/update_spec.rb +++ b/spec/graphql/mutations/releases/update_spec.rb @@ -9,8 +9,8 @@ RSpec.describe Mutations::Releases::Update do let_it_be(:reporter) { create(:user) } let_it_be(:developer) { create(:user) } - let_it_be(:tag) { 'v1.1.0'} - let_it_be(:name) { 'Version 1.0'} + let_it_be(:tag) { 'v1.1.0' } + let_it_be(:name) { 'Version 1.0' } let_it_be(:description) { 'The first release :rocket:' } let_it_be(:released_at) { Time.parse('2018-12-10').utc } let_it_be(:created_at) { Time.parse('2018-11-05').utc } |