using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using LCU.API.Internal.Operations.IncentiveApiLib.Persistence; using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.API.Internal.Operations.IncentiveApi.Services; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using Microsoft.EntityFrameworkCore; using Moq; using NUnit.Framework; using LCU.API.Internal.Operations.IncentiveApi.Exceptions; namespace Application.UnitTests.Services { public class DepartmentServiceTest { private DepartmentService _departmentService; private IDepartmentRepository _departmentRepository; private ICurrentUserService _currentUserService; private IUserAssignmentService _userAssignmentService; private ApplicationDbContext _context; [SetUp] public void Setup() { var mockDateTime = new DateTimeService(); _currentUserService = Mock.Of(); _userAssignmentService = Mock.Of(); Mock.Get(_currentUserService).Setup(s => s.GetCurrentUser()).Returns(new ApplicationUser() { Email = "JohnTest@test.com" }); var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .EnableSensitiveDataLogging(true) .Options; _context = new ApplicationDbContext(options, _currentUserService, mockDateTime); _departmentRepository = new DepartmentRepository(_context); _departmentService = new DepartmentService(_departmentRepository, _userAssignmentService, new UnitOfWork(_context)); } [Test] public async Task Basic_Flow() { //Retrieve Empty var departments = await _departmentService.GetAllDepartmentsAsync(); Assert.IsNotNull(departments); Assert.IsEmpty(departments); //Add New Department var department = await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName", DayForceGlCode = "1", DepartmentName = "TestName", DnaOrgNbr = "1" }); Assert.NotNull(department); Assert.True(department.DepartmentName == "TestName"); //New Department Can Be Retrieved departments = await _departmentService.GetAllDepartmentsAsync(); Assert.IsNotNull(departments); Assert.True(departments.Count == 1); Assert.True(departments.SingleOrDefault()?.DepartmentName == "TestName"); var id = departments.SingleOrDefault()?.Id; if (id == null) { Assert.Fail("Department ID was null, a save failed"); return; } //Department can be updated department = await _departmentService.UpdateDepartmentAsync( new Department() { DepartmentName = "NewName", State = DepartmentState.Active, BusinessLineCode = "BUS", RegionCode = "CENTRAL" }, (int)id); Assert.NotNull(department); Assert.True(department.DepartmentName == "NewName"); Assert.True(department.BusinessLineCode == "BUS"); Assert.True(department.RegionCode == "CENTRAL"); Assert.True(department.State == DepartmentState.Active); //Updated department can be retrieved individually department = await _departmentService.GetDepartmentByIdAsync((int)id); Assert.True(department.DepartmentName == "NewName"); //Updated department can be retrieved by all departments = await _departmentService.GetAllDepartmentsAsync(); Assert.IsNotNull(departments); Assert.True(departments.Count == 1); } [Test] public async Task Throws_Duplicate_Exception() { //Add New Department var testDepartment = await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName", DayForceGlCode = "1", DepartmentName = "TestName", DnaOrgNbr = "1" }); Assert.NotNull(testDepartment); Assert.True(testDepartment.DepartmentName == "TestName"); //Add New Department var testDepartment2 = await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName2", DayForceGlCode = "1", DepartmentName = "TestName2", DnaOrgNbr = "1" }); Assert.NotNull(testDepartment2); Assert.True(testDepartment2.DepartmentName == "TestName2"); //Add New Department With Same Name Assert.ThrowsAsync(async () => { await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName", DayForceGlCode = "1", DepartmentName = "TestName", DnaOrgNbr = "1" }); }); //Add New Department With Same Name Ignore Case Assert.ThrowsAsync(async () => { await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName", DayForceGlCode = "1", DepartmentName = "testname", DnaOrgNbr = "1" }); }); //Update Department To Already Existing Name Assert.ThrowsAsync(async () => { await _departmentService.UpdateDepartmentAsync(new Department() { DepartmentName = "TestName" }, testDepartment2.Id ?? 1); }); //Allow Update to Update itself (Same Name), should not throw try { var updatedDepartment = await _departmentService.UpdateDepartmentAsync( new Department() { DepartmentName = "TestName2", BusinessLineCode = "2" }, testDepartment2.Id ?? 1); Assert.AreEqual("TestName2", updatedDepartment.DepartmentName); } catch (Exception) { Assert.Fail(); } } [Test] public async Task GetDepartmentDetailsAsync_Basic() { var department = new Department() { DepartmentName = "Dept1", Id = 55, State = DepartmentState.Active }; var user = new AppUser { HomeDepartment = "Home", Role = Role.Admin, AdEmail = "AbrahamTestAssociate1@test.com", EmployeeId = "11771", FullName = "Abraham TestAssociate1", BaseRole = "UNKNOWN", Departments = new List() }; user.Departments.ForEach(x => x.Employee = user); var yesterday = DateTime.Now.AddDays(-1); var testDepartment = await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName", DayForceGlCode = "1", DepartmentName = "TestName", DnaOrgNbr = "1", Assignments = new List { new UserDepartment() { Id = 11, Department = department, Employee = user, Role = Role.BM, IsHome = true, StartDate = yesterday, EndDate = null }, new UserDepartment() { Id = 12, Department = department, Employee = user, Role = Role.BM, IsHome = false, StartDate = yesterday, EndDate = null } } }); var result = await _departmentService.GetDepartmentDetailsAsync(testDepartment.Id.Value); Assert.AreEqual("TestName", result.Department.DepartmentName); Assert.AreEqual(testDepartment.Assignments.Count, result.Assignments.Count); Assert.AreEqual(11, result.Assignments.ElementAt(0).Id); Assert.AreEqual(12, result.Assignments.ElementAt(1).Id); Assert.IsNull(result.RegionalManager); Mock.Get(_userAssignmentService).Verify( mock => mock.GetUserAssignment(AssignmentType.RegionalManager, It.IsAny()), Times.Never); } [Test] public void GetDepartmentDetailsAsync_NotFoundException() { var exception = Assert.ThrowsAsync(async () => { await _departmentService.GetDepartmentDetailsAsync(1); }); Assert.AreEqual("Could Not Find Department With ID 1", exception.Message); } [Test] public async Task GetDepartmentDetailsAsync_RegionCodeLookup() { var user = new AppUser { HomeDepartment = "Home", Role = Role.Admin, AdEmail = "user@landmarkcu.com", EmployeeId = "C0000", FullName = "Abraham TestAssociate1", BaseRole = "UNKNOWN", PersonId = 0, Departments = new List() }; var yesterday = DateTime.Now.AddDays(-1); var testDepartment = await _departmentService.SaveDepartmentAsync(new Department() { BusinessLineCode = "1", DayforceDepartmentName = "TestName", DayForceGlCode = "1", DepartmentName = "TestName", DnaOrgNbr = "1", Assignments = new List { new UserDepartment { Id = 11, StartDate = yesterday, Employee = user, IsHome = true, Role = Role.Admin}, new UserDepartment { Id = 12, StartDate = yesterday, Employee = user, IsHome = false, Role = Role.Admin} }, RegionCode = "NORTH" }); var regionalManager = new AppUser { AdEmail = "regionalManager@landmarkcu.com", EmployeeId = "RM000", PersonId = 1 }; var regionalManagerAssignment = new UserAssignment { Type = AssignmentType.RegionalManager, Key = testDepartment.RegionCode, AppUser = regionalManager }; Mock.Get(_userAssignmentService) .Setup(mock => mock.GetUserAssignment(AssignmentType.RegionalManager, It.IsAny())) .ReturnsAsync(regionalManagerAssignment); var result = await _departmentService.GetDepartmentDetailsAsync(testDepartment.Id.Value); Assert.AreEqual("regionalManager@landmarkcu.com", result.RegionalManager.AdEmail); Assert.AreEqual("RM000", result.RegionalManager.EmployeeId); Assert.AreEqual(1, result.RegionalManager.PersonId); Mock.Get(_userAssignmentService).Verify( mock => mock.GetUserAssignment(AssignmentType.RegionalManager, It.IsAny()), Times.Once); } [Test] public async Task GetHierarchicalDepartmentsForEmployeeAsync_Basic_ADMIN() { var departmentRepository = Mock.Of(); var userAssignmentService = Mock.Of(); var mockUnitOfWork = new Mock(); var departmentService = new DepartmentService(departmentRepository, userAssignmentService, mockUnitOfWork.Object); var user = new AppUser() { AdEmail = "tester@test.com", BaseRole = "Tester", EmployeeId = "11771", FullName = "Test McTester", HomeDepartment = "HOME", PersonId = 565, Departments = new List() { new UserDepartment() { DepartmentId = 55, Role = Role.Admin } } }; Mock.Get(departmentRepository).Setup(s => s.GetAllDepartmentsAsync()).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep1" } }); Mock.Get(departmentRepository).Setup(s => s.FindDepartmentsByRegionAsync(It.IsAny())).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep2" } }); var results = await departmentService.GetHierarchicalDepartmentsForEmployeeAsync(user, false); Assert.NotNull(results); Assert.IsNotEmpty(results); Mock.Get(departmentRepository).Verify(s => s.GetAllDepartmentsAsync(), Times.Once); Mock.Get(departmentRepository).Verify(s => s.FindDepartmentsByRegionAsync(It.IsAny()), Times.Never); } [Test] public async Task GetHierarchicalDepartmentsForEmployeeAsync_Basic_RM() { var departmentRepository = Mock.Of(); var userAssignmentService = Mock.Of(); var mockUnitOfWork = new Mock(); var departmentService = new DepartmentService(departmentRepository, userAssignmentService, mockUnitOfWork.Object); var user = new AppUser() { AdEmail = "tester@test.com", BaseRole = "Tester", EmployeeId = "11771", FullName = "Test McTester", HomeDepartment = "HOME", PersonId = 565, Departments = new List() { new UserDepartment() { DepartmentId = 55, Role = Role.RegionalManager, Department = new Department() { RegionCode = Region.East.Code } } } }; Mock.Get(departmentRepository).Setup(s => s.GetAllDepartmentsAsync()).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep1" } }); Mock.Get(departmentRepository).Setup(s => s.FindDepartmentsByRegionAsync(It.IsAny())).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep2" } }); var results = await departmentService.GetHierarchicalDepartmentsForEmployeeAsync(user, false); Assert.NotNull(results); Assert.IsNotEmpty(results); Mock.Get(departmentRepository).Verify(s => s.GetAllDepartmentsAsync(), Times.Never); Mock.Get(departmentRepository).Verify(s => s.FindDepartmentsByRegionAsync(It.IsAny()), Times.Once); } // if you are RM but there is no region, you'll just get the branch where you are RM back... [Test] public async Task GetHierarchicalDepartmentsForEmployeeAsync_Basic_RM_null_region() { var departmentRepository = Mock.Of(); var userAssignmentService = Mock.Of(); var mockUnitOfWork = new Mock(); var departmentService = new DepartmentService(departmentRepository, userAssignmentService, mockUnitOfWork.Object); var user = new AppUser() { AdEmail = "tester@test.com", BaseRole = "Tester", EmployeeId = "11771", FullName = "Test McTester", HomeDepartment = "HOME", PersonId = 565, Departments = new List() { new UserDepartment() { DepartmentId = 55, Role = Role.RegionalManager, Department = new Department() { DepartmentName = "testdep3" // No Region. }, StartDate = DateTime.Today } } }; Mock.Get(departmentRepository).Setup(s => s.GetAllDepartmentsAsync()).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep1" } }); Mock.Get(departmentRepository).Setup(s => s.FindDepartmentsByRegionAsync(It.IsAny())).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep2" } }); var results = await departmentService.GetHierarchicalDepartmentsForEmployeeAsync(user, false); Assert.NotNull(results); Assert.IsNotEmpty(results); Mock.Get(departmentRepository).Verify(s => s.GetAllDepartmentsAsync(), Times.Never); Mock.Get(departmentRepository).Verify(s => s.FindDepartmentsByRegionAsync(It.IsAny()), Times.Never); } [Test] public async Task GetHierarchicalDepartmentsForEmployeeAsync_Basic_ABM_MANAGER_BM() { var departmentRepository = Mock.Of(); var userAssignmentService = Mock.Of(); var mockUnitOfWork = new Mock(); var departmentService = new DepartmentService(departmentRepository, userAssignmentService, mockUnitOfWork.Object); var user = new AppUser() { AdEmail = "tester@test.com", BaseRole = "Tester", EmployeeId = "11771", FullName = "Test McTester", HomeDepartment = "HOME", PersonId = 565, Departments = new List() { new UserDepartment() { DepartmentId = 55, Role = Role.ABM, Department = new Department() { DepartmentName = "testdeptabm" } } } }; Mock.Get(departmentRepository).Setup(s => s.GetAllDepartmentsAsync()).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep1" } }); Mock.Get(departmentRepository).Setup(s => s.FindDepartmentsByRegionAsync(It.IsAny())).ReturnsAsync(new List() { new Department() { DepartmentName = "testdep2" } }); var results = await departmentService.GetHierarchicalDepartmentsForEmployeeAsync(user, true); Assert.NotNull(results); Assert.IsNotEmpty(results); Mock.Get(departmentRepository).Verify(s => s.GetAllDepartmentsAsync(), Times.Never); Mock.Get(departmentRepository).Verify(s => s.FindDepartmentsByRegionAsync(It.IsAny()), Times.Never); results = await departmentService.GetHierarchicalDepartmentsForEmployeeAsync(user, false); Assert.NotNull(results); Assert.IsEmpty(results); } } }