cd8c78d165
CI - Build & Test / Backend (.NET) (push) Successful in 45s
CI - Build & Test / Backend integration (PostgreSQL/Toxiproxy) (push) Failing after 1m0s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m49s
CI - Build & Test / Security Check (push) Successful in 7s
CI - Build & Test / Deploy Nexus (push) Has been skipped
93 lines
3.3 KiB
C#
93 lines
3.3 KiB
C#
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Nexus.Api.Http;
|
|
using Xunit;
|
|
|
|
namespace Nexus.Api.Tests;
|
|
|
|
public sealed class ProblemDetailsContractTests
|
|
{
|
|
[Theory]
|
|
[InlineData(400, NexusProblemCodes.ValidationFailed)]
|
|
[InlineData(401, NexusProblemCodes.Unauthenticated)]
|
|
[InlineData(403, NexusProblemCodes.Forbidden)]
|
|
[InlineData(409, NexusProblemCodes.Conflict)]
|
|
[InlineData(429, NexusProblemCodes.RateLimited)]
|
|
[InlineData(503, NexusProblemCodes.DependencyUnavailable)]
|
|
[InlineData(504, NexusProblemCodes.Timeout)]
|
|
[InlineData(500, NexusProblemCodes.InternalError)]
|
|
public void Defaults_AddStableCodeAndTraceId(int status, string expectedCode)
|
|
{
|
|
var context = new DefaultHttpContext { TraceIdentifier = "trace-contract" };
|
|
var problem = new ProblemDetails { Status = status };
|
|
|
|
NexusProblemDetailsDefaults.Apply(problem, context);
|
|
|
|
Assert.Equal(expectedCode, problem.Extensions["code"]);
|
|
Assert.Equal("trace-contract", problem.Extensions["traceId"]);
|
|
Assert.False(string.IsNullOrWhiteSpace(problem.Title));
|
|
Assert.False(string.IsNullOrWhiteSpace(problem.Type));
|
|
}
|
|
|
|
[Fact]
|
|
public void Defaults_PreserveExplicitMachineCode()
|
|
{
|
|
var context = new DefaultHttpContext { TraceIdentifier = "trace-contract" };
|
|
var problem = new ProblemDetails { Status = 409 };
|
|
problem.Extensions["code"] = "config_hash_conflict";
|
|
|
|
NexusProblemDetailsDefaults.Apply(problem, context);
|
|
|
|
Assert.Equal("config_hash_conflict", problem.Extensions["code"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void LegacyError_IsConvertedWithoutLosingTheStableContract()
|
|
{
|
|
var context = new DefaultHttpContext { TraceIdentifier = "trace-legacy" };
|
|
|
|
var problem = NexusProblemDetailsDefaults.FromLegacyError(
|
|
new { error = "Task not found." },
|
|
StatusCodes.Status404NotFound,
|
|
context);
|
|
|
|
Assert.NotNull(problem);
|
|
Assert.Equal("Task not found.", problem.Detail);
|
|
Assert.Equal(NexusProblemCodes.NotFound, problem.Extensions["code"]);
|
|
Assert.Equal("trace-legacy", problem.Extensions["traceId"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void LegacySuccessPayload_IsNotConverted()
|
|
{
|
|
var context = new DefaultHttpContext();
|
|
|
|
var problem = NexusProblemDetailsDefaults.FromLegacyError(
|
|
new { error = "informational field" },
|
|
StatusCodes.Status200OK,
|
|
context);
|
|
|
|
Assert.Null(problem);
|
|
}
|
|
|
|
[Fact]
|
|
public void SharedResult_UsesProblemJsonAndPreservesTypedExtensions()
|
|
{
|
|
var result = NexusHttpResults.Problem(
|
|
StatusCodes.Status409Conflict,
|
|
"The agent file changed.",
|
|
extensions: new Dictionary<string, object?>
|
|
{
|
|
["currentHash"] = "hash-current"
|
|
});
|
|
|
|
Assert.Equal(
|
|
"application/problem+json",
|
|
Assert.IsAssignableFrom<IContentTypeHttpResult>(result).ContentType);
|
|
var problem = Assert.IsType<ProblemDetails>(
|
|
Assert.IsAssignableFrom<IValueHttpResult>(result).Value);
|
|
Assert.Equal(NexusProblemCodes.Conflict, problem.Extensions["code"]);
|
|
Assert.Equal("hash-current", problem.Extensions["currentHash"]);
|
|
}
|
|
}
|