using System; using System.Threading.Tasks; using System.Collections.Generic; using Xunit; using Moq; using ComplianceNFs.Core.Application.Services; using ComplianceNFs.Core.Ports; using ComplianceNFs.Core.Entities; using ComplianceNFs.Infrastructure.Repositories; using Microsoft.Extensions.Logging; namespace ComplianceNFs.Infrastructure.Tests { public class MatchingServiceTests { [Fact] public async Task MatchAsync_SetsMatchedStatus_WhenSingleRecordMatches() { // Arrange var invoice = new EnergyInvoice { CnpjComp = "02696252000122", CnpjVend = "06981176000158", MontNF = 19.845m, PrecNF = 248.76m, MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 359630, Filename = "f.xml" }; var CaminhoDB = "X:\\Middle\\Informativo Setorial\\Modelo Word\\BD1_dados cadastrais e faturas.accdb"; var repo = new AccessDbRepository(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21"); // Act var result = repo.GetByCnpj(invoice.CnpjComp); var mockLogger = new Mock>(); var service = new MatchingService(repo, mockLogger.Object); // Act await service.MatchAsync(invoice); // Debug output System.Diagnostics.Debug.WriteLine($"Invoice status after match: {invoice.Status}"); // Assert Assert.Equal(result.First().CnpjComp, invoice.CnpjComp); Assert.Equal(result.First().CnpjVend, invoice.CnpjVend); Assert.Equal(result.First().MontLO, invoice.MontNF); Assert.Equal(result.First().PrecLO, invoice.PrecNF); Assert.Equal(InvoiceStatus.Matched, invoice.Status); Assert.Equal(240712110001250501, (Int64)invoice.MatchedCodTE!); } [Fact] public async Task MatchAsync_SetsFallbackMatched_WhenSumOfTwoRecordsMatches() { var mockRepo = new Mock(); var mockLogger = new Mock>(); var invoice = new EnergyInvoice { CnpjComp = "123", CnpjVend = "456", MontNF = 300, PrecNF = 600, MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 1, Filename = "f.xml" }; var records = new List { new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 100, PrecLO = 200, CodTE = 1 }, new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 200, PrecLO = 400, CodTE = 2 } }; mockRepo.Setup(r => r.GetByCnpj("123")).Returns(records); var service = new MatchingService(mockRepo.Object, mockLogger.Object); await service.MatchAsync(invoice); Assert.Equal(InvoiceStatus.FallbackMatched, invoice.Status); Assert.Equal(1, invoice.MatchedCodTE); // or null, depending on your logic Assert.Contains("Matched by sum", invoice.DiscrepancyNotes); } [Fact] public async Task MatchAsync_SetsNotFound_WhenNoMatch() { // Arrange var mockRepo = new Mock(); var mockLogger = new Mock>(); var invoice = new EnergyInvoice { CnpjComp = "123", CnpjVend = "456", MontNF = 999, PrecNF = 999, MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 1, Filename = "f.xml" }; var records = new List { new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 100, PrecLO = 200, CodTE = 1 }, new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 200, PrecLO = 400, CodTE = 2 } }; mockRepo.Setup(r => r.GetByCnpj("123")).Returns(records); var service = new MatchingService(mockRepo.Object, mockLogger.Object); // Act await service.MatchAsync(invoice); // Assert Assert.Equal(InvoiceStatus.NotFound, invoice.Status); Assert.Null(invoice.MatchedCodTE); } } public class ComplianceServiceTests { [Fact] public async Task ValidateAsync_SetsValidated_WhenTaxMatches() { var service = new ComplianceService(); var invoice = new EnergyInvoice { MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 1, Filename = "f.xml", Status = InvoiceStatus.Matched, ValorSemImpostos = 100, ValorFinalComImpostos = 125m, IcmsNF = 0.2m, // implied tax = 0.1 }; await service.ValidateAsync(invoice); // Debug output System.Diagnostics.Debug.WriteLine($"Invoice status after validate: {invoice.Status}"); Assert.Null(invoice.DiscrepancyNotes); Assert.Equal(InvoiceStatus.Validated, invoice.Status); } [Fact] public async Task ValidateAsync_SetsTaxMismatch_WhenTaxDiffers() { // Arrange var invoice = new EnergyInvoice { MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 1, Filename = "f.xml", IcmsNF = 100, Status = InvoiceStatus.Matched }; var service = new ComplianceService(); // Act invoice.IcmsNF = 100; invoice.ValorFinalComImpostos = 110; invoice.ValorSemImpostos = 100; await service.ValidateAsync(invoice); // Assert Assert.Equal(InvoiceStatus.TaxMismatch, invoice.Status); } } public class NotificationServiceTests { [Fact] public async Task NotifyAsync_WritesToConsole() { // Arrange var invoice = new EnergyInvoice { MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 1, Filename = "f.xml", Status = InvoiceStatus.Validated }; var service = new NotificationService(); // Act & Assert var ex = await Record.ExceptionAsync(() => service.NotifyAsync(invoice, "Test message")); Assert.Null(ex); // Should not throw } } }