diff options
Diffstat (limited to 'spec/graphql/mutations/discussions/toggle_resolve_spec.rb')
-rw-r--r-- | spec/graphql/mutations/discussions/toggle_resolve_spec.rb | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/spec/graphql/mutations/discussions/toggle_resolve_spec.rb b/spec/graphql/mutations/discussions/toggle_resolve_spec.rb new file mode 100644 index 00000000000..9ac4d6ab165 --- /dev/null +++ b/spec/graphql/mutations/discussions/toggle_resolve_spec.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Discussions::ToggleResolve do + subject(:mutation) do + described_class.new(object: nil, context: { current_user: user }, field: nil) + end + + let_it_be(:project) { create(:project, :repository) } + + describe '#resolve' do + subject do + mutation.resolve({ id: id_arg, resolve: resolve_arg }) + end + + let(:id_arg) { discussion.to_global_id.to_s } + let(:resolve_arg) { true } + let(:mutated_discussion) { subject[:discussion] } + let(:errors) { subject[:errors] } + + shared_examples 'a working resolve method' do + context 'when the user does not have permission' do + let_it_be(:user) { create(:user) } + + it 'raises an error if the resource is not accessible to the user' do + expect { subject }.to raise_error( + Gitlab::Graphql::Errors::ResourceNotAvailable, + "The resource that you are attempting to access does not exist or you don't have permission to perform this action" + ) + end + end + + context 'when the user has permission' do + let_it_be(:user) { create(:user, developer_projects: [project]) } + + context 'when discussion cannot be found' do + let(:id_arg) { "#{discussion.to_global_id}foo" } + + it 'raises an error' do + expect { subject }.to raise_error( + Gitlab::Graphql::Errors::ResourceNotAvailable, + "The resource that you are attempting to access does not exist or you don't have permission to perform this action" + ) + end + end + + context 'when discussion is not a Discussion' do + let(:discussion) { create(:note, noteable: noteable, project: project) } + + it 'raises an error' do + expect { subject }.to raise_error( + Gitlab::Graphql::Errors::ArgumentError, + "#{discussion.to_global_id} is not a valid id for Discussion." + ) + end + end + + shared_examples 'returns a resolved discussion without errors' do + it 'returns a resolved discussion' do + expect(mutated_discussion).to be_resolved + end + + it 'returns empty errors' do + expect(errors).to be_empty + end + end + + shared_examples 'returns an unresolved discussion without errors' do + it 'returns an unresolved discussion' do + expect(mutated_discussion).not_to be_resolved + end + + it 'returns empty errors' do + expect(errors).to be_empty + end + end + + context 'when the `resolve` argument is true' do + include_examples 'returns a resolved discussion without errors' + + context 'when the discussion is already resolved' do + before do + discussion.resolve!(user) + end + + include_examples 'returns a resolved discussion without errors' + end + + context 'when the service raises an `ActiveRecord::RecordNotSaved` error' do + before do + allow_next_instance_of(::Discussions::ResolveService) do |service| + allow(service).to receive(:execute).and_raise(ActiveRecord::RecordNotSaved) + end + end + + it 'does not resolve the discussion' do + expect(mutated_discussion).not_to be_resolved + end + + it 'returns errors' do + expect(errors).to contain_exactly('Discussion failed to be resolved') + end + end + end + + context 'when the `resolve` argument is false' do + let(:resolve_arg) { false } + + context 'when the discussion is resolved' do + before do + discussion.resolve!(user) + end + + include_examples 'returns an unresolved discussion without errors' + + context 'when the service raises an `ActiveRecord::RecordNotSaved` error' do + before do + allow_next_instance_of(discussion.class) do |instance| + allow(instance).to receive(:unresolve!).and_raise(ActiveRecord::RecordNotSaved) + end + end + + it 'does not unresolve the discussion' do + expect(mutated_discussion).to be_resolved + end + + it 'returns errors' do + expect(errors).to contain_exactly('Discussion failed to be unresolved') + end + end + end + + context 'when the discussion is already unresolved' do + include_examples 'returns an unresolved discussion without errors' + end + end + end + end + + context 'when discussion is on a merge request' do + let_it_be(:noteable) { create(:merge_request, source_project: project) } + let(:discussion) { create(:diff_note_on_merge_request, noteable: noteable, project: project).to_discussion } + + it_behaves_like 'a working resolve method' + end + + context 'when discussion is on a design' do + let_it_be(:noteable) { create(:design, :with_file, issue: create(:issue, project: project)) } + let(:discussion) { create(:diff_note_on_design, noteable: noteable, project: project).to_discussion } + + it_behaves_like 'a working resolve method' + end + end +end |