test(application): GetRubroByIdQueryHandlerTests dedicado (CAT-001)
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using NSubstitute;
|
||||
using SIGCM2.Application.Abstractions.Persistence;
|
||||
using SIGCM2.Application.Rubros.GetById;
|
||||
using SIGCM2.Domain.Entities;
|
||||
using SIGCM2.Domain.Exceptions;
|
||||
|
||||
namespace SIGCM2.Application.Tests.Rubros.GetById;
|
||||
|
||||
public class GetRubroByIdQueryHandlerTests
|
||||
{
|
||||
private static readonly FakeTimeProvider FakeTime =
|
||||
new(new DateTimeOffset(2026, 4, 18, 12, 0, 0, TimeSpan.Zero));
|
||||
|
||||
private readonly IRubroRepository _repo = Substitute.For<IRubroRepository>();
|
||||
|
||||
private static DateTime UtcNow => FakeTime.GetUtcNow().UtcDateTime;
|
||||
|
||||
private static Rubro MakeRubro(
|
||||
int id,
|
||||
int? parentId = null,
|
||||
bool activo = true,
|
||||
int? tarifarioBaseId = null,
|
||||
DateTime? fechaModificacion = null)
|
||||
=> new(id, parentId, $"Rubro{id}", orden: 1, activo, tarifarioBaseId,
|
||||
fechaCreacion: UtcNow, fechaModificacion);
|
||||
|
||||
// ── Handle_RubroExiste_ActivoPorDefecto_RetornaDto ───────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_RubroExiste_ActivoPorDefecto_RetornaDto()
|
||||
{
|
||||
var rubro = MakeRubro(id: 5, parentId: 2, tarifarioBaseId: 10);
|
||||
_repo.GetByIdAsync(5, Arg.Any<CancellationToken>()).Returns(rubro);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var result = await handler.Handle(new GetRubroByIdQuery(Id: 5));
|
||||
|
||||
result.Should().NotBeNull();
|
||||
result.Id.Should().Be(5);
|
||||
result.Nombre.Should().Be("Rubro5");
|
||||
result.ParentId.Should().Be(2);
|
||||
result.Orden.Should().Be(1);
|
||||
result.Activo.Should().BeTrue();
|
||||
result.TarifarioBaseId.Should().Be(10);
|
||||
result.FechaCreacion.Should().Be(UtcNow);
|
||||
result.FechaModificacion.Should().BeNull();
|
||||
}
|
||||
|
||||
// ── Handle_RubroNoExiste_LanzaRubroNotFoundException ────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_RubroNoExiste_LanzaRubroNotFoundException()
|
||||
{
|
||||
_repo.GetByIdAsync(99, Arg.Any<CancellationToken>()).Returns((Rubro?)null);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var act = () => handler.Handle(new GetRubroByIdQuery(Id: 99));
|
||||
|
||||
await act.Should().ThrowAsync<RubroNotFoundException>()
|
||||
.WithMessage("*99*");
|
||||
}
|
||||
|
||||
// ── Handle_RubroNotFoundException_ContienIdCorrecto ─────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_RubroNotFoundException_ContieneIdCorrecto()
|
||||
{
|
||||
_repo.GetByIdAsync(42, Arg.Any<CancellationToken>()).Returns((Rubro?)null);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
|
||||
var ex = await Assert.ThrowsAsync<RubroNotFoundException>(
|
||||
() => handler.Handle(new GetRubroByIdQuery(Id: 42)));
|
||||
|
||||
ex.Id.Should().Be(42);
|
||||
}
|
||||
|
||||
// ── Handle_CancellationToken_SePropagaAlRepo ─────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_CancellationToken_SePropagaAlRepo()
|
||||
{
|
||||
// The handler signature accepts CancellationToken and forwards it to the repo.
|
||||
// We verify the repo is called exactly once with the matching id and any token.
|
||||
_repo.GetByIdAsync(7, Arg.Any<CancellationToken>()).Returns(MakeRubro(7));
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
await handler.Handle(new GetRubroByIdQuery(Id: 7));
|
||||
|
||||
await _repo.Received(1).GetByIdAsync(7, Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
// ── Handle_FechaCreacion_SeSerializaComoInstantUTC ───────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_FechaCreacion_SeSerializaComoInstantUTC()
|
||||
{
|
||||
var expectedUtc = new DateTime(2026, 1, 15, 8, 30, 0, DateTimeKind.Utc);
|
||||
var rubro = new Rubro(3, null, "RubroUTC", 0, true, null, expectedUtc, null);
|
||||
_repo.GetByIdAsync(3, Arg.Any<CancellationToken>()).Returns(rubro);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var result = await handler.Handle(new GetRubroByIdQuery(Id: 3));
|
||||
|
||||
result.FechaCreacion.Should().Be(expectedUtc);
|
||||
result.FechaCreacion.Kind.Should().Be(DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
// ── Handle_FechaModificacion_Null_SeRetornaNull ──────────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_FechaModificacion_Null_SeRetornaNull()
|
||||
{
|
||||
var rubro = MakeRubro(id: 8, fechaModificacion: null);
|
||||
_repo.GetByIdAsync(8, Arg.Any<CancellationToken>()).Returns(rubro);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var result = await handler.Handle(new GetRubroByIdQuery(Id: 8));
|
||||
|
||||
result.FechaModificacion.Should().BeNull();
|
||||
}
|
||||
|
||||
// ── Handle_FechaModificacion_ConValor_SeRetornaCorrecto ──────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_FechaModificacion_ConValor_SeRetornaCorrecto()
|
||||
{
|
||||
var fechaMod = new DateTime(2026, 3, 10, 10, 0, 0, DateTimeKind.Utc);
|
||||
var rubro = MakeRubro(id: 9, fechaModificacion: fechaMod);
|
||||
_repo.GetByIdAsync(9, Arg.Any<CancellationToken>()).Returns(rubro);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var result = await handler.Handle(new GetRubroByIdQuery(Id: 9));
|
||||
|
||||
result.FechaModificacion.Should().Be(fechaMod);
|
||||
}
|
||||
|
||||
// ── Handle_RubroRaiz_SinParent_RetornaDtoConParentIdNull ─────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_RubroRaiz_SinParent_RetornaDtoConParentIdNull()
|
||||
{
|
||||
var rubro = MakeRubro(id: 1, parentId: null);
|
||||
_repo.GetByIdAsync(1, Arg.Any<CancellationToken>()).Returns(rubro);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var result = await handler.Handle(new GetRubroByIdQuery(Id: 1));
|
||||
|
||||
result.ParentId.Should().BeNull();
|
||||
}
|
||||
|
||||
// ── Handle_RubroConTarifarioBaseId_SeRetornaCorrecto ────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_RubroConTarifarioBaseId_SeRetornaCorrecto()
|
||||
{
|
||||
var rubro = MakeRubro(id: 11, tarifarioBaseId: 42);
|
||||
_repo.GetByIdAsync(11, Arg.Any<CancellationToken>()).Returns(rubro);
|
||||
|
||||
var handler = new GetRubroByIdQueryHandler(_repo);
|
||||
var result = await handler.Handle(new GetRubroByIdQuery(Id: 11));
|
||||
|
||||
result.TarifarioBaseId.Should().Be(42);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user