Skip to content

Commit

Permalink
Add Created.Result (#177)
Browse files Browse the repository at this point in the history
* Add Result.Created

* add test for result constructor and result map

* set IsSuccess in true when status is created
  • Loading branch information
sunecko committed May 13, 2024
1 parent 0e50578 commit 8f8f2df
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 2 deletions.
28 changes: 27 additions & 1 deletion src/Ardalis.Result/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> Errors { get; protected set; } = [];
[JsonInclude]
public IEnumerable<ValidationError> ValidationErrors { get; protected set; } = [];
Expand Down Expand Up @@ -101,6 +104,29 @@ public static Result<T> Success(T value, string successMessage)
{
return new Result<T>(value, successMessage);
}

/// <summary>
/// Represents a successful operation that resulted in the creation of a new resource.
/// </summary>
/// <typeparam name="T">The type of the resource created.</typeparam>
/// <returns>A Result<typeparamref name="T"/> with status Created.</returns>
public static Result<T> Created(T value)
{
return new Result<T>(ResultStatus.Created) { Value = value };
}

/// <summary>
/// Represents a successful operation that resulted in the creation of a new resource.
/// Sets the SuccessMessage property to the provided value.
/// </summary>
/// <typeparam name="T">The type of the resource created.</typeparam>
/// <param name="value">The value of the resource created.</param>
/// <param name="location">The URL indicating where the newly created resource can be accessed.</param>
/// <returns>A Result<typeparamref name="T"/> with status Created.</returns>
public static Result<T> Created(T value, string location)
{
return new Result<T>(ResultStatus.Created) { Value = value, Location = location };
}

/// <summary>
/// Represents an error that occurred during the execution of the service.
Expand Down
3 changes: 3 additions & 0 deletions src/Ardalis.Result/ResultExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TDestination>.Created(func(result.Value))
: Result<TDestination>.Created(func(result.Value), result.Location);
case ResultStatus.NotFound: return result.Errors.Any()
? Result<TDestination>.NotFound(result.Errors.ToArray())
: Result<TDestination>.NotFound();
Expand Down
1 change: 1 addition & 0 deletions src/Ardalis.Result/ResultStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
public enum ResultStatus
{
Ok,
Created,
Error,
Forbidden,
Unauthorized,
Expand Down
29 changes: 28 additions & 1 deletion tests/Ardalis.Result.UnitTests/ResultConstructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<object>.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<object>.Created(value);

Assert.Equal(ResultStatus.Created, result.Status);
Assert.Equal(result.Location, string.Empty);
Assert.True(result.IsSuccess);
}

[Fact]
public void InitializesStatusToErrorGivenErrorFactoryCall()
{
Expand Down
34 changes: 34 additions & 0 deletions tests/Ardalis.Result.UnitTests/ResultMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,40 @@ public void ShouldProduceComplexTypeReturnValueFromSuccessWithMethod()
actual.Value.Bar.Should().Be(foo.Bar);
}

[Fact]
public void ShouldProduceReturnValueFromCreated()
{
int createdValue = 123;
var result = Result<int>.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<Foo>.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<Foo>.Created(foo);

var actual = result.Map(FooDto.CreateFromFoo);

actual.Value.Bar.Should().Be(foo.Bar);
}

[Fact]
public void ShouldProduceNotFound()
{
Expand Down

0 comments on commit 8f8f2df

Please sign in to comment.