diff --git a/src/MaksIT.Results.Tests/MaksIT.Results.Tests.csproj b/src/MaksIT.Results.Tests/MaksIT.Results.Tests.csproj index 05769bf..069255b 100644 --- a/src/MaksIT.Results.Tests/MaksIT.Results.Tests.csproj +++ b/src/MaksIT.Results.Tests/MaksIT.Results.Tests.csproj @@ -14,6 +14,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/MaksIT.Results.Tests/UnitTest1.cs b/src/MaksIT.Results.Tests/UnitTest1.cs index 17f3a4d..eb00ce3 100644 --- a/src/MaksIT.Results.Tests/UnitTest1.cs +++ b/src/MaksIT.Results.Tests/UnitTest1.cs @@ -1,137 +1,166 @@ -using Xunit; using System.Net; -using MaksIT.Results; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; using MaksIT.Results.Mvc; -namespace MaksIT.Results.Tests { - public class ResultTests { - [Fact] - public void Result_Ok_ShouldReturnSuccess() { - // Arrange - var message = "Operation successful"; - // Act - var result = Result.Ok(message); +namespace MaksIT.Results.Tests; +public class ResultTests { + [Fact] + public void Result_Ok_ShouldReturnSuccess() { + // Arrange + var message = "Operation successful"; - // Assert - Assert.True(result.IsSuccess); - Assert.Contains(message, result.Messages); - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - } + // Act + var result = Result.Ok(message); - [Fact] - public void Result_BadRequest_ShouldReturnFailure() { - // Arrange - var message = "Invalid request"; - - // Act - var result = Result.BadRequest(message); - - // Assert - Assert.False(result.IsSuccess); - Assert.Contains(message, result.Messages); - Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); - } - - [Fact] - public void Result_Generic_Ok_ShouldReturnSuccessWithValue() { - // Arrange - var value = 42; - var message = "Operation successful"; - - // Act - var result = Result.Ok(value, message); - - // Assert - Assert.True(result.IsSuccess); - Assert.Equal(value, result.Value); - Assert.Contains(message, result.Messages); - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - } - - [Fact] - public void Result_Generic_NotFound_ShouldReturnFailureWithNullValue() { - // Arrange - var message = "Resource not found"; - - // Act - var result = Result.NotFound(null, message); - - // Assert - Assert.False(result.IsSuccess); - Assert.Null(result.Value); - Assert.Contains(message, result.Messages); - Assert.Equal(HttpStatusCode.NotFound, result.StatusCode); - } - - [Fact] - public void Result_ToResultOfType_ShouldTransformValue() { - // Arrange - var initialValue = 42; - var transformedValue = "42"; - var result = Result.Ok(initialValue); - - // Act - var transformedResult = result.ToResultOfType(value => value.ToString()); - - // Assert - Assert.True(transformedResult.IsSuccess); - Assert.Equal(transformedValue, transformedResult.Value); - Assert.Equal(result.StatusCode, transformedResult.StatusCode); - } - - [Fact] - public void Result_ToActionResult_ShouldReturnStatusCodeResult() { - // Arrange - var result = Result.Ok("Operation successful"); - - // Act - var actionResult = result.ToActionResult(); - - // Assert - Assert.IsType(actionResult); - var statusCodeResult = actionResult as StatusCodeResult; - Assert.NotNull(statusCodeResult); - Assert.Equal((int)HttpStatusCode.OK, statusCodeResult.StatusCode); - } - - [Fact] - public void Result_ToActionResult_ShouldReturnObjectResultForFailure() { - // Arrange - var errorMessage = "An error occurred"; - var result = Result.BadRequest(errorMessage); - - // Act - var actionResult = result.ToActionResult(); - - // Assert - Assert.IsType(actionResult); - var objectResult = actionResult as ObjectResult; - Assert.NotNull(objectResult); - Assert.Equal((int)HttpStatusCode.BadRequest, objectResult.StatusCode); - Assert.IsType(objectResult.Value); - var problemDetails = objectResult.Value as ProblemDetails; - Assert.NotNull(problemDetails); - Assert.Equal((int)HttpStatusCode.BadRequest, problemDetails.Status); - Assert.Equal("An error occurred", problemDetails.Title); - Assert.Equal(errorMessage, problemDetails.Detail); - } - - [Fact] - public void Result_Generic_ToActionResult_ShouldReturnObjectResultWithValue() { - // Arrange - var value = new { Id = 1, Name = "Test" }; - var result = Result.Ok(value); - - // Act - var actionResult = result.ToActionResult(); - - // Assert - Assert.IsType(actionResult); - var objectResult = actionResult as ObjectResult; - Assert.NotNull(objectResult); - Assert.Equal((int)HttpStatusCode.OK, objectResult.StatusCode); - Assert.Equal(value, objectResult.Value); - } + // Assert + Assert.True(result.IsSuccess); + Assert.Contains(message, result.Messages); + Assert.Equal(HttpStatusCode.OK, result.StatusCode); } -} \ No newline at end of file + + [Fact] + public void Result_BadRequest_ShouldReturnFailure() { + // Arrange + var message = "Invalid request"; + + // Act + var result = Result.BadRequest(message); + + // Assert + Assert.False(result.IsSuccess); + Assert.Contains(message, result.Messages); + Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); + } + + [Fact] + public void Result_Generic_Ok_ShouldReturnSuccessWithValue() { + // Arrange + var value = 42; + var message = "Operation successful"; + + // Act + var result = Result.Ok(value, message); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal(value, result.Value); + Assert.Contains(message, result.Messages); + Assert.Equal(HttpStatusCode.OK, result.StatusCode); + } + + [Fact] + public void Result_Generic_NotFound_ShouldReturnFailureWithNullValue() { + // Arrange + var message = "Resource not found"; + + // Act + var result = Result.NotFound(null, message); + + // Assert + Assert.False(result.IsSuccess); + Assert.Null(result.Value); + Assert.Contains(message, result.Messages); + Assert.Equal(HttpStatusCode.NotFound, result.StatusCode); + } + + [Fact] + public void Result_ToResultOfType_ShouldTransformValue() { + // Arrange + var initialValue = 42; + var transformedValue = "42"; + var result = Result.Ok(initialValue); + + // Act + var transformedResult = result.ToResultOfType(value => value.ToString()); + + // Assert + Assert.True(transformedResult.IsSuccess); + Assert.Equal(transformedValue, transformedResult.Value); + Assert.Equal(result.StatusCode, transformedResult.StatusCode); + } + + [Fact] + public void Result_ToActionResult_ShouldReturnStatusCodeResult() { + // Arrange + var result = Result.Ok("Operation successful"); + + // Act + var actionResult = result.ToActionResult(); + + // Assert + Assert.IsType(actionResult); + var statusCodeResult = actionResult as StatusCodeResult; + Assert.NotNull(statusCodeResult); + Assert.Equal((int)HttpStatusCode.OK, statusCodeResult.StatusCode); + } + + [Fact] + public void Result_ToActionResult_ShouldReturnObjectResultForFailure() { + // Arrange + var errorMessage = "An error occurred"; + var result = Result.BadRequest(errorMessage); + + // Act + var actionResult = result.ToActionResult(); + + // Assert + Assert.IsType(actionResult); + var objectResult = actionResult as ObjectResult; + Assert.NotNull(objectResult); + Assert.Equal((int)HttpStatusCode.BadRequest, objectResult.StatusCode); + Assert.IsType(objectResult.Value); + var problemDetails = objectResult.Value as ProblemDetails; + Assert.NotNull(problemDetails); + Assert.Equal((int)HttpStatusCode.BadRequest, problemDetails.Status); + Assert.Equal("An error occurred", problemDetails.Title); + Assert.Equal(errorMessage, problemDetails.Detail); + } + + [Fact] + public void Result_Generic_ToActionResult_ShouldReturnObjectResultWithValue() { + // Arrange + var value = new { Id = 1, Name = "Test" }; + var result = Result.Ok(value); + + // Act + var actionResult = result.ToActionResult(); + + // Assert + Assert.IsType(actionResult); + var objectResult = actionResult as ObjectResult; + Assert.NotNull(objectResult); + Assert.Equal((int)HttpStatusCode.OK, objectResult.StatusCode); + Assert.Equal(value, objectResult.Value); + } + + [Fact] + public async Task ObjectResult_ShouldSerializeToCamelCaseJson() { + // Arrange + var testObject = new TestPascalCase { FirstName = "John", LastName = "Doe" }; + var objectResult = new ObjectResult(testObject); + var context = new DefaultHttpContext(); + var memoryStream = new MemoryStream(); + context.Response.Body = memoryStream; + var actionContext = new ActionContext { + HttpContext = context + }; + + // Act + await objectResult.ExecuteResultAsync(actionContext); + + // Assert + memoryStream.Seek(0, SeekOrigin.Begin); + var json = await new StreamReader(memoryStream).ReadToEndAsync(); + Assert.Contains("\"firstName\"", json); + Assert.Contains("\"lastName\"", json); + Assert.DoesNotContain("\"FirstName\"", json); + Assert.DoesNotContain("\"LastName\"", json); + } + + private class TestPascalCase { + public string FirstName { get; set; } + public string LastName { get; set; } + } +} diff --git a/src/MaksIT.Results/MaksIT.Results.csproj b/src/MaksIT.Results/MaksIT.Results.csproj index 93db211..2722e1a 100644 --- a/src/MaksIT.Results/MaksIT.Results.csproj +++ b/src/MaksIT.Results/MaksIT.Results.csproj @@ -8,7 +8,7 @@ MaksIT.Results - 1.0.9 + 1.1.0 Maksym Sadovnychyy MAKS-IT MaksIT.Results diff --git a/src/MaksIT.Results/Mvc/ObjectResult.cs b/src/MaksIT.Results/Mvc/ObjectResult.cs index c3564b5..fc0c739 100644 --- a/src/MaksIT.Results/Mvc/ObjectResult.cs +++ b/src/MaksIT.Results/Mvc/ObjectResult.cs @@ -1,29 +1,34 @@ -using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Mvc; + namespace MaksIT.Results.Mvc; -public class ObjectResult : IActionResult { - public object? Value { get; } - public int? StatusCode { get; set; } +public class ObjectResult(object? value) : IActionResult { + private static readonly JsonSerializerOptions _jsonSerializerOptions = new() { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; - public ObjectResult(object? value) { - Value = value; - } + public object? Value { get; } = value; + public int? StatusCode { get; set; } public async Task ExecuteResultAsync(ActionContext context) { var response = context.HttpContext.Response; + if (StatusCode.HasValue) { response.StatusCode = StatusCode.Value; } + response.ContentType = "application/json"; + if (Value is not null) { - await JsonSerializer.SerializeAsync(response.Body, Value); + await JsonSerializer.SerializeAsync( + response.Body, + Value, + Value?.GetType() ?? typeof(object), + _jsonSerializerOptions + ); } } } \ No newline at end of file