using e_suite.API.Common; using e_suite.API.Common.exceptions; using e_suite.Database.Core.Extensions.Exceptions; using eSuite.API.Middleware; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; using Newtonsoft.Json; using NUnit.Framework; using System.ComponentModel.DataAnnotations; namespace eSuite.API.UnitTests.Middleware; [TestFixture] public class ExceptionCaptureUnitTests { private Mock _requestDelegateMock = null!; private readonly Mock _exceptionLoggerMock = new Mock()!; private ExceptionCapture _exceptionCaptureMiddleWare = null!; [SetUp] public void Setup() { _requestDelegateMock = new Mock(); _exceptionCaptureMiddleWare = new ExceptionCapture(_requestDelegateMock.Object, _exceptionLoggerMock.Object); } [Test] public void ExceptionMiddleWare_WhenCalled_InvokeCalledAndNoExceptionThrown() { //Arrange var context = new DefaultHttpContext(); //Assert Assert.DoesNotThrowAsync(async () => { //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); }); _requestDelegateMock.Verify(x => x.Invoke(context), Times.Once); } [Test] public async Task ExceptionMiddleWare_WhenGuidMismatchThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws( () => new GuidMismatchException("Test error")); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Test error")); } [Test] public async Task ExceptionMiddleWare_WhenNotFoundExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status404NotFound)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Not found")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'e_suite.API.Common.exceptions.NotFoundException' was thrown.")); } [Test] public async Task ExceptionMiddleWare_WhenExistsExceptionExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'e_suite.API.Common.exceptions.ExistsException' was thrown.")); } [Test] public async Task ExceptionMiddleWare_WhenInvalidOperationExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Operation is not valid due to the current state of the object.")); } [Test] public async Task ExceptionMiddleWare_WhenValidationExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'System.ComponentModel.DataAnnotations.ValidationException' was thrown.")); } [Test] public async Task ExceptionMiddleWare_WhenArgumentExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Value does not fall within the expected range.")); } [Test] public async Task ExceptionMiddleWare_WhenInvalidReferenceObjectIdThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'e_suite.API.Common.exceptions.InvalidReferenceObjectId' was thrown.")); } [Test] public async Task ExceptionMiddleWare_WhenTokenInvalidExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'e_suite.API.Common.exceptions.TokenInvalidException' was thrown.")); } [Test] public async Task ExceptionMiddleWare_WhenInvalidEmailExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Bad request")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'e_suite.API.Common.exceptions.InvalidEmailException' was thrown.")); } [Test] public async Task ExceptionMiddleWare_WhenOperationCanceledExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status400BadRequest)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Request cancelled")); Assert.That(problem!.Detail, Is.EqualTo("The operation was canceled.")); } [Test] public async Task ExceptionMiddleWare_WhenUnhandledExceptionThrow_ExpectedResponseReturned() { //Arrange var context = new DefaultHttpContext(); context.Response.Body = new MemoryStream(); _requestDelegateMock.Setup(x => x.Invoke(context)).Throws(); //Act await _exceptionCaptureMiddleWare.InvokeAsync(context); //Assert Assert.That(context.Response.StatusCode, Is.EqualTo(StatusCodes.Status500InternalServerError)); context.Response.Body.Seek(0, SeekOrigin.Begin); using var reader = new StreamReader(context.Response.Body); var streamText = reader.ReadToEnd(); var problem = JsonConvert.DeserializeObject(streamText); Assert.That(problem, Is.Not.Null); Assert.That(problem!.Title, Is.EqualTo("Internal Server Error")); Assert.That(problem!.Detail, Is.EqualTo("Exception of type 'System.Exception' was thrown.")); } }