using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.API.Internal.Operations.IncentiveApi.Services; using CsvHelper; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using Moq; using NUnit.Framework; using LCU.API.Internal.Operations.IncentiveApi.Services.Action; using LCU.API.Internal.Operations.IncentiveApi.Models.Action; using LCU.API.Internal.Operations.IncentiveApi.Services.MicroApiServices; using LCU.Library.Internal.IncentiveApiModels.Requests; using LCU.Library.Internal.FileOperationsModels.Models; using LCU.Library.Internal.FileOperationsModels.Models.NameSettings; namespace Application.UnitTests.Services.Action { public class ActionVehicleImportServiceTest { private IActionVehicleImportService _service; private IUserRepository _userRepository; private IActivityService _activityService; private IFileOperationsApiService _fileOperationsApiService; private Mock _deadActivityService; [SetUp] public void Setup() { _userRepository = Mock.Of(); _fileOperationsApiService = Mock.Of(); _activityService = Mock.Of(); _deadActivityService = new Mock(); _service = new ActionVehicleImportService(_userRepository, _fileOperationsApiService, _activityService, _deadActivityService.Object); } public StreamReader GetActionFile() { var path = @"Services/Action/Action_IndirectVehicleLoanSales.csv"; var reader = new StreamReader(path); return reader; } [Test] public async Task ProcessFileNames_OK() { var department = new Department() { DepartmentName = "Dept1", Id = 55, State = DepartmentState.Active }; var user = new AppUser() { AdEmail = "johndoe@test.com", 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 }; user.Departments.Add(assignment); var request = new ActionVehicleRequest { DynamicFileName = "vehiclesales", FilePath = "clean", DynamicFileSettings = new DynamicNameSetting() { } }; var files = new string[] { "x" }; byte[] array = File.ReadAllBytes( @"Services/Action/Action_IndirectVehicleLoanSales.csv"); //Setup Mock.Get(_fileOperationsApiService).Setup(x => x.BuildDynamicFileList(It.IsAny())).ReturnsAsync(files); Mock.Get(_fileOperationsApiService).Setup(x => x.GetFileContent(It.IsAny())).ReturnsAsync(array.ToString()); Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); Mock.Get(_activityService).Setup(x => x.SaveActivityRangeAsync(It.IsAny>())).Verifiable(); await _service.ImportTransactions(request); Mock.Get(_fileOperationsApiService).Verify(x => x.GetFileContent(It.IsAny()), Times.Once); Mock.Get(_activityService).Verify(x => x.SaveActivityRangeAsync(It.IsAny>()), Times.Once); } [Test] public async Task ProcessCsv_OK() { var department = new Department() { DepartmentName = "Dept1", Id = 55, State = DepartmentState.Active }; var user = new AppUser() { AdEmail = "johndoe@test.com", 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 }; user.Departments.Add(assignment); Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); var results = await _service.CreateActivity(transactions); Assert.NotNull(results); Assert.AreEqual(7, results.Count()); } public IEnumerable ImportTestTransactions() { var input = GetActionFile(); var csvReader = new CsvReader(input, CultureInfo.InvariantCulture); return csvReader.GetRecords().ToList(); } [Test] public async Task SavesDeadActivity_WhenNoUserFound() { Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync((AppUser)null); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); var results = await _service.CreateActivity(transactions); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count() == 7 && da.All(y => y.Reason == DeadActivityReason.MissingRequiredField) && da.All(y => y.ReasonNote.ToLowerInvariant().Contains("action import, no user for"))))); //Our test CSV has email information for every row except 1 _deadActivityService.Verify(x =>x.SaveDeadActivityRange(It.Is>( da => da.Count(x => !string.IsNullOrWhiteSpace(x.EmployeeEmail)) == 6))); } [Test] public async Task SavesDeadActivity_WhenFindingUserFails() { Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.IsAny())) .Throws(new Exception("OOops")); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); var results = await _service.CreateActivity(transactions); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count() == 7 && da.All(y => y.Reason == DeadActivityReason.MissingRequiredField) && da.All(y => y.ReasonNote.ToLowerInvariant().Contains("action import, no user for"))))); //Our test CSV has email information for every row except 1 _deadActivityService.Verify(x =>x.SaveDeadActivityRange(It.Is>( da => da.Count(x => !string.IsNullOrWhiteSpace(x.EmployeeEmail)) == 6))); } [Test] public async Task SavesDeadActivity_WhenNoHomeDepartmentFound() { //Use one user for all lines for simplicity var user = new AppUser() { AdEmail = "johndoe@test.com", EmployeeId = "11771", FullName = "John Doe", Departments = new List() }; Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync(user); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); var results = await _service.CreateActivity(transactions); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count() == 7 && da.All(y => y.Reason == DeadActivityReason.MissingRequiredField) && da.All(y => y.ReasonNote.ToLowerInvariant().Contains("reliably determinable home"))))); } [Test] public async Task SavesDeadActivity_BothKinds() { var user = new AppUser() { AdEmail = "johndoe@test.com", EmployeeId = "11771", FullName = "John Doe", Departments = new List() }; //There are 2 entries with this email, they will have a user but no home department Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.Is(x => x.ToLowerInvariant() == "test2@landmarkcu.com"))).ReturnsAsync(user); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); var results = await _service.CreateActivity(transactions); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count(y => y.Reason == DeadActivityReason.MissingRequiredField && y.ReasonNote.ToLowerInvariant().Contains("action import, no user for")) == 5))); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count(y => y.Reason == DeadActivityReason.MissingRequiredField && y.ReasonNote.ToLowerInvariant().Contains("reliably determinable home")) == 2))); } [Test] public async Task SomeActivitiesAreDeadJim_Ok() { var john = new AppUser() { AdEmail = "johndoe@test.com", EmployeeId = "John", FullName = "John Doe", Departments = new List() }; //There are 2 entries with this email, they will have a user but no home department Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.Is(x => x.ToLowerInvariant() == "michaelnembhard@landmarkcu.com"))).ReturnsAsync(john); var department = new Department() { DepartmentName = "Dept1", Id = 55, State = DepartmentState.Active }; var mary = new AppUser() { AdEmail = "marydeer@test.com", EmployeeId = "Mary", FullName = "Mary Deer", Departments = new List() }; var assignment = new UserDepartment() { Id = 99, Department = department, Employee = mary, Role = Role.BM, IsHome = true, StartDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1), EndDate = null }; mary.Departments.Add(assignment); //There are 2 entries with this email, they will not have a home department assigned Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.Is(x => x.ToLowerInvariant() == "test@landmarkcu.com"))).ReturnsAsync(john); //There are 2 entries with this email, they will have a home department assigned Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.Is(x => x.ToLowerInvariant() == "test2@landmarkcu.com"))).ReturnsAsync(mary); //Everyone else won't exist var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); //Mary should have 2 successful results var results = await _service.CreateActivity(transactions); Assert.NotNull(results); Assert.AreEqual(2,results.Count); Assert.True(results.All(x => x.EmployeeId == "Mary")); //John should have 2 entries in dead activity for not having a home department _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count(y => y.EmployeeId == john.EmployeeId && y.Reason == DeadActivityReason.MissingRequiredField && y.ReasonNote.ToLowerInvariant().Contains("reliably determinable home")) == 2))); //Everyone else could not be identified _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count(y => (y.EmployeeId != john.EmployeeId && y.EmployeeId != mary.EmployeeId) && y.Reason == DeadActivityReason.MissingRequiredField && y.ReasonNote.ToLowerInvariant().Contains("action import, no user for")) == 3))); } [Test] public async Task FailToSaveDeadActivity_DoesntThrow() { Mock.Get(_userRepository).Setup(s => s.FindUserByAdEmailAsync(It.IsAny())).ReturnsAsync((AppUser)null); _deadActivityService.Setup(x => x.SaveDeadActivityRange(It.IsAny>())) .ThrowsAsync(new Exception("Oops")); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); Assert.IsNotEmpty(transactions); Assert.AreEqual(7, transactions.Count()); List results = null; Assert.DoesNotThrowAsync(async () => { var res = await _service.CreateActivity(transactions); results = res.ToList(); }); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count() == 7 && da.All(y => y.Reason == DeadActivityReason.MissingRequiredField) && da.All(y => y.ReasonNote.ToLowerInvariant().Contains("action import, no user for"))))); //Our test CSV has email information for every row except 1 _deadActivityService.Verify(x =>x.SaveDeadActivityRange(It.Is>( da => da.Count(x => !string.IsNullOrWhiteSpace(x.EmployeeEmail)) == 6))); } } }