using System.Security.Claims; using adas_core.Application.Repositories.Interfaces; using adas_core.Application.Services; using adas_core.Application.Services.Interfaces; using adas_core.Domain.Enums; using adas_core.Domain.Models; using adas_core.Domain.Models.MongoModels; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using MongoDB.Bson; using Moq; namespace adas_core.Test.Services; /// /// Provides a unit test class for testing the functionality of the UnitService. /// /// /// This class is intended to contain test methods that validate the behavior and correctness of the UnitService. /// public class UnitServiceTest { private readonly Mock _auditServiceMock = new(); private readonly Mock _httpContextAccessorMock = new(); private Mock _clientMessageServiceMock = null!; private Mock> _loggerMock = null!; private Mock _masterListServiceFactoryMock = null!; private Mock _patientServiceMock = null!; private Mock _pointOfCareServiceMock = null!; private Mock _subscribersServiceMock = null!; private Mock _unitRepositoryMock = null!; private UnitService _unitService = null!; /// /// Initializes mocked dependencies and a configured instance for each test, /// including a mock with a test user claim. /// [SetUp] public void SetUp() { _unitRepositoryMock = new Mock(); _patientServiceMock = new Mock(); _loggerMock = new Mock>(); _clientMessageServiceMock = new Mock(); _subscribersServiceMock = new Mock(); _masterListServiceFactoryMock = new Mock(); _pointOfCareServiceMock = new Mock(); var userClaims = new ClaimsPrincipal(new ClaimsIdentity([ new Claim(ClaimTypes.Name, "TestUser") ], "mock")); var httpContextMock = new DefaultHttpContext { User = userClaims }; _httpContextAccessorMock.Setup(accessor => accessor.HttpContext) .Returns(httpContextMock); _unitService = new UnitService( _unitRepositoryMock.Object, new Lazy(() => _patientServiceMock.Object), _loggerMock.Object, _masterListServiceFactoryMock.Object, _subscribersServiceMock.Object, new Lazy(() => _clientMessageServiceMock.Object), _pointOfCareServiceMock.Object, _httpContextAccessorMock.Object, _auditServiceMock.Object ); } /// /// Verifies that the unit service returns all units retrieved from the repository, including the correct count and content. /// [Test] public async Task GetAll_ShouldReturnAllUnits() { // Arrange var units = new List { new() { Id = ObjectId.GenerateNewId() } }; _unitRepositoryMock.Setup(repo => repo.GetAll()).ReturnsAsync(units); // Act var result = await _unitService.GetAll(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count, Is.EqualTo(1)); Assert.That(result, Is.EqualTo(units)); } /// /// Verifies that the Get method on the unit service returns the expected unit when a valid identifier is provided. /// [Test] public async Task Get_ShouldReturnUnitById() { // Arrange var unitId = ObjectId.GenerateNewId(); var unit = new Unit { Id = unitId }; _unitRepositoryMock.Setup(repo => repo.FindById(unitId)).ReturnsAsync(unit); // Act var result = await _unitService.Get(unitId.ToString()); // Assert Assert.That(result, Is.Not.Null); Assert.That(result, Is.EqualTo(unit)); } /// /// Verifies that the Get method retrieves a unit by name when the provided identifier is not a valid ObjectId, matching against either the unit's Title or Name. /// [Test] public async Task Get_ShouldReturnUnitByName_WhenIdIsNotObjectId() { // Arrange var unitName = "TestUnit"; var units = new List { new() { Title = unitName }, new() { Name = unitName } }; _unitRepositoryMock.Setup(repo => repo.GetAll()).ReturnsAsync(units); // Act var result = await _unitService.Get(unitName); // Assert Assert.That(result, Is.Not.Null); Assert.That(result?.Title ?? result?.Name, Is.EqualTo(unitName)); } /// /// Verifies that _unitService" returns all units retrieved from the repository, /// ensuring the result is not null, contains the expected number of units, and matches the source data. /// [Test] public async Task GetAllUnits_ShouldReturnAllUnits() { // Arrange var units = new List { new() { Id = ObjectId.GenerateNewId(), Name = "Unit1" }, new() { Id = ObjectId.GenerateNewId(), Name = "Unit2" } }; _unitRepositoryMock.Setup(repo => repo.GetAll()).ReturnsAsync(units); // Act var result = await _unitService.GetAll(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Count(), Is.EqualTo(units.Count)); Assert.That(result, Is.EquivalentTo(units)); } /// /// Verifies that _unitService.FindById" returns the matching when the repository locates it by id. /// [Test] public async Task GetUnitById_ShouldReturnUnit_WhenFound() { // Arrange var unitId = ObjectId.GenerateNewId(); var unit = new Unit { Id = unitId, Name = "Unit1" }; _unitRepositoryMock.Setup(repo => repo.FindById(unitId)).ReturnsAsync(unit); // Act var result = await _unitService.FindById(unitId); // Assert Assert.That(result, Is.Not.Null); Assert.That(result, Is.EqualTo(unit)); } /// /// Verifies that GetByName returns the matching unit when a unit with the specified name exists in the repository. /// [Test] public async Task GetUnitByName_ShouldReturnUnit_WhenFound() { // Arrange var unitName = "TestUnit"; var expectedUnit = new Unit { Id = ObjectId.GenerateNewId(), Name = unitName }; _unitRepositoryMock.Setup(repo => repo.FindByName(unitName)).ReturnsAsync(expectedUnit); // Act var result = await _unitService.GetByName(unitName); // Assert Assert.That(result, Is.Not.Null); Assert.That(result, Is.EqualTo(expectedUnit)); } /// /// Verifies that FindByPatientId returns the associated unit when the patient is found in an active (in-use) point of care. /// [Test] public async Task FindUnitByPatientId_ShouldReturnUnit_WhenPatientFoundInActivePoC() { // Arrange var patientId = ObjectId.GenerateNewId(); var unitId = ObjectId.GenerateNewId(); var pocId = ObjectId.GenerateNewId(); var patient = new Patient { Id = patientId, PointOfCareId = pocId, UnitId = unitId }; var unit = new Unit { Id = unitId, PointOfCares = [new PointOfCare { Id = pocId, UnitId = unitId, Status = StatusEnum.PointOfCare.InUse }] }; _unitRepositoryMock.Setup(repo => repo.FindById(unitId)).ReturnsAsync(unit); _patientServiceMock.Setup(service => service.FindById(patientId, false)).ReturnsAsync(patient); // Act var result = await _unitService.FindByPatientId(patientId); // Assert Assert.That(result, Is.Not.Null); Assert.That(result?.PointOfCares?.Any(c => c.Id == patient.PointOfCareId && c.UnitId == patient.UnitId), Is.True); } /// /// Verifies that the unit service returns the matching units retrieved from the repository when a call is made to find units by the specified master list identifier and type. /// [Test] public async Task FindUnitsByMasterListId_ShouldReturnUnits_WhenUnitsFound() { // Arrange var masterListId = ObjectId.GenerateNewId(); var masterListType = MasterListType.AltableOptionList; var units = new List { new(), new() }; _unitRepositoryMock.Setup(repo => repo.FindByMasterListId(masterListId, masterListType)).ReturnsAsync(units); // Act var result = await _unitService.FindUnitsByMasterListId(masterListId, masterListType); // Assert if (result != null) { var actual = result.ToList(); Assert.That(actual, Is.Not.Null); Assert.That(actual, Is.EqualTo(units)); } } /// /// Verifies that the unit service returns the matching units when the repository contains units /// whose point of care matches the specified patient location. /// [Test] public async Task FindByLocation_ShouldReturnUnits_WhenUnitsFound() { // Arrange var location = new PatientLocation("TestUnit", "TestBed", "TestRoom"); var units = new List { new() { PointOfCares = [new PointOfCare { UnitName = "TestUnit", Bed = "TestBed" }] } }; _unitRepositoryMock.Setup(repo => repo.GetAll()).ReturnsAsync(units); // Act var result = await _unitService.FindByLocation(location); // Assert Assert.That(result, Is.Not.Null); Assert.That(result?.Count, Is.EqualTo(1)); Assert.That(result?.First().PointOfCares?.First().UnitName, Is.EqualTo("TestUnit")); Assert.That(result?.First().PointOfCares?.First().Bed, Is.EqualTo("TestBed")); } /// /// Verifies that FindByLocation returns an empty list when no units match the specified patient location. /// [Test] public async Task FindByLocation_ShouldReturnEmptyList_WhenNoUnitsFound() { // Arrange var location = new PatientLocation("NonExistentUnit", "NonExistentBed", "NonExistentRoom"); _unitRepositoryMock.Setup(repo => repo.GetAll()).ReturnsAsync([]); // Act var result = await _unitService.FindByLocation(location); // Assert Assert.That(result, Is.Not.Null); Assert.That(result?.Count, Is.EqualTo(0)); } /// /// Verifies that the unit service returns the expected unit when a valid unit identifier is provided. /// /// A task that represents the asynchronous test execution. [Test] public async Task FindById_ShouldReturnUnit_WhenValidIdProvided() { // Arrange var unitId = ObjectId.GenerateNewId(); var expectedUnit = new Unit { Id = unitId }; _unitRepositoryMock.Setup(repo => repo.FindById(unitId)).ReturnsAsync(expectedUnit); // Act var result = await _unitService.FindById(unitId); // Assert Assert.That(result, Is.Not.Null); Assert.That(result, Is.EqualTo(expectedUnit)); } /// /// Verifies that the unit service's FindById method returns null when invoked with a null identifier, /// ensuring graceful handling of null input without throwing or returning a default entity. /// [Test] public async Task FindById_ShouldReturnNull_WhenNullIdProvided() { // Arrange // Act var result = await _unitService.FindById(null); // Assert Assert.That(result, Is.Null); } /// /// Verifies that FindByName retrieves and returns the expected Unit when a valid unit name is provided. /// [Test] public async Task FindByName_ShouldReturnUnit_WhenValidNameProvided() { // Arrange var unitName = "Unit1"; var expectedUnit = new Unit { Name = unitName }; _unitRepositoryMock.Setup(repo => repo.FindByName(unitName)).ReturnsAsync(expectedUnit); // Act var result = await _unitService.FindByName(unitName); // Assert Assert.That(result, Is.Not.Null); Assert.That(result, Is.EqualTo(expectedUnit)); } /// /// Verifies that the unit service correctly delegates the insert operation to the repository and returns the inserted unit entity unchanged. /// [Test] public async Task InsertOne_ShouldReturnInsertedUnit() { // Arrange var unit = new Unit { Id = ObjectId.GenerateNewId(), Name = "TestUnit" }; _unitRepositoryMock.Setup(repo => repo.InsertOneUnit(unit)).ReturnsAsync(unit); // Act var result = await _unitService.InsertOne(unit); // Assert Assert.That(result, Is.Not.Null); Assert.That(result, Is.EqualTo(unit)); } }