Files
SIG-CM2.0/tests/SIGCM2.Application.Tests/Rubros/GetById/GetRubroByIdQueryHandlerTests.cs

168 lines
6.4 KiB
C#
Raw Normal View History

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);
}
}