mishima-nexus-client-csharp/tests/Robotico.Nexus.Client.Tests/NexusWireStatusTests.cs

116 lines
4.1 KiB
C#
Raw Permalink Normal View History

using Grpc.Core;
using Mishima.Nexus.Wire.V1;
using Robotico.Result.Errors;
using Xunit;
namespace Robotico.Nexus.Client.Tests;
public class NexusWireStatusTests
{
[Fact]
public void ToResult_Succeeds_WhenStatusIsOk()
{
Robotico.Result.Result result = NexusWireStatus.ToResult(new NexusStatus { Code = "OK" });
Assert.True(result.IsSuccess());
}
[Fact]
public void ToResult_Fails_WhenStatusIsNull()
{
Robotico.Result.Result result = NexusWireStatus.ToResult((NexusStatus?)null);
Assert.True(result.IsError(out IError? error));
Assert.Equal(NexusErrors.WireFailed, error!.Code);
}
[Fact]
public void ToResult_Fails_WithCodeAndMessage_FromStatus()
{
Robotico.Result.Result result = NexusWireStatus.ToResult(new NexusStatus { Code = "NXS_FOO", Message = "boom" });
Assert.True(result.IsError(out IError? error));
Assert.Equal("NXS_FOO", error!.Code);
Assert.Equal("boom", error.Message);
}
[Fact]
public void ToResult_Fails_WithFallbackCodeAndMessage_WhenBlank()
{
Robotico.Result.Result result = NexusWireStatus.ToResult(new NexusStatus { Code = string.Empty, Message = string.Empty });
Assert.True(result.IsError(out IError? error));
Assert.Equal(NexusErrors.WireFailed, error!.Code);
Assert.Equal("Nexus call failed.", error.Message);
}
[Fact]
public void ToResultGeneric_CarriesValue_OnSuccess()
{
Robotico.Result.Result<int> result = NexusWireStatus.ToResult(new NexusStatus { Code = "OK" }, 42);
Assert.True(result.IsSuccess(out int value, out _));
Assert.Equal(42, value);
}
[Fact]
public void ToResultGeneric_PropagatesError_OnFailure()
{
Robotico.Result.Result<int> result = NexusWireStatus.ToResult(new NexusStatus { Code = "NXS_BAD", Message = "bad" }, 42);
Assert.True(result.IsError(out IError? error));
Assert.Equal("NXS_BAD", error!.Code);
}
[Fact]
public void IsOk_True_ForOkStatus()
{
Assert.True(NexusWireStatus.IsOk(new NexusStatus { Code = "OK" }));
}
[Fact]
public void IsOk_False_ForNullOrNonOkStatus()
{
Assert.False(NexusWireStatus.IsOk(null));
Assert.False(NexusWireStatus.IsOk(new NexusStatus { Code = "NXS_BAD" }));
}
[Theory]
[InlineData(StatusCode.OK, NexusErrors.WireFailed)]
[InlineData(StatusCode.Cancelled, NexusErrors.Unavailable)]
[InlineData(StatusCode.Unknown, NexusErrors.WireFailed)]
[InlineData(StatusCode.InvalidArgument, NexusErrors.InvalidArgument)]
[InlineData(StatusCode.DeadlineExceeded, NexusErrors.Unavailable)]
[InlineData(StatusCode.NotFound, NexusErrors.NotFound)]
[InlineData(StatusCode.AlreadyExists, NexusErrors.AlreadyExists)]
[InlineData(StatusCode.PermissionDenied, NexusErrors.WireFailed)]
[InlineData(StatusCode.ResourceExhausted, NexusErrors.Unavailable)]
[InlineData(StatusCode.FailedPrecondition, NexusErrors.InvalidArgument)]
[InlineData(StatusCode.Aborted, NexusErrors.WireFailed)]
[InlineData(StatusCode.OutOfRange, NexusErrors.InvalidArgument)]
[InlineData(StatusCode.Unimplemented, NexusErrors.WireFailed)]
[InlineData(StatusCode.Internal, NexusErrors.WireFailed)]
[InlineData(StatusCode.Unavailable, NexusErrors.Unavailable)]
[InlineData(StatusCode.DataLoss, NexusErrors.WireFailed)]
[InlineData(StatusCode.Unauthenticated, NexusErrors.WireFailed)]
public void FromException_MapsEveryGrpcStatusCode(StatusCode statusCode, string expectedCode)
{
RpcException exception = new(new Status(statusCode, "detail message"));
IError error = NexusWireStatus.FromException(exception);
Assert.Equal(expectedCode, error.Code);
Assert.Contains("detail message", error.Message, StringComparison.Ordinal);
}
[Fact]
public void FromException_FallsBackTo_ExceptionMessage_WhenDetailBlank()
{
RpcException exception = new(new Status(StatusCode.Internal, string.Empty));
IError error = NexusWireStatus.FromException(exception);
Assert.Contains(exception.Message, error.Message, StringComparison.Ordinal);
}
}