using adas_core.Application.Customizations.HPAZ; 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.Pumps; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Bson; using Moq; using Options = Microsoft.Extensions.Options.Options; namespace adas_core.Test.Customizations.HPAZ; [TestFixture] public class CalculatedObservationsTest { [SetUp] public void Setup() { _alarmServiceMock = new Mock(); var alarmServiceLazy = new Lazy(() => _alarmServiceMock.Object); _patientServiceMock = new Mock(); _lightBeaconServiceMock = new Mock(); var balizaServiceLazy = new Lazy(() => _lightBeaconServiceMock.Object); _recordingServiceMock = new Mock(); var recordingServiceLazy = new Lazy(() => _recordingServiceMock.Object); _relayServiceMock = new Mock(); var relayServiceLazy = new Lazy(() => _relayServiceMock.Object); _treatmentServiceMock = new Mock(); var treatmentServiceLazy = new Lazy(() => _treatmentServiceMock.Object); _medicineServiceMock = new Mock(); var medicineServiceLazy = new Lazy(() => _medicineServiceMock.Object); _configObservationServiceMock = new Mock(); _observationServiceMock = new Mock(); var observationServiceLazy = new Lazy(() => _observationServiceMock.Object); _logger = new Mock>(); _optionsApiSettings = Options.Create(_apiSettings); _optionsApiSettings.Value.IgnoreCalcObservationsOlderInMinutesThan = 5; _optionsRecordingSettings = Options.Create(_recordingSettings); var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(_patientServiceMock.Object); serviceCollection.AddSingleton(balizaServiceLazy); serviceCollection.AddSingleton(recordingServiceLazy); serviceCollection.AddSingleton(relayServiceLazy); serviceCollection.AddSingleton(treatmentServiceLazy); serviceCollection.AddSingleton(medicineServiceLazy); serviceCollection.AddSingleton(_configObservationServiceMock.Object); serviceCollection.AddSingleton(observationServiceLazy); serviceCollection.AddSingleton(_optionsApiSettings); serviceCollection.AddSingleton(_optionsRecordingSettings); serviceCollection.AddSingleton(_logger.Object); serviceCollection.AddSingleton(alarmServiceLazy); var serviceProvider = serviceCollection.BuildServiceProvider(); _calculatedObservations = new CalculatedObservations(serviceProvider); } private CalculatedObservations _calculatedObservations; private Mock _patientServiceMock; private Mock _lightBeaconServiceMock; private Mock _recordingServiceMock; private Mock _relayServiceMock; private Mock _treatmentServiceMock; private Mock _medicineServiceMock; private Mock _configObservationServiceMock; private Mock _observationServiceMock; private Mock _alarmServiceMock; private Mock> _logger; private readonly ApiSettings _apiSettings = new() { VolumetricAirOcclusionAlarm = ["Occlusion", "Upstream Occlusion"] }; private IOptions _optionsApiSettings; private readonly RecordingSettings _recordingSettings = new(); private IOptions _optionsRecordingSettings; private readonly List _pressBloodArteryMean = ["TAm"]; private static readonly DateTime Now = DateTime.Now; private static readonly ObjectId PatientId = ObjectId.GenerateNewId(); [Test] public async Task Calculate_Ventilation_Mode_PRVC_Returns_VCRP() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Value = "PRVC", Name = "Resp_Mode" }; var result = await _calculatedObservations.Map(observation, false); Assert.That(result, Is.Not.Null); Assert.That(result!.Value, Is.EqualTo("VCRP")); } [Test] public async Task Calculate_Ventilation_Mode_FLUJ_ALTO_Returns_OAF() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Value = "FLUJ.ALTO", Name = "Resp_Mode" }; var result = await _calculatedObservations.Map(observation, false); Assert.That(result, Is.Not.Null); Assert.That(result!.Value, Is.EqualTo("OAF")); } [Test] public async Task Calculate_Ventilation_Mode_Not_PRVC_Not_FLUJ_ALTO_Returns_Other() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Value = "VNI PC", Name = "Resp_Mode" }; var result = await _calculatedObservations.Map(observation, false); Assert.That(result, Is.Not.Null); using (Assert.EnterMultipleScope()) { Assert.That(result!.Value, Is.Not.EqualTo("VCRP")); Assert.That(result.Value, Is.Not.EqualTo("OAF")); } } [Test] public async Task CalculateSF_Sattc_98_Returns_Not_Sattc_FiO2() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Sattc", Value = 98 }; var obsLast = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var value = 96.0 / 34.0; value = Math.Round(value, 4); var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Sattc_FiO2", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsLast]); await _calculatedObservations.Map(observation, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && Math.Abs(double.Parse(arg.Value.ToString()!) - double.Parse(obsCalculate.Value.ToString()!)) <= 0 && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true), Times.Never); } [Test] public async Task CalculateOxygenationIndex_FiO2_Returns_Oxygenation_Index() { var patientId = ObjectId.GenerateNewId(); var obsFio2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var obsPVam = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "P_VAM", Value = 6 }; var obsPaO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 234 }; const int value = 6 * 34 * 100 / 234; var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Oxygenation_Index", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsPVam, obsPaO2]); await _calculatedObservations.Map(obsFio2, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && arg.Value.ToString() == obsCalculate.Value.ToString() && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true)); } [Test] public async Task CalculateOxygenationIndex_P_VAM_Returns_Oxygenation_Index() { var patientId = ObjectId.GenerateNewId(); var obsFiO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var obsPVam = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "P_VAM", Value = 6 }; var obsPaO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 234 }; var value = 6 * 34 * 100 / 234; var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Oxygenation_Index", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsFiO2, obsPaO2]); await _calculatedObservations.Map(obsPVam, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && arg.Value.ToString() == obsCalculate.Value.ToString() && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true)); } [Test] public async Task CalculateOxygenationIndex_PaO2_Tidal_Returns_Oxygenation_Index() { var patientId = ObjectId.GenerateNewId(); var obsFiO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var obsPVam = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "P_VAM", Value = 6 }; var obsPaO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 234 }; var value = 6 * 34 * 100 / 234; var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Oxygenation_Index", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsFiO2, obsPVam]); await _calculatedObservations.Map(obsPaO2, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && arg.Value.ToString() == obsCalculate.Value.ToString() && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true)); } [Test] public async Task CalculateOxygenationIndex_PaO2_Tidal_Not_Returns_Oxygenation_Index() { var patientId = ObjectId.GenerateNewId(); var obsFiO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var obsPaO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 234 }; var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Oxygenation_Index", CodingSystem = "ADAS" }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsFiO2]); await _calculatedObservations.Map(obsPaO2, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true), Times.Never); } [Test] public async Task CalculateOxygenationIndex_PaO2_Tidal_0_Not_Returns_Oxygenation_Index() { var patientId = ObjectId.GenerateNewId(); var obsFiO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var obsPVam = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "P_VAM", Value = 6 }; var obsPaO2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 0 }; const int value = 6 * 34 * 100 / 234; var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Oxygenation_Index", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsFiO2, obsPVam]); await _calculatedObservations.Map(obsPaO2, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true), Times.Never); } [Test] public async Task CalculatePF_PaO2_Returns_PaO2_FiO2() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 234 }; var obsLast = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var value = 234.0 / 34.0; value = Math.Round(value, 4); var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_FiO2", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsLast]); await _calculatedObservations.Map(observation, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && Equals(TryparseDouble(arg.Value), TryparseDouble(obsCalculate.Value)) && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true)); } [Test] public async Task CalculatePF_FiO2_Returns_PaO2_FiO2() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 34 }; var obsLast = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 234 }; var value = 234.0 / 34.0; value = Math.Round(value, 4); var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_FiO2", CodingSystem = "ADAS", Value = value }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsLast]); await _calculatedObservations.Map(observation, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && Equals(TryparseDouble(arg.Value), TryparseDouble(obsCalculate.Value)) && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true)); } [Test] public async Task CalculatePF_FiO2_0_Not_Returns_PaO2_FiO2() { var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "PaO2_Tidal", Value = 98 }; var obsLast = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "FiO2", Value = 0 }; var obsCalculate = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Sattc_FiO2", CodingSystem = "ADAS" }; _observationServiceMock .Setup(l => l.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>())) .ReturnsAsync([obsLast]); await _calculatedObservations.Map(observation, false); _observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg => arg.Name == obsCalculate.Name && arg.PatientId == patientId && arg.CodingSystem == obsCalculate.CodingSystem ), true, true), Times.Never); } [Test] public async Task SendAlarm_BlueCode_FC_SpO2_Alarm_True_Returns_SendAlarm_BlueCode() { var patientId = ObjectId.GenerateNewId(); var now = DateTime.Now; var obsSattc = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "Sattc", Value = 50, Time = now }; var obsFc = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Value = "50", Name = "FC", Time = now }; var listObservation = new List { obsSattc, obsFc }; await _calculatedObservations.CalculateBlueCodeList(listObservation); _observationServiceMock.Verify(o => o.InsertObservation(It.IsAny(), true, true), Times.Once); _alarmServiceMock.Verify( a => a.SendAlarm(It.IsAny(), "BlueCode", AlarmEnum.Name.Blue, AlarmEnum.Severity.None, AlarmEnum.Type.Auto), Times.Once); } [Test] public async Task SendAlarm_BlueCode_FC_TAm_Alarm_True_Returns_SendAlarm_BlueCode() { var patientId = ObjectId.GenerateNewId(); var now = DateTime.Now; var obsFc = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Value = "50", Name = "FC", Time = now }; var obsTAm1 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "TAm", Value = 100, Time = now.AddSeconds(-5) }; var obsTAm2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "TAm", Value = 50, Time = now }; var listObservation = new List { obsFc, obsTAm2 }; var listTAmObs = new List { obsTAm1 }; _observationServiceMock.Setup(l => l.FindLastObservations(patientId, 1, _pressBloodArteryMean)) .ReturnsAsync(listTAmObs); await _calculatedObservations.CalculateBlueCodeList(listObservation); _observationServiceMock.Verify(o => o.InsertObservation(It.IsAny(), true, true), Times.Once); _alarmServiceMock.Verify( a => a.SendAlarm(It.IsAny(), "BlueCode", AlarmEnum.Name.Blue, AlarmEnum.Severity.None, AlarmEnum.Type.Auto), Times.Once); } [Test] public async Task SendAlarm_BlueCode_FC_TAm_Alarm_False() { var patientId = ObjectId.GenerateNewId(); var now = DateTime.Now; var obsFc = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Value = "50", Name = "FC", Time = now }; var obsTAm1 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "TAm", Value = 100, Time = now.AddSeconds(-5) }; var obsTAm2 = new PatientObservation { Id = ObjectId.GenerateNewId(), PatientId = patientId, Name = "TAm", Value = 80, Time = now }; var listObservation = new List { obsFc, obsTAm2 }; var listTAmObs = new List { obsTAm1 }; _observationServiceMock.Setup(l => l.FindLastObservations(patientId, 1, _pressBloodArteryMean)) .ReturnsAsync(listTAmObs); await _calculatedObservations.CalculateBlueCodeList(listObservation); _observationServiceMock.Verify(o => o.InsertObservation(It.IsAny(), true, true), Times.Never); _alarmServiceMock.Verify( a => a.SendAlarm(It.IsAny(), "BlueCode", AlarmEnum.Name.Blue, AlarmEnum.Severity.None, AlarmEnum.Type.Auto), Times.Never); } private static double? TryparseDouble(object value) { return double.TryParse(value.ToString(), out var valueParsed) ? valueParsed : null; } [Test] public async Task Map_PumpObservation_DrugName_Null_AlarmType_Occlusion_Return_Insert_Pump_Insert_PositionName() { var pumpObservation = new PumpObservation { Code = "Tile-6", Time = Now, Name = "g-1-pump-Tile-6", Number = 2, Total = 7, TotalAux = 0, Status = PumpEnum.Status.Alarm, PumpMode = PumpEnum.Mode.Unknown, InfusingStatus = PumpEnum.InfusingStatus.Unknown, Pressure = new CommonPumpTypes.PumpValue(), //drugName = "Nutrición Parenteral", Concentration = new CommonPumpTypes.PumpValue(), DrugAmount = new CommonPumpTypes.PumpValue(), DiluentVolume = new CommonPumpTypes.PumpValue(), DoseRate = new CommonPumpTypes.PumpValue(), Rate = new CommonPumpTypes.PumpValue(), VolumeInfused = new CommonPumpTypes.PumpValue { Value = 0.00001 }, VolumeRemaining = new CommonPumpTypes.PumpValue { Value = 0.00001 }, TimeRemaining = new CommonPumpTypes.PumpValue { Value = 1441, Units = "min" }, PatientWeight = new CommonPumpTypes.PumpValue(), AlarmType = PumpEnum.AlarmType.Occlusion, AlarmMode = PumpEnum.AlarmMode.Hight, GatewayNumber = 1, IsAux = false, IsInfusing = false, Expires = 100 }; await _calculatedObservations.Map(pumpObservation); _observationServiceMock.Verify(d => d.InsertObservation(It.Is(arg => arg.Value.ToString() == "Rack 1 Bomba 2"), true, true)); } [Test] public async Task Map_PumpObservation_DrugName_Null_AlarmType_Occlusion_Return_Insert_Pump_Insert_Aux_PositionName() { var pumpObservation = new PumpObservation { Code = "Tile-6", Time = Now, Name = "g-1-pump-Tile-6", Number = 2, Total = 7, TotalAux = 0, Status = PumpEnum.Status.Alarm, PumpMode = PumpEnum.Mode.Unknown, InfusingStatus = PumpEnum.InfusingStatus.Unknown, Pressure = new CommonPumpTypes.PumpValue(), //drugName = "Nutrición Parenteral", Concentration = new CommonPumpTypes.PumpValue(), DrugAmount = new CommonPumpTypes.PumpValue(), DiluentVolume = new CommonPumpTypes.PumpValue(), DoseRate = new CommonPumpTypes.PumpValue(), Rate = new CommonPumpTypes.PumpValue(), VolumeInfused = new CommonPumpTypes.PumpValue { Value = 0.00001 }, VolumeRemaining = new CommonPumpTypes.PumpValue { Value = 0.00001 }, TimeRemaining = new CommonPumpTypes.PumpValue { Value = 1441, Units = "min" }, PatientWeight = new CommonPumpTypes.PumpValue(), AlarmType = PumpEnum.AlarmType.Occlusion, AlarmMode = PumpEnum.AlarmMode.Hight, GatewayNumber = 1, IsAux = true, IsInfusing = false, Expires = 100 }; await _calculatedObservations.Map(pumpObservation); _observationServiceMock.Verify(d => d.InsertObservation(It.Is(arg => arg.Value.ToString() == "Rack Aux 1 Bomba 2"), true, true)); } [Test] public async Task Map_PatientObservation_Alarm_Pump_Retur_obs() { PatientObservation patientObservation = new() { CodingSystem = "ADAS_ALARM", Code = "Pump_VolumetricAirOclusion", Name = "Alarm_Pump_VolumetricAirOclusion", Value = "Rack 1 Bomba 1", PatientId = PatientId, Time = Now }; var result = await _calculatedObservations.Map(patientObservation, false); Assert.That(result, Is.Not.Null); Assert.That(result!.Name, Is.EqualTo(patientObservation.Name)); } }