using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.API.Internal.Operations.IncentiveApi.Services; using Moq; using NUnit.Framework; using System.Threading.Tasks; using System; using System.Collections.Generic; using CsvHelper.Configuration; using CsvHelper; using System.Globalization; using System.IO; using LCU.Library.Internal.IncentiveApiModels.Requests; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using LCU.Library.Internal.Exceptions; using LCU.API.Internal.Operations.IncentiveApi.Services.MicroApiServices; using LCU.API.Internal.Operations.IncentiveApi.Services.Temenos; using LCU.API.Internal.Operations.IncentiveApi.Models.Temenos; using LCU.Library.Internal.FileOperationsModels.Models; namespace Application.UnitTests.Services.Temenos { public class ImportIndirectVehicleSalesServiceTest { private ImportIndirectVehicleSalesService _importIndirectVehicleSalesService; private Mock _mockUserRepository; private Mock _mockActivityService; private Mock _mockFileOperationsApiService; private Mock _mockDeadActivityService; [SetUp] public void SetUp() { _mockUserRepository = new Mock(); _mockActivityService = new Mock(); _mockFileOperationsApiService = new Mock(); _mockDeadActivityService = new Mock(); _importIndirectVehicleSalesService = new ImportIndirectVehicleSalesService(_mockActivityService.Object, _mockUserRepository.Object, _mockFileOperationsApiService.Object, _mockDeadActivityService.Object); } [Test] public async Task HandleImportIndirectVehicleSales_DeadAndAcceptedActivities_Ok() { var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", ApplicationID = "123", CreatedDate = DateTime.Now.AddDays(-50).ToString(), ReferringEmployeeEmail = "matched@mail.com" }, new DirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", ApplicationID = "321", CreatedDate = DateTime.Now.AddDays(-30).ToString(), ReferringEmployeeEmail = "dead@mail.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.ToString() }, new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ApplicationID = "321", DisbursedDate = DateTime.Now.ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser("matched@mail.com"); _mockUserRepository.SetupSequence(x => x.FindUserByAdEmailAsync(It.IsAny())) .ReturnsAsync(user) .ReturnsAsync((AppUser)null); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; await _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Once); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Once); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Exactly(2)); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public async Task HandleImportIndirectVehicleSales_NoMatches_NoActivitiesSaved() { var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", ApplicationID = "123", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ReferringEmployeeEmail = "test@mail.com" }, new DirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", ApplicationID = "321", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ReferringEmployeeEmail = "test@mail.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = "987-65-4321", CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.ToString() }, new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-20).ToString(), ApplicationID = "321", DisbursedDate = DateTime.Now.ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser("matched@mail.com"); _mockUserRepository.SetupSequence(x => x.FindUserByAdEmailAsync(It.IsAny())) .ReturnsAsync(user) .ReturnsAsync((AppUser)null); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; await _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Never); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Never); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public async Task HandleImportIndirectVehicleSales_OneIndirectMatch_CorrectActivitySaved() { var referringEmail = "matched@mail.com"; var matchedSsn = "123-45-6789"; var directCreatedDate = DateTime.Now.AddDays(-50).ToString(); var indirectCreatedDate = DateTime.Now.AddDays(-10).ToString(); var disbursedDate = DateTime.Now.ToString(); var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = matchedSsn, ApplicationID = "123", CreatedDate = directCreatedDate, ReferringEmployeeEmail = referringEmail }, new DirectVehicleSaleRecord() { ApplicantSSN = "123-45-9876", ApplicationID = "123", CreatedDate = DateTime.Now.AddDays(-30).ToString(), ReferringEmployeeEmail = "test@test.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = matchedSsn, CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = disbursedDate }, new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-60).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.AddDays(-70).ToString() }, new IndirectVehicleSaleRecord() { ApplicantSSN = "999-99-9999", CreatedDate = DateTime.Now.AddDays(-60).ToString(), ApplicationID = "999", DisbursedDate = DateTime.Now.AddDays(-65).ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser(referringEmail); _mockUserRepository.Setup(x => x.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); _mockActivityService.Setup(x => x.SaveActivityRangeAsync(It.IsAny>())); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "filename", IndirectDynamicFileName = "indirectFileName" }; await _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.Is>(x => x.Count == 1 && x[0].EmployeeEmail == referringEmail && x[0].SourceCreated == DateTime.Parse(disbursedDate) && x[0].Accepted == DateTime.Parse(disbursedDate).Date.AddHours(12)))); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Once); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public async Task HandleImportIndirectVehicleSales_MultipleIndirectApplicants_FirstRecordMatches() { var referringEmail = "matched@mail.com"; var matchedSsn = "123-45-6789"; var directCreatedDate = DateTime.Now.AddDays(-50).ToString(); var indirectCreatedDate = DateTime.Now.AddDays(-10).ToString(); var disbursedDate = DateTime.Now.ToString(); var matchedApplicantName = "matchedName"; var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = matchedSsn, ApplicationID = "123", CreatedDate = directCreatedDate, ReferringEmployeeEmail = referringEmail }, new DirectVehicleSaleRecord() { ApplicantSSN = matchedSsn, ApplicationID = "123", CreatedDate = directCreatedDate, ReferringEmployeeEmail = "secondapplicant@test.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = matchedSsn, CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = disbursedDate, ApplicantName = matchedApplicantName }, new IndirectVehicleSaleRecord() { ApplicantSSN = matchedSsn, CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = disbursedDate } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser(referringEmail); _mockUserRepository.Setup(x => x.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); _mockActivityService.Setup(x => x.SaveActivityRangeAsync(It.IsAny>())); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "filename", IndirectDynamicFileName = "indirectFileName" }; await _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.Is>(x => x.Count == 1 && x[0].Detail.MemberName == matchedApplicantName && x[0].EmployeeEmail == referringEmail && x[0].SourceCreated == DateTime.Parse(disbursedDate) && x[0].Accepted == DateTime.Parse(disbursedDate).Date.AddHours(12)))); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Once); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public void HandleImportIndirectVehicleSales_DeadActivityServiceFails_ExceptionThrown() { var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", ApplicationID = "321", CreatedDate = DateTime.Now.AddDays(-30).ToString(), ReferringEmployeeEmail = "dead@mail.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.ToString() }, new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ApplicationID = "321", DisbursedDate = DateTime.Now.ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser("matched@mail.com"); _mockUserRepository.Setup(x => x.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync((AppUser)null); _mockDeadActivityService.Setup(x => x.SaveDeadActivityRange(It.IsAny>())).ThrowsAsync(new Exception("Failure")); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; Assert.ThrowsAsync(() => _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request)); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Once); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Once); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public void HandleImportIndirectVehicleSales_ActivityServiceFails_ExceptionThrown() { var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", ApplicationID = "321", CreatedDate = DateTime.Now.AddDays(-30).ToString(), ReferringEmployeeEmail = "test@mail.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())) .ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser("matched@mail.com"); _mockUserRepository.Setup(x => x.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); _mockActivityService.Setup(x => x.SaveActivityRangeAsync(It.IsAny>())).ThrowsAsync(new Exception("Failure")); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; Assert.ThrowsAsync(() => _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request)); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Never); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Once); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Once); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public async Task HandleImportIndirectVehicleSales_UserRepositoryFails_DeadActivitySaved() { var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", ApplicationID = "123", CreatedDate = DateTime.Now.AddDays(-50).ToString(), ReferringEmployeeEmail = "matched@mail.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.ToString() }, new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ApplicationID = "321", DisbursedDate = DateTime.Now.ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); _mockUserRepository.Setup(x => x.FindUserByAdEmailAsync(It.IsAny())).ThrowsAsync(new Exception("Failure")); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; await _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>(x => x.Count == 1)), Times.Once); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Once); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public async Task HandleImportIndirectVehicleSales_NullEmployeeHomedepartment_DeadActivitySaved() { var directFileContent = new List() { new DirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", ApplicationID = "123", CreatedDate = DateTime.Now.AddDays(-50).ToString(), ReferringEmployeeEmail = "matched@mail.com" } }; var directWriter = GetWriter(directFileContent); var indirectFileContent = new List() { new IndirectVehicleSaleRecord() { ApplicantSSN = "123-45-6789", CreatedDate = DateTime.Now.AddDays(-40).ToString(), ApplicationID = "123", DisbursedDate = DateTime.Now.ToString() }, new IndirectVehicleSaleRecord() { ApplicantSSN = "555-55-5555", CreatedDate = DateTime.Now.AddDays(-10).ToString(), ApplicationID = "321", DisbursedDate = DateTime.Now.ToString() } }; var indirectWriter = GetWriter(indirectFileContent); var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.SetupSequence(x => x.GetFileContent(It.IsAny())) .ReturnsAsync(directWriter.ToString()) .ReturnsAsync(indirectWriter.ToString()); var user = GetAppUser("matched@mail.com", false); _mockUserRepository.Setup(x => x.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; await _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>(x => x.Count == 1)), Times.Once); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Once); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Exactly(2)); } [Test] public Task HandleImportIndirectVehicleSales_FileOperationsGetContentServiceFails_ExceptionThrown() { var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(fileResponse); _mockFileOperationsApiService.Setup(x => x.GetFileContent(It.IsAny())).ThrowsAsync(new Exception("Failure")); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; Assert.ThrowsAsync(() => _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request)); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Never); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Never); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Once); return Task.CompletedTask; } [Test] public Task HandleImportIndirectVehicleSales_FileOperationsBuildListServiceFails_ExceptionThrown() { var fileResponse = new string[] { "filename" }; _mockFileOperationsApiService.Setup(x => x.BuildDynamicFileList(It.IsAny())).ThrowsAsync(new Exception("Failure")); var request = new ImportIndirectVehicleSalesRequest() { FilePath = "path\\", DirectDynamicFileName = "directFileName", IndirectDynamicFileName = "indirectFileName" }; Assert.ThrowsAsync(() => _importIndirectVehicleSalesService.HandleImportIndirectVehicleSales(request)); _mockDeadActivityService.Verify(x => x.SaveDeadActivityRange(It.IsAny>()), Times.Never); _mockActivityService.Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Never); _mockUserRepository.Verify(x => x.FindUserByAdEmailAsync(It.IsAny()), Times.Never); _mockFileOperationsApiService.Verify(x => x.GetFileContent(It.IsAny()), Times.Never); return Task.CompletedTask; } private StringWriter GetWriter(List fileContent) { var writer = new StringWriter(); var config = new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = "|", HasHeaderRecord = false }; using (var csv = new CsvWriter(writer, config)) { csv.WriteRecords(fileContent); } return writer; } private AppUser GetAppUser(string emailAddress, bool assignHomeDepartment = true) { var department = new Department { DepartmentName = "Dept1", Id = 55, State = DepartmentState.Active }; var user = new AppUser { AdEmail = emailAddress, EmployeeId = "11771", FullName = "John Doe", Departments = new List() }; var assignment = new UserDepartment { Id = 99, Department = department, Employee = user, Role = Role.BM, IsHome = true, StartDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1), EndDate = null }; if (assignHomeDepartment) { user.Departments.Add(assignment); } return user; } } }