using System; using System.Threading.Tasks; using System.Linq; using Moq; using NUnit.Framework; using LCU.API.Internal.DocumentIngestor.Services; using LCU.Library.Internal.DocumentIngestorModels.Entities; using LCU.Library.Internal.DocumentIngestorModels.Enums; using LCU.API.Internal.DocumentIngestor.Configurations; using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices; using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices; using LCU.Library.DocumentType.Models.Responses.External; using LCU.Library.Internal.ApiResponse.Models; using LCU.Library.Internal.Exceptions; using Serilog; using System.Collections.Generic; namespace LCU.API.Internal.DocumentIngestorTests.Services; public class UploadCompletionReprocessingServiceTest { private UploadCompletionReprocessingService _uploadCompletionReprocessingService; private Mock _mockIngestorRunInfoService; private Mock _mockDocumentProcessingInfoService; private Mock _mockUploadCompletionService; private Mock _mockDocumentTypeRetrieverService; private ApiConfiguration _apiConfiguration; private readonly Mock _logger = new(); private readonly ILogger _originalLogger = Log.Logger; [SetUp] public void Setup() { Log.Logger = _logger.Object; _mockIngestorRunInfoService = new Mock(); _mockDocumentProcessingInfoService = new Mock(); _mockDocumentTypeRetrieverService = new Mock(); _mockUploadCompletionService = new Mock(); _apiConfiguration = new ApiConfiguration(); _uploadCompletionReprocessingService = new UploadCompletionReprocessingService(_mockIngestorRunInfoService.Object, _mockDocumentProcessingInfoService.Object, _mockDocumentTypeRetrieverService.Object, _mockUploadCompletionService.Object, _apiConfiguration); } [TearDown] public void TearDown() { Log.Logger = _originalLogger; } [Test] public async Task QueueReprocessUploadCompletionByDocumentProcessingInfoId_Success() { var documentProcessingInfoId = DateTime.Now.Millisecond; var userName = Guid.NewGuid().ToString(); var documentProcessingInfo = SetupGetDocumentProcessingInfo(documentProcessingInfoId); var ingestorRunInfo = SetupGetIngestorRunInfo(documentProcessingInfo.IngestorRunInfoId); SetupDocumentInformation(documentProcessingInfo.DocumentId); _mockDocumentProcessingInfoService.Setup(x => x.UpdateStatusAndAddLog(documentProcessingInfoId, documentProcessingInfo.StatusType, It.IsAny(), userName, It.IsAny())).ReturnsAsync(documentProcessingInfo); await _uploadCompletionReprocessingService.QueueReprocessUploadCompletionByDocumentProcessingInfoId(documentProcessingInfoId, userName); _mockDocumentProcessingInfoService.Verify(x => x.GetByIdAsync(documentProcessingInfoId), Times.Once); _mockIngestorRunInfoService.Verify(x => x.GetByIdAsync(ingestorRunInfo.IngestorRunInfoId), Times.Once); _mockDocumentTypeRetrieverService.Verify(x => x.GetDocumentInformationById(documentProcessingInfo.DocumentId ?? Guid.Empty), Times.Once); _mockDocumentProcessingInfoService.Verify(x => x.UpdateStatusAndAddLog(documentProcessingInfoId, It.IsAny(), It.IsAny(), userName, It.IsAny()), Times.Once); _mockUploadCompletionService.Verify(x => x.HandleUploadCompletion(It.IsAny>()), Times.Once); } [Test] public void QueueReprocessUploadCompletionByDocumentProcessingInfoId_Failure_Exception() { var id = DateTime.Now.Millisecond; var userName = Guid.NewGuid().ToString(); _mockDocumentProcessingInfoService.Setup(x => x.GetByIdAsync(id)).ThrowsAsync(new Exception("Test Error")); Assert.ThrowsAsync(async () => await _uploadCompletionReprocessingService .QueueReprocessUploadCompletionByDocumentProcessingInfoId(id, userName)); _mockDocumentProcessingInfoService.Verify(x => x.GetByIdAsync(It.IsAny()), Times.Once); _mockIngestorRunInfoService.Verify(x => x.GetByIdAsync(It.IsAny()), Times.Never); _mockDocumentTypeRetrieverService.Verify(x => x.GetDocumentInformationById(It.IsAny()), Times.Never); _mockDocumentProcessingInfoService.Verify(x => x.UpdateStatusAndAddLog(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); _mockUploadCompletionService.Verify(x => x.HandleUploadCompletion(It.IsAny>()), Times.Never); } [Test] public void QueueReprocessUploadCompletionByDocumentProcessingInfoId_Failure_ArgumentNullException() { var id = DateTime.Now.Millisecond; var userName = Guid.NewGuid().ToString(); _mockDocumentProcessingInfoService.Setup(x => x.GetByIdAsync(id)).ThrowsAsync(new ArgumentNullException("Test Error")); Assert.ThrowsAsync(async () => await _uploadCompletionReprocessingService .QueueReprocessUploadCompletionByDocumentProcessingInfoId(id, userName)); _mockDocumentProcessingInfoService.Verify(x => x.GetByIdAsync(id), Times.Once); _mockIngestorRunInfoService.Verify(x => x.GetByIdAsync(It.IsAny()), Times.Never); _mockDocumentProcessingInfoService.Verify(x => x.UpdateStatusAndAddLog(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); _mockUploadCompletionService.Verify(x => x.HandleUploadCompletion(It.IsAny>()), Times.Never); } [Test] public void QueueReprocessAllNotificationDataFailures_InfoServiceThrowsArgumentNull_ThrowsServiceException() { var processStatus = ProcessStatusTypes.NotificationDataFailure; _mockDocumentProcessingInfoService .Setup(s => s.GetByProcessStatusTypeAsync(processStatus, null)) .ThrowsAsync(new ArgumentNullException()); Assert.ThrowsAsync(() => _uploadCompletionReprocessingService.QueueReprocessAllNotificationDataFailures(Guid.NewGuid().ToString())); } [Test] public async Task QueueReprocessAllNotificationDataFailures_InfoServiceThrows_ThrowsServiceException() { var processStatus = ProcessStatusTypes.NotificationDataFailure; _mockDocumentProcessingInfoService .Setup(s => s.GetByProcessStatusTypeAsync(processStatus, null)) .ThrowsAsync(new Exception()); Assert.ThrowsAsync(() => _uploadCompletionReprocessingService.QueueReprocessAllNotificationDataFailures(Guid.NewGuid().ToString())); } [Test] public async Task QueueReprocessAllNotificationDataFailures_InfoServiceReturnsMoreThanLimit_RequeuesUpToLimit() { var id = DateTime.Now.Millisecond; var username = Guid.NewGuid().ToString(); var notificationDataFailures = Enumerable .Repeat(() => SetupGetDocumentProcessingInfo(id), 16) .Select(f => f()) .ToArray(); foreach (var info in notificationDataFailures) { SetupGetIngestorRunInfo(info.IngestorRunInfoId); SetupDocumentInformation(info.DocumentId); } var processStatus = ProcessStatusTypes.NotificationDataFailure; _apiConfiguration.NotificationDataFailureReprocessLimit = notificationDataFailures.Length / 2; _mockDocumentProcessingInfoService .Setup(s => s.GetByProcessStatusTypeAsync(processStatus, null)) .ReturnsAsync(notificationDataFailures); await _uploadCompletionReprocessingService.QueueReprocessAllNotificationDataFailures(username); _mockDocumentProcessingInfoService .Verify ( s => s.UpdateStatusAndAddLog ( It.Is(id => notificationDataFailures.Any(f => f.DocumentProcessingInfoId == id)), ProcessStatusTypes.UploadCompletionReprocessing, It.IsAny(), username, It.IsAny() ), Times.Exactly(_apiConfiguration.NotificationDataFailureReprocessLimit) ); _mockUploadCompletionService .Verify ( dp => dp.HandleUploadCompletion ( It.IsAny>() ), Times.Exactly(_apiConfiguration.NotificationDataFailureReprocessLimit) ); } private DocumentProcessingInfo SetupGetDocumentProcessingInfo(int id) { var info = new DocumentProcessingInfo { IngestorRunInfoId = Guid.NewGuid(), CreatedDate = DateTime.Now, DocumentValuePayload = Guid.NewGuid().ToString(), StatusType = Random(), DocumentFileName = Guid.NewGuid().ToString(), ProcessCount = DateTime.Now.Millisecond, DocumentType = "EAgreement", DocumentBusinessName = Guid.NewGuid().ToString(), DocumentProcessingInfoId = id, DocumentId = Guid.NewGuid() }; _mockDocumentProcessingInfoService .Setup(s => s.GetByIdAsync(id)) .ReturnsAsync(info); return info; } private IngestorRunInfo SetupGetIngestorRunInfo(Guid ingestorRunInfoId) { var info = new IngestorRunInfo { IngestorRunInfoId = ingestorRunInfoId, StartTimeStamp = DateTime.Now, IngestorType = Random(), IndexFileName = Guid.NewGuid().ToString(), IndexFilePath = Guid.NewGuid().ToString(), IndexTotal = DateTime.Now.Millisecond }; _mockIngestorRunInfoService .Setup(s => s.GetByIdAsync(ingestorRunInfoId)) .ReturnsAsync(info); return info; } private EnrichedDocumentMetadataResponse SetupDocumentInformation(Guid? documentId) { var info = new EnrichedDocumentMetadataResponse() { DocumentId = documentId ?? Guid.Empty, Type = "LnNent", PersonNumbers = new[] { "123" }, AccountNumber = 345 }; _mockDocumentTypeRetrieverService .Setup(s => s.GetDocumentInformationById(documentId ?? Guid.Empty)) .ReturnsAsync(info); return info; } private static T Random() where T : struct, Enum => Enum.GetValues()[DateTime.Now.Millisecond % (Enum.GetValues().Length - 1)]; }