UDT-011: Localización Temporal Argentina (infra transversal) #25
@@ -2,12 +2,13 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Serilog;
|
using Serilog;
|
||||||
using Scalar.AspNetCore;
|
using Scalar.AspNetCore;
|
||||||
using SIGCM2.Api.Authorization;
|
using SIGCM2.Api.Authorization;
|
||||||
|
using SIGCM2.Api.Filters;
|
||||||
using SIGCM2.Api.HealthChecks;
|
using SIGCM2.Api.HealthChecks;
|
||||||
|
using SIGCM2.Api.Json;
|
||||||
using SIGCM2.Api.Middleware;
|
using SIGCM2.Api.Middleware;
|
||||||
using SIGCM2.Application;
|
using SIGCM2.Application;
|
||||||
using SIGCM2.Infrastructure;
|
using SIGCM2.Infrastructure;
|
||||||
using SIGCM2.Infrastructure.Audit.Jobs;
|
using SIGCM2.Infrastructure.Audit.Jobs;
|
||||||
using SIGCM2.Api.Filters;
|
|
||||||
|
|
||||||
// Bootstrap logger — before DI is built
|
// Bootstrap logger — before DI is built
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
@@ -36,10 +37,15 @@ builder.Services.AddAuthorization();
|
|||||||
builder.Services.AddScoped<IAuthorizationHandler, PermissionAuthorizationHandler>();
|
builder.Services.AddScoped<IAuthorizationHandler, PermissionAuthorizationHandler>();
|
||||||
builder.Services.AddSingleton<IAuthorizationMiddlewareResultHandler, ForbiddenProblemDetailsHandler>();
|
builder.Services.AddSingleton<IAuthorizationMiddlewareResultHandler, ForbiddenProblemDetailsHandler>();
|
||||||
|
|
||||||
// Controllers with exception filter
|
// Controllers with exception filter + JSON options
|
||||||
|
// UDT-011: DateOnlyJsonConverter ensures Cat2 date fields serialize as "yyyy-MM-dd"
|
||||||
|
// and never as "2026-05-01T00:00:00" or with a UTC "Z" suffix.
|
||||||
builder.Services.AddControllers(opts =>
|
builder.Services.AddControllers(opts =>
|
||||||
{
|
{
|
||||||
opts.Filters.Add<ExceptionFilter>();
|
opts.Filters.Add<ExceptionFilter>();
|
||||||
|
}).AddJsonOptions(jsonOpts =>
|
||||||
|
{
|
||||||
|
jsonOpts.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
|
||||||
});
|
});
|
||||||
|
|
||||||
// OpenAPI / Scalar
|
// OpenAPI / Scalar
|
||||||
|
|||||||
@@ -693,4 +693,46 @@ public sealed class FiscalControllerTests : IAsyncLifetime
|
|||||||
Assert.True(json.TryGetProperty("items", out _), "Response must have 'items'");
|
Assert.True(json.TryGetProperty("items", out _), "Response must have 'items'");
|
||||||
Assert.True(json.TryGetProperty("total", out _), "Response must have 'total'");
|
Assert.True(json.TryGetProperty("total", out _), "Response must have 'total'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── UDT-011: DateOnly serialization format ────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [UDT-011 REQ-BE-JSON-001] POST /iva → vigenciaDesde en respuesta debe ser
|
||||||
|
/// "yyyy-MM-dd" (e.g. "2025-01-01"), no "2025-01-01T00:00:00" ni con sufijo "Z".
|
||||||
|
/// Valida que DateOnlyJsonConverter está activo en el pipeline de controllers.
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task CreateIva_VigenciaDesde_SerializesAsDateOnlyString()
|
||||||
|
{
|
||||||
|
const string codigo = "IVA_9999";
|
||||||
|
var token = await GetAdminTokenAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var req = BuildRequest(HttpMethod.Post, IvaEndpoint, new
|
||||||
|
{
|
||||||
|
codigo,
|
||||||
|
descripcion = "IVA DateOnly Format Test",
|
||||||
|
porcentaje = 5.0m,
|
||||||
|
aplicaIVA = true,
|
||||||
|
vigenciaDesde = "2025-01-01"
|
||||||
|
}, token);
|
||||||
|
var resp = await _client.SendAsync(req);
|
||||||
|
|
||||||
|
Assert.Equal(HttpStatusCode.Created, resp.StatusCode);
|
||||||
|
|
||||||
|
// Read raw JSON string to inspect format (not deserialized)
|
||||||
|
var rawJson = await resp.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
// vigenciaDesde MUST be "2025-01-01" — short date format
|
||||||
|
Assert.Contains("\"2025-01-01\"", rawJson);
|
||||||
|
|
||||||
|
// Must NOT contain datetime format or UTC suffix
|
||||||
|
Assert.DoesNotContain("T00:00:00", rawJson);
|
||||||
|
Assert.DoesNotContain("\"2025-01-01Z\"", rawJson);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await DeleteTipoDeIvaByCodigoAsync(codigo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user