From 6d4ea0d57ea4cad56f1da3ec8709bfdf13663ea6 Mon Sep 17 00:00:00 2001 From: andrewmorris43 Date: Wed, 15 Jan 2025 14:04:35 +0000 Subject: [PATCH 1/3] test: add CreateException unit tests --- .../CreateException/CreateException.cs | 38 +++--- .../CohortManager/src/Functions/Functions.sln | 6 + .../CreateExceptionTests.cs | 108 ++++++++++++++++++ .../CreateExceptionTests.csproj | 30 +++++ 4 files changed, 161 insertions(+), 21 deletions(-) create mode 100644 tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs create mode 100644 tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.csproj diff --git a/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs b/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs index 12061cd94..297a7ee49 100644 --- a/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs +++ b/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs @@ -10,48 +10,44 @@ namespace NHS.CohortManager.ExceptionService; using Common; using Data.Database; -public class CreateException +public class CreateExceptionRecord { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IValidationExceptionData _validationData; - private readonly ICreateResponse _createResponse; - public CreateException(ILogger logger, IValidationExceptionData validationExceptionData, ICreateResponse createResponse) + public CreateExceptionRecord(ILogger logger, IValidationExceptionData validationExceptionData, ICreateResponse createResponse) { _logger = logger; _validationData = validationExceptionData; _createResponse = createResponse; } - [Function("CreateException")] + [Function("CreateExceptionRecord")] public async Task RunAsync([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req) { + ValidationException exception; + try { - ValidationException exception; - var requestBody = ""; - using (var reader = new StreamReader(req.Body, Encoding.UTF8)) { - requestBody = await reader.ReadToEndAsync(); + var requestBody = await reader.ReadToEndAsync(); exception = JsonSerializer.Deserialize(requestBody); } - if (!string.IsNullOrEmpty(requestBody)) - { - if (_validationData.Create(exception)) - { - return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req); - } - } - return req.CreateResponse(HttpStatusCode.BadRequest); - } catch (Exception ex) { - _logger.LogError(ex, "there has been an error while creating an exception record: {Message}", ex.Message); - return req.CreateResponse(HttpStatusCode.InternalServerError); + _logger.LogError(ex, ex.Message); + return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req); } + if (_validationData.Create(exception)) + { + _logger.LogInformation("The exception record has been created successfully"); + return _createResponse.CreateHttpResponse(HttpStatusCode.Created, req); + } + + _logger.LogError("The exception record was not inserted into the database: {Exception}", exception); + return _createResponse.CreateHttpResponse(HttpStatusCode.InternalServerError, req); } } - diff --git a/application/CohortManager/src/Functions/Functions.sln b/application/CohortManager/src/Functions/Functions.sln index 45c12352e..3139e7045 100644 --- a/application/CohortManager/src/Functions/Functions.sln +++ b/application/CohortManager/src/Functions/Functions.sln @@ -174,6 +174,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ValidateDatesTests", "..\.. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataServiceTests", "..\..\..\..\tests\UnitTests\DataServiceTests\DataServiceTests.csproj", "{E26B2D73-BD60-4AD8-B403-939ACEDE9429}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateExceptionTests", "..\..\..\..\tests\UnitTests\ExceptionHandlingTests\CreateExceptionTests\CreateExceptionTests.csproj", "{190F304E-D716-4A65-985D-042BF7B22460}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -440,6 +442,10 @@ Global {E26B2D73-BD60-4AD8-B403-939ACEDE9429}.Debug|Any CPU.Build.0 = Debug|Any CPU {E26B2D73-BD60-4AD8-B403-939ACEDE9429}.Release|Any CPU.ActiveCfg = Release|Any CPU {E26B2D73-BD60-4AD8-B403-939ACEDE9429}.Release|Any CPU.Build.0 = Release|Any CPU + {190F304E-D716-4A65-985D-042BF7B22460}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {190F304E-D716-4A65-985D-042BF7B22460}.Debug|Any CPU.Build.0 = Debug|Any CPU + {190F304E-D716-4A65-985D-042BF7B22460}.Release|Any CPU.ActiveCfg = Release|Any CPU + {190F304E-D716-4A65-985D-042BF7B22460}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs b/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs new file mode 100644 index 000000000..f8d9d67d9 --- /dev/null +++ b/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs @@ -0,0 +1,108 @@ +namespace NHS.CohortManager.Tests.UnitTests.CreateExceptionTests; + +using System.Net; +using Microsoft.Extensions.Logging; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Moq; +using Model; +using Common; +using Data.Database; +using NHS.CohortManager.ExceptionService; +using System.Text.Json; +using System.Text; + +[TestClass] +public class CreateExceptionTests +{ + private readonly Mock> _logger = new(); + private readonly Mock _context = new(); + private readonly Mock _request; + private readonly ValidationException _requestBody; + private readonly CreateExceptionRecord _function; + private readonly Mock _createResponse = new(); + private readonly Mock _validationExceptionData = new(); + + public CreateExceptionTests() + { + _request = new Mock(_context.Object); + + _requestBody = new ValidationException() { ExceptionId = 1 }; + + _function = new CreateExceptionRecord(_logger.Object, _validationExceptionData.Object, _createResponse.Object); + + _request.Setup(r => r.CreateResponse()).Returns(() => + { + var response = new Mock(_context.Object); + response.SetupProperty(r => r.Headers, new HttpHeadersCollection()); + response.SetupProperty(r => r.StatusCode); + response.SetupProperty(r => r.Body, new MemoryStream()); + return response.Object; + }); + + _createResponse.Setup(x => x.CreateHttpResponse(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((HttpStatusCode statusCode, HttpRequestData req, string ResponseBody) => + { + var response = req.CreateResponse(statusCode); + response.Headers.Add("Content-Type", "application/json; charset=utf-8"); + response.WriteString(ResponseBody); + return response; + }); + + var json = JsonSerializer.Serialize(_requestBody); + SetUpRequestBody(json); + } + + [TestMethod] + public async Task Run_EmptyRequest_ReturnBadRequest() + { + // Arrange + SetUpRequestBody(string.Empty); + + // Act + var result = await _function.RunAsync(_request.Object); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(HttpStatusCode.BadRequest, result.StatusCode); + } + + [TestMethod] + public async Task Run_ExceptionRecordCreated_ReturnsCreated() + { + // Arrange + _validationExceptionData.Setup(s => s.Create(It.IsAny())).Returns(true); + + // Act + var result = await _function.RunAsync(_request.Object); + + // Assert + Assert.IsNotNull(result); + _validationExceptionData.Verify(v => v.Create(It.IsAny()), Times.Once); + Assert.AreEqual(HttpStatusCode.Created, result.StatusCode); + } + + [TestMethod] + public async Task Run_ExceptionRecordFailedToCreate_ReturnsInternalServerError() + { + // Arrange + _validationExceptionData.Setup(s => s.Create(It.IsAny())).Returns(false); + + // Act + var result = await _function.RunAsync(_request.Object); + + // Assert + Assert.IsNotNull(result); + _validationExceptionData.Verify(v => v.Create(It.IsAny()), Times.Once); + Assert.AreEqual(HttpStatusCode.InternalServerError, result.StatusCode); + } + + private void SetUpRequestBody(string json) + { + var byteArray = Encoding.ASCII.GetBytes(json); + var bodyStream = new MemoryStream(byteArray); + + _request.Setup(r => r.Body).Returns(bodyStream); + } +} + diff --git a/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.csproj b/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.csproj new file mode 100644 index 000000000..e18a6fad7 --- /dev/null +++ b/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + + From 0bd2fed25301a4b01684cd930d82021b179eb729 Mon Sep 17 00:00:00 2001 From: andrewmorris43 Date: Thu, 16 Jan 2025 11:22:23 +0000 Subject: [PATCH 2/3] fix: CreateException function name --- .../ExceptionHandling/CreateException/CreateException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs b/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs index 297a7ee49..48602897b 100644 --- a/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs +++ b/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs @@ -22,7 +22,7 @@ public CreateExceptionRecord(ILogger logger, IValidationE _createResponse = createResponse; } - [Function("CreateExceptionRecord")] + [Function("CreateException")] public async Task RunAsync([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req) { ValidationException exception; From 6dcac9fb430f1efeb654a10e799d0720deaed28b Mon Sep 17 00:00:00 2001 From: andrewmorris43 Date: Thu, 16 Jan 2025 12:12:49 +0000 Subject: [PATCH 3/3] chore: revert create exception class name --- .../ExceptionHandling/CreateException/CreateException.cs | 6 +++--- .../CreateExceptionTests/CreateExceptionTests.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs b/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs index 48602897b..d6e523c6a 100644 --- a/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs +++ b/application/CohortManager/src/Functions/ExceptionHandling/CreateException/CreateException.cs @@ -10,12 +10,12 @@ namespace NHS.CohortManager.ExceptionService; using Common; using Data.Database; -public class CreateExceptionRecord +public class CreateException { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IValidationExceptionData _validationData; private readonly ICreateResponse _createResponse; - public CreateExceptionRecord(ILogger logger, IValidationExceptionData validationExceptionData, ICreateResponse createResponse) + public CreateException(ILogger logger, IValidationExceptionData validationExceptionData, ICreateResponse createResponse) { _logger = logger; _validationData = validationExceptionData; diff --git a/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs b/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs index f8d9d67d9..f0b698966 100644 --- a/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs +++ b/tests/UnitTests/ExceptionHandlingTests/CreateExceptionTests/CreateExceptionTests.cs @@ -15,11 +15,11 @@ namespace NHS.CohortManager.Tests.UnitTests.CreateExceptionTests; [TestClass] public class CreateExceptionTests { - private readonly Mock> _logger = new(); + private readonly Mock> _logger = new(); private readonly Mock _context = new(); private readonly Mock _request; private readonly ValidationException _requestBody; - private readonly CreateExceptionRecord _function; + private readonly CreateException _function; private readonly Mock _createResponse = new(); private readonly Mock _validationExceptionData = new(); @@ -29,7 +29,7 @@ public CreateExceptionTests() _requestBody = new ValidationException() { ExceptionId = 1 }; - _function = new CreateExceptionRecord(_logger.Object, _validationExceptionData.Object, _createResponse.Object); + _function = new CreateException(_logger.Object, _validationExceptionData.Object, _createResponse.Object); _request.Setup(r => r.CreateResponse()).Returns(() => {