using NSubstitute; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Application.Audit; using SIGCM2.Application.IngresosBrutos.Update; using SIGCM2.Domain.Exceptions; using SIGCM2.Domain.Fiscal; using IibbEntity = SIGCM2.Domain.Entities.IngresosBrutos; namespace SIGCM2.Application.Tests.IngresosBrutos.Update; public class UpdateIngresosBrutosCommandHandlerTests { private readonly IIngresosBrutosRepository _repo = Substitute.For(); private readonly IAuditLogger _audit = Substitute.For(); private readonly UpdateIngresosBrutosCommandHandler _handler; private static IibbEntity MakeEntity(int id = 1) => IibbEntity.FromDb( id: id, provincia: ProvinciaArgentina.BuenosAires, descripcion: "IIBB BA", alicuota: 3m, activo: true, vigenciaDesde: new DateOnly(2024, 1, 1), vigenciaHasta: null, predecesorId: null, fechaCreacion: DateTime.UtcNow, fechaModificacion: null); private static UpdateIngresosBrutosCommand ValidCommand(int id = 1) => new( Id: id, Descripcion: "IIBB BA actualizado", Activo: true); public UpdateIngresosBrutosCommandHandlerTests() { _handler = new UpdateIngresosBrutosCommandHandler(_repo, _audit); _repo.GetByIdAsync(1, Arg.Any()).Returns(MakeEntity()); _repo.UpdateCosmeticoAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()).Returns(true); } [Fact] public async Task Handle_NotFound_ThrowsIngresosBrutosNotFoundException() { _repo.GetByIdAsync(99, Arg.Any()).Returns((IibbEntity?)null); await Assert.ThrowsAsync( () => _handler.Handle(ValidCommand(99))); } [Fact] public async Task Handle_HappyPath_ReturnsDtoWithUpdatedDescription() { var result = await _handler.Handle(ValidCommand()); Assert.Equal("IIBB BA actualizado", result.Descripcion); } [Fact] public async Task Handle_HappyPath_CallsUpdateCosmeticoOnce() { await _handler.Handle(ValidCommand()); await _repo.Received(1).UpdateCosmeticoAsync( 1, "IIBB BA actualizado", true, Arg.Any()); } [Fact] public async Task Handle_HappyPath_CallsAuditWithUpdateAction() { await _handler.Handle(ValidCommand()); await _audit.Received(1).LogAsync( action: "ingresos_brutos.update", targetType: "IngresosBrutos", targetId: "1", metadata: Arg.Any(), ct: Arg.Any()); } [Fact] public async Task Handle_AuditLoggerThrows_ExceptionBubblesUp() { _audit.LogAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(Task.FromException(new InvalidOperationException("audit fail"))); await Assert.ThrowsAsync( () => _handler.Handle(ValidCommand())); } }