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.API.Internal.Operations.IncentiveApi.Configuration; using LCU.Library.Internal.FileOperationsModels.Models.NameSettings; using LCU.Library.Internal.FileOperationsModels.Models; namespace Application.UnitTests.Services.Action { public class ActionCreditCardImportServiceTest { private IActionCreditCardImportService _actionCreditCardImportService; 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(); _actionCreditCardImportService = new ActionCreditCardImportService(_userRepository, _fileOperationsApiService, _activityService,_deadActivityService.Object); } private static StreamReader GetActionFile() { var path = @"Services/Action/Action_CreditCardPersonal.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 ActionCreditCardRequest { DynamicFileName = "credit", FilePath = "clean", DynamicFileSettings = new DynamicNameSetting() { } }; var files = new[] { "x" }; var array = await File.ReadAllBytesAsync( @"Services/Action/Action_CreditCardPersonal.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 _actionCreditCardImportService.ImportTransactions("personal", 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); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); // Should lose the duplicate. var results = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); Assert.NotNull(results); Assert.AreEqual(14, results.Count); } private 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); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); var results = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count == 15 && 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(deadActivity => !string.IsNullOrWhiteSpace(deadActivity.EmployeeEmail)) == 14))); } [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); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); var results = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count == 15 && 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(deadActivity => !string.IsNullOrWhiteSpace(deadActivity.EmployeeEmail)) == 14))); } [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); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); var results = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count == 15 && da.All(y => y.Reason == DeadActivityReason.MissingRequiredField) && da.All(y => y.ReasonNote.ToLowerInvariant().Contains("reliably determinable home"))))); } [Test] public async Task SavesDeadActivity_MissingEmployeeId_MissingDepartmentId() { 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() == "michaelnembhard@landmarkcu.com"))).ReturnsAsync(user); var transactions = ImportTestTransactions(); Assert.NotNull(transactions); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); var results = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); 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")) == 13))); _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() == "michaelnembhard@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() == "lauriepaulos@landmarkcu.com"))).ReturnsAsync(mary); //Everyone else won't exist var transactions = ImportTestTransactions(); Assert.NotNull(transactions); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); //Mary should have 2 successful results var results = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); 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")) == 11))); } [Test] public void 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); var actionCreditCardPersonalRows = transactions.ToList(); Assert.IsNotEmpty(actionCreditCardPersonalRows); Assert.AreEqual(15, actionCreditCardPersonalRows.Count); List results = null; Assert.DoesNotThrowAsync(async () => { var res = await _actionCreditCardImportService.CreateActivity(actionCreditCardPersonalRows); results = res.ToList(); }); Assert.NotNull(results); Assert.IsEmpty(results); _deadActivityService.Verify(x => x.SaveDeadActivityRange(It.Is>( da => da.Count == 15 && 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(deadActivity => !string.IsNullOrWhiteSpace(deadActivity.EmployeeEmail)) == 14))); } } }