using System.Security.Claims; using adas_core.Application.Exceptions; using adas_core.Application.Repositories.Interfaces; using adas_core.Application.Services; using adas_core.Application.Services.Interfaces; using adas_core.Domain.Models; using adas_core.Domain.Models.MongoModels; using adas_core.Test.Utilities; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using MongoDB.Bson; using Moq; namespace adas_core.Test.Services; /// /// Provides unit tests for the class, verifying the behavior and correctness of discharge-related operations. /// public class DischargeServiceTest { private readonly Mock _auditServiceMock = new(); private readonly Mock _clientMessageServiceMock = new(); private readonly Mock _dischargeRepositoryMock = new(); private readonly Mock _httpContextAccessorMock = new(); private readonly Mock> _loggerMock = new(); private readonly Mock _masterMock = new(); private readonly Mock> _patientServiceLazyMock = new(); private readonly Mock _pointOfCareServiceMock = new(); private readonly Mock _subscribersServiceMock = new(); private readonly Mock _unitServiceMock = new(); private DischargeService _dischargeService = null!; /// /// Sets up the test environment by creating a mock authenticated user context and instantiating the with its required dependencies for use in unit tests. /// [SetUp] public void Setup() { 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); _dischargeService = new DischargeService( _loggerMock.Object, _subscribersServiceMock.Object, _dischargeRepositoryMock.Object, _patientServiceLazyMock.Object, _clientMessageServiceMock.Object, _pointOfCareServiceMock.Object, _httpContextAccessorMock.Object, _auditServiceMock.Object, _unitServiceMock.Object, _masterMock.Object); } /// /// Verifies that successfully deletes a discharge /// when it exists in the repository. /// /// The discharge entity expected to be deleted; its identifier is used to invoke the repository delete operation. [Test] public async Task DeleteDischargeAsync_WhenDischargeExists_DeletesDischarge() { // Arrange var dischargeId = ObjectId.GenerateNewId(); var discharge = new Discharge { Id = dischargeId }; _dischargeRepositoryMock.Setup(repo => repo.FindById(dischargeId)).ReturnsAsync(discharge); // Act await _dischargeService.DeleteDischargeAsync(discharge); // Assert _dischargeRepositoryMock.Verify(repo => repo.Delete(dischargeId), Times.Once); } //necesita el pocservice // [Test] // public async Task GetDischargeByIdAsync_WhenDischargeExists_ReturnsDischarge() // { // // Arrange // var dischargeId = ObjectId.GenerateNewId(); // var discharge = new Discharge { Id = dischargeId }; // _dischargeRepositoryMock.Setup(repo => repo.FindById(dischargeId)).ReturnsAsync(discharge); // // // Act // var result = await _dischargeService.GetDischargeByIdAsync(dischargeId); // // // Assert // Assert.That(result, Is.EqualTo(discharge)); // } /// /// Verifies that throws a when the requested discharge is not found. /// [Test] public void GetDischargeByIdAsync_WhenExceptionOccurs_ReturnsNullAndLogsError() { // Arrange var dischargeId = ObjectId.GenerateNewId(); // Act and assert Func act = async () => await _dischargeService.GetDischargeByIdAsync(dischargeId); Assert.ThrowsAsync(act); } /// /// Verifies that the discharge service returns the expected discharges retrieved from the repository when the underlying repository call completes successfully without exceptions. /// /// A representing the asynchronous test execution. [Test] public async Task GetDischargesAsync_WhenNoException_ReturnsDischarges() { // Arrange var discharge = TestUtilities.CreateValidDischarge(); var discharges = new List { discharge }; _dischargeRepositoryMock.Setup(repo => repo.FindAll()).ReturnsAsync(discharges); // Act var result = await _dischargeService.GetDischargesAsync(); var resultList = result.ToList(); // Assert Assert.That(resultList.First().Id, Is.EqualTo(discharges.First().Id)); } //necesita el pocservice // [Test] // public async Task GetDischargeByPatientId_WhenDischargeExists_ReturnsDischarge() // { // // Arrange // var discharge = TestUtilities.CreateValidDischarge(); // _dischargeRepositoryMock.Setup(repo => repo.GetByPatientId(discharge.PatientId)).ReturnsAsync(discharge); // // // Act // var result = await _dischargeService.GetDischargeByPatientId(discharge.PatientId); // // // Assert // Assert.That(result?.Id, Is.EqualTo(discharge.Id)); // } /// /// Verifies that returns the inserted discharge /// when the underlying repository successfully completes the insertion and the entity can be retrieved by its identifier. /// [Test] public async Task InsertDischarge_WhenInsertionSuccessful_ReturnsInsertedDischarge() { // Arrange var dischargeId = ObjectId.GenerateNewId(); var discharge = new Discharge { Id = dischargeId }; _dischargeRepositoryMock.Setup(repo => repo.InsertOneAsync(discharge)).Returns(Task.CompletedTask); _dischargeRepositoryMock.Setup(repo => repo.FindById(dischargeId)).ReturnsAsync(discharge); // Act var result = await _dischargeService.InsertDischarge(discharge); // Assert Assert.That(result, Is.EqualTo(discharge)); } /// /// Verifies that handles repository insertion failures by propagating the exception thrown by the underlying data store. /// [Test] public void InsertDischarge_WhenInsertionFails_ReturnsNullAndLogsError() { // Arrange var discharge = new Discharge { Id = ObjectId.GenerateNewId() }; var exception = new Exception("Failed to insert discharge"); _dischargeRepositoryMock.Setup(repo => repo.InsertOneAsync(discharge)).ThrowsAsync(exception); // Assert Func act = async () => await _dischargeService.InsertDischarge(discharge); Assert.ThrowsAsync(act); } /// /// Verifies that returns the discharge /// retrieved from the repository when a discharge exists for the specified patient location. /// [Test] public async Task GetDischargeByLocation_WhenDischargeExists_ReturnsDischarge() { // Arrange var location = new PatientLocation("UnitName", "Bed", "Room"); var discharge = new Discharge(); _dischargeRepositoryMock.Setup(repo => repo.GetDischargeByLocation(location)).ReturnsAsync(discharge); // Act var result = await _dischargeService.GetDischargeByLocation(location); // Assert Assert.That(result, Is.EqualTo(discharge)); } /// /// Verifies that returns null when the underlying discharge repository throws an exception while retrieving the discharge record for the specified patient location. /// [Test] public async Task GetDischargeByLocation_WhenExceptionOccurs_ReturnsNullAndLogsError() { // Arrange var location = new PatientLocation("UnitName", "Bed", "Room"); var exception = new Exception("Failed to retrieve discharge by location"); _dischargeRepositoryMock.Setup(repo => repo.GetDischargeByLocation(location)).ThrowsAsync(exception); // Act var result = await _dischargeService.GetDischargeByLocation(location); // Assert Assert.That(result, Is.Null); } // [Test] // public async Task GetDischargeByPointOfCareId_WhenDischargeExists_ReturnsDischarge() // { // // Arrange // var discharge = TestUtilities.CreateValidDischarge(); // _dischargeRepositoryMock.Setup(repo => repo.GetDischargeByPointOfCareId(discharge.PointOfCareId)).ReturnsAsync(discharge); // // // Act // var result = await _dischargeService.GetDischargeByPointOfCareId(discharge.PointOfCareId); // // // Assert // Assert.That(result, Is.EqualTo(discharge)); // } /// /// Verifies that returns null when the underlying repository throws an exception while attempting to retrieve a discharge by its point-of-care identifier. /// [Test] public async Task GetDischargeByPointOfCareId_WhenExceptionOccurs_ReturnsNullAndLogsError() { // Arrange var poc = ObjectId.GenerateNewId(); var exception = new Exception("Failed to retrieve discharge by PointOfCareId"); _dischargeRepositoryMock.Setup(repo => repo.GetDischargeByPointOfCareId(poc)).ThrowsAsync(exception); // Act var result = await _dischargeService.GetDischargeByPointOfCareId(poc); // Assert Assert.That(result, Is.Null); } }