From 8f8f2df0cd21b9d6319a93eb01e546eb40f04e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Huerta=20Garcia?= <95185284+hectorrhg@users.noreply.github.com> Date: Mon, 13 May 2024 14:34:15 -0400 Subject: [PATCH] Add Created.Result (#177) * Add Result.Created * add test for result constructor and result map * set IsSuccess in true when status is created --- src/Ardalis.Result/Result.cs | 28 ++++++++++++++- src/Ardalis.Result/ResultExtensions.cs | 3 ++ src/Ardalis.Result/ResultStatus.cs | 1 + .../ResultConstructor.cs | 29 +++++++++++++++- tests/Ardalis.Result.UnitTests/ResultMap.cs | 34 +++++++++++++++++++ 5 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/Ardalis.Result/Result.cs b/src/Ardalis.Result/Result.cs index b85611c..4f84791 100644 --- a/src/Ardalis.Result/Result.cs +++ b/src/Ardalis.Result/Result.cs @@ -42,12 +42,15 @@ protected Result(ResultStatus status) public Type ValueType => typeof(T); [JsonInclude] public ResultStatus Status { get; protected set; } = ResultStatus.Ok; - public bool IsSuccess => Status == ResultStatus.Ok; + + public bool IsSuccess => Status is ResultStatus.Ok or ResultStatus.Created; [JsonInclude] public string SuccessMessage { get; protected set; } = string.Empty; [JsonInclude] public string CorrelationId { get; protected set; } = string.Empty; [JsonInclude] + public string Location { get; protected set; } = string.Empty; + [JsonInclude] public IEnumerable Errors { get; protected set; } = []; [JsonInclude] public IEnumerable ValidationErrors { get; protected set; } = []; @@ -101,6 +104,29 @@ public static Result Success(T value, string successMessage) { return new Result(value, successMessage); } + + /// + /// Represents a successful operation that resulted in the creation of a new resource. + /// + /// The type of the resource created. + /// A Result with status Created. + public static Result Created(T value) + { + return new Result(ResultStatus.Created) { Value = value }; + } + + /// + /// Represents a successful operation that resulted in the creation of a new resource. + /// Sets the SuccessMessage property to the provided value. + /// + /// The type of the resource created. + /// The value of the resource created. + /// The URL indicating where the newly created resource can be accessed. + /// A Result with status Created. + public static Result Created(T value, string location) + { + return new Result(ResultStatus.Created) { Value = value, Location = location }; + } /// /// Represents an error that occurred during the execution of the service. diff --git a/src/Ardalis.Result/ResultExtensions.cs b/src/Ardalis.Result/ResultExtensions.cs index 6a27793..042c4b1 100644 --- a/src/Ardalis.Result/ResultExtensions.cs +++ b/src/Ardalis.Result/ResultExtensions.cs @@ -19,6 +19,9 @@ public static class ResultExtensions switch (result.Status) { case ResultStatus.Ok: return func(result); + case ResultStatus.Created: return string.IsNullOrEmpty(result.Location) + ? Result.Created(func(result.Value)) + : Result.Created(func(result.Value), result.Location); case ResultStatus.NotFound: return result.Errors.Any() ? Result.NotFound(result.Errors.ToArray()) : Result.NotFound(); diff --git a/src/Ardalis.Result/ResultStatus.cs b/src/Ardalis.Result/ResultStatus.cs index 750a06e..6ec26e4 100644 --- a/src/Ardalis.Result/ResultStatus.cs +++ b/src/Ardalis.Result/ResultStatus.cs @@ -3,6 +3,7 @@ public enum ResultStatus { Ok, + Created, Error, Forbidden, Unauthorized, diff --git a/tests/Ardalis.Result.UnitTests/ResultConstructor.cs b/tests/Ardalis.Result.UnitTests/ResultConstructor.cs index f695c56..fea584d 100644 --- a/tests/Ardalis.Result.UnitTests/ResultConstructor.cs +++ b/tests/Ardalis.Result.UnitTests/ResultConstructor.cs @@ -94,7 +94,34 @@ public void InitializesValueUsingGenericFactoryMethodAndSetsStatusToOkWithMessag Assert.Equal(value, result.Value); Assert.Equal(message, result.SuccessMessage); } - + + [Theory] + [InlineData(null)] + [InlineData(123)] + [InlineData("test value")] + public void InitializesStatusToCreatedAndSetLocationGivenCreatedFactoryCall(object value) + { + string location = "https://github.com/ardalis/Result"; + var result = Result.Created(value, location); + + Assert.Equal(ResultStatus.Created, result.Status); + Assert.Equal(location, result.Location); + Assert.True(result.IsSuccess); + } + + [Theory] + [InlineData(null)] + [InlineData(123)] + [InlineData("test value")] + public void InitializesStatusToCreatedGivenCreatedFactoryCall(object value) + { + var result = Result.Created(value); + + Assert.Equal(ResultStatus.Created, result.Status); + Assert.Equal(result.Location, string.Empty); + Assert.True(result.IsSuccess); + } + [Fact] public void InitializesStatusToErrorGivenErrorFactoryCall() { diff --git a/tests/Ardalis.Result.UnitTests/ResultMap.cs b/tests/Ardalis.Result.UnitTests/ResultMap.cs index 696c2ff..01d1588 100644 --- a/tests/Ardalis.Result.UnitTests/ResultMap.cs +++ b/tests/Ardalis.Result.UnitTests/ResultMap.cs @@ -42,6 +42,40 @@ public void ShouldProduceComplexTypeReturnValueFromSuccessWithMethod() actual.Value.Bar.Should().Be(foo.Bar); } + [Fact] + public void ShouldProduceReturnValueFromCreated() + { + int createdValue = 123; + var result = Result.Created(createdValue); + string expected = createdValue.ToString(); + + var actual = result.Map(val => val.ToString()); + + expected.Should().BeEquivalentTo(actual.Value); + } + + [Fact] + public void ShouldProduceComplexTypeReturnValueFromCreatedAnonymously() + { + var foo = new Foo("Bar"); + var result = Result.Created(foo); + + var actual = result.Map(foo => new FooDto(foo.Bar)); + + actual.Value.Bar.Should().Be(foo.Bar); + } + + [Fact] + public void ShouldProduceComplexTypeReturnValueFromCreatedWithMethod() + { + var foo = new Foo("Bar"); + var result = Result.Created(foo); + + var actual = result.Map(FooDto.CreateFromFoo); + + actual.Value.Bar.Should().Be(foo.Bar); + } + [Fact] public void ShouldProduceNotFound() {