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.AppSettings; using adas_core.Domain.Models.MongoModels; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using MongoDB.Bson; using Moq; using Options = Microsoft.Extensions.Options.Options; namespace adas_core.Test.Services; /// /// Contains unit tests for verifying the behavior and functionality of the class. /// public class AlarmServiceTest { private readonly Mock _alarmRepositoryMock; private readonly AlarmService _alarmService; private readonly ApiSettings _apiSettings = new() { ConfigObservation = new ConfigObservationSettings { IgnoreUnknownObservation = false }, IntravenousLinesCode = ["10546003"], AllergiesCode = ["473011001"], DrainageCode = ["56868008"], IsolationCode = ["302147001"], PositionCode = ["386053000"] }; private readonly Mock _calculatedObservationsServiceMock; private readonly Mock _configObservationServiceMock; private readonly Mock _observationServiceMock; private readonly Mock _patientServiceMock; private readonly RecordingSettings _recordingSettings = new(); private readonly Mock _unitServiceMock; public AlarmServiceTest() { var optionsApiSettings = Options.Create(_apiSettings); Options.Create(_recordingSettings); _observationServiceMock = new Mock(); var observationServiceMockLazy = new Lazy(() => _observationServiceMock.Object); _patientServiceMock = new Mock(); _configObservationServiceMock = new Mock(); _unitServiceMock = new Mock(); var pocServiceMock = new Mock(); var beaconServiceMock = new Mock(); var beaconServiceMockLazy = new Lazy(() => beaconServiceMock.Object); var relayServiceMock = new Mock(); var relayServiceMockLazy = new Lazy(() => relayServiceMock.Object); var recordingServiceMock = new Mock(); var recordingServiceMockLazy = new Lazy(() => recordingServiceMock.Object); var clientMessageServiceMock = new Mock(); var subscribersServiceMock = new Mock(); var httpContextAccessorMock = new Mock(); var auditServiceMock = new Mock(); _calculatedObservationsServiceMock = new Mock(); var calculatedObservationsServiceLazy = new Lazy(() => _calculatedObservationsServiceMock.Object); var logger = new Mock>(); _alarmRepositoryMock = 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); _alarmService = new AlarmService( _alarmRepositoryMock.Object, logger.Object, _patientServiceMock.Object, _configObservationServiceMock.Object, observationServiceMockLazy, clientMessageServiceMock.Object, subscribersServiceMock.Object, calculatedObservationsServiceLazy, beaconServiceMockLazy, recordingServiceMockLazy, relayServiceMockLazy, optionsApiSettings, _unitServiceMock.Object, pocServiceMock.Object, httpContextAccessorMock.Object, auditServiceMock.Object, false // Disable the timer for testing ); } /// /// Verifies that when an ORU_R40 type request is processed without any alarms, the patient is located but the observation is not persisted. /// [Test] public async Task SaveRequest_Oru_R40_Type_Without_Alarms_Dont_Insert() { // Arrange var apiRequest = new ApiRequest { Type = "ORU_R40", PatientNumber = "12345", Observation = new PatientObservation { Value = "Test" }, Alarms = [], Location = new PatientLocation { Bed = "Bed1", Room = "Bed1", UnitName = "Unit1" } }; var unit = new Unit { Configuration = new UnitConfiguration { AutoAdt = true } }; var patient = new Patient { Id = ObjectId.GenerateNewId(), Bed = "Bed1" }; _unitServiceMock.Setup(u => u.FindByUnitNameOrPocName(It.IsAny(), It.IsAny())) .ReturnsAsync(unit); _patientServiceMock.Setup(p => p.FindPatientByApiRequest(apiRequest)).ReturnsAsync(patient); _observationServiceMock.Setup(o => o.SaveRequestAsync(It.IsAny())).Returns(Task.CompletedTask); // Act await _alarmService.SaveRequest(apiRequest); // Assert _patientServiceMock.Verify(p => p.FindPatientByApiRequest(apiRequest), Times.Once); _observationServiceMock.Verify(o => o.SaveRequestAsync(It.IsAny()), Times.Never); } /// /// Verifies that inserts the provided alarm observations into the alarm repository. /// [Test] public async Task ProcessAlarmObservations_Should_Insert_Alarm_Observations() { // Arrange var patient = new Patient { Id = ObjectId.GenerateNewId(), Bed = "Bed1" }; var alarmObservations = new List { new() { Value = "Alarm1", Time = DateTime.UtcNow} }; var observations = new List { new() { Value = "Alarm1", Time = DateTime.MinValue} }; _configObservationServiceMock.Setup(o => o.Map(It.IsAny(), It.IsAny())) .ReturnsAsync((PatientObservationAlarm obs, bool _) => obs); // Correct setup _calculatedObservationsServiceMock.Setup(o => o.Map(It.IsAny(), It.IsAny())) .ReturnsAsync((PatientObservationAlarm obs, bool _) => obs); // Correct setup // Act await _alarmService.ProcessAlarmObservations(alarmObservations, observations, patient, DateTime.UtcNow); // Assert _alarmRepositoryMock.Verify(a => a.InsertOneAsync(It.IsAny()), Times.Once); } /// /// Verifies that when checking observation alarms for a patient observation with an "Event_PEEP_Low" configuration /// (coding system "ADAS_EVENT", description "EVT_LO and EVT_EXTR_LO"), the alarm service does not insert a new observation, /// as indicated by the verification that InsertObservation is never invoked. /// [Test] public async Task CheckObservationAlarm_Alarm_EventPEEP_PEEP_bajo_create_Event() { var obs = new PatientObservation(); var configs = new ConfigObservation { Id = ObjectId.GenerateNewId(), Name = "Event_PEEP_Low", CodingSystem = "ADAS_EVENT", Description = "EVT_LO and EVT_EXTR_LO" }; _configObservationServiceMock.Setup(c => c.Get(It.IsAny(), false)) .ReturnsAsync(configs); await _alarmService.CheckObservationAlarm(obs); _observationServiceMock.Verify(o => o.InsertObservation(obs, true, true), Times.Never); } /// /// Verifies that processes a patient observation /// matching a configured rule (name "EVT_LO" with required value "PEEP") by inserting a new /// observation with the original value preserved (e.g., "PEEP High") while the alarm /// configuration handles the red beacon signaling. /// [Test] public async Task CheckObservationAlarm_Should_Launch_Red_Alarm_And_Set_BeaconColor_Red() { var alarmConfig = new AlarmConfig { Enabled = true, Priority = 10, Beacon = new AlarmItem { Enabled = true, BeaconColor = AlarmEnum.BeaconColor.Red, // Using the enum value EndAfter = 60 // Assuming the alarm should end after 60 seconds } }; var configs = new ConfigObservation { Id = ObjectId.GenerateNewId(), Name = "Event_PEEP_Low", CodingSystem = "ADAS_EVENT", Description = "logs an event. No generate an alarm.", Alarm = alarmConfig, RequiredValue = "PEEP" }; var obsConfig = new ConfigObservation { Id = ObjectId.GenerateNewId(), Name = "EVT_LO", CheckObservations = true, CreateObservation = [configs] }; var patId = ObjectId.GenerateNewId(); // Arrange var obs = new PatientObservation { Id = ObjectId.GenerateNewId(), Name = "EVT_LO", PatientId = patId, Value = "PEEP High", Time = DateTime.UtcNow, CheckObservations = true, CreateObservation = [configs] }; _configObservationServiceMock.Setup(c => c.Get(It.IsAny(), false)) .ReturnsAsync(obsConfig); // Act await _alarmService.CheckObservationAlarm(obs); _observationServiceMock.Verify( o => o.InsertObservation( It.Is(ob => ob.Value.ToString() == "PEEP High"), true, true), Times.Once); } }