using adas_core.Application.Customizations.HUVH.UCIN; 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.Utils; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Bson; using Moq; using Newtonsoft.Json; namespace adas_core.Test.Customizations.HUVH.UCIN; /// /// Test fixture that contains unit tests for the type. /// /// /// Marked with TestFixture so that the NUnit test runner discovers and executes the contained test methods. /// /// [TestFixture] public class CalculatedObservationsTest { /// /// Initializes the mocked dependencies and configuration required to instantiate for unit tests, including observation, medicine, and treatment services, the logger, and an populated with mapping interventions and complexity observation values deserialized from JSON. /// /// [SetUp] public void Setup() { _mockObservationService = new Mock(); _medicineServiceMock = new Mock(); _treatmentServiceMock = new Mock(); _logger = new Mock>(); //JSON data const string mappingInterventionsJson = @"[ { ""Type"": ""Respiratory_Device"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""Oxigeno (O2)/Alto flujo"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 204.0, ""FinalValue"": null } ] }, { ""Type"": ""Respiratory_Device"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""CPAP "", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 202.0, ""FinalValue"": null } ] }, { ""Type"": ""Respiratory_Device"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""Ventilaci\u00f3n mec\u00e1nica Invasiva"", ""Value"": [ { ""InitialValue"": 3.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 201.0, ""FinalValue"": null } ] }, { ""Type"": ""Respiratory_Device"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VAFO Ventilaci\u00f3n Oscilatoria de alta frecuencia"", ""Value"": [ { ""InitialValue"": 4.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 200.0, ""FinalValue"": null } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VV perfif\u00e9rica"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 103.1, ""FinalValue"": 103.5 } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VV epicut\u00e1neo cava"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 102.1, ""FinalValue"": 102.5 } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VV umbilical"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 101.1, ""FinalValue"": null } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VV central"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 104.1, ""FinalValue"": 104.3 } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VV PICC"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 108.1, ""FinalValue"": 108.2 } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VA umbilical"", ""Value"": [ { ""InitialValue"": 3.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 101.2, ""FinalValue"": null } ] }, { ""Type"": ""Intravenous_Routes"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""VA"", ""Value"": [ { ""InitialValue"": 3.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 106.1, ""FinalValue"": 106.3 } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Digoxina ev"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 118.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Digoxina vo"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 1753.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Amiodarona ev"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 169.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Amiodarona vo"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 16323.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Atropina"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 186.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Esmolol"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 853.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Propranolol"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 7122.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Isoprenalina"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 283.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Flecainida ev"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 1247.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Antiarr\u00edtmicos"", ""Name"": ""Flecainida vo"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 7055.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Adrenalina"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 281.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Noradrenalina"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 100000.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Milrinona"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 618.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Levosimendan"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 2073.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Dopamina"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 149.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Debutamina"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 1968.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Drogas vasoactivas"", ""Name"": ""Fenilefrina"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 12319.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Morfina ev"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 472.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Morfina ov"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 7081.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Fentanil"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 434.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Midazolam"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 756.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Dexmedetomidina"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 15910.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Cisatraculi"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 15066.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Propofol"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 314.0, ""FinalValue"": null } ] }, { ""Type"": ""Medication"", ""Category"": ""Treatment"", ""Group"": ""Sedaci\u00f3n"", ""Name"": ""Ketamina"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 374.0, ""FinalValue"": null } ] }, { ""Type"": ""System"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""Hipotermia"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 100001.0, ""FinalValue"": null } ] }, { ""Type"": ""System"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""aEEG"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 100002.0, ""FinalValue"": null } ] }, { ""Type"": ""System"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""Drenaje ventricular (DVE)"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 315.1, ""FinalValue"": null }, { ""InitialValue"": 315.2, ""FinalValue"": null } ] }, { ""Type"": ""System"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""Drenaje toracico"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 311.0, ""FinalValue"": 314.0 } ] }, { ""Type"": ""System"", ""Category"": ""Intervention"", ""Group"": ""not defined"", ""Name"": ""Dialisis peritoneal - abdominal"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 306.0, ""FinalValue"": 310.0 } ] }, { ""Type"": ""Newborn_Weight"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Newborn_Weight"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": 500.0, ""valueContributed"": 5 }, { ""InitialValue"": 501.0, ""FinalValue"": 1000.0, ""valueContributed"": 4 }, { ""InitialValue"": 1001.0, ""FinalValue"": 1500.0, ""valueContributed"": 3 }, { ""InitialValue"": 1501.0, ""FinalValue"": 2000.0, ""valueContributed"": 2 }, { ""InitialValue"": 2000.0, ""FinalValue"": 2500.0, ""valueContributed"": 1 } ], ""Codes"": [ { ""InitialValue"": 10000465.0, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Cardiaca"", ""Value"": [ { ""InitialValue"": 4.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.1, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Digestiva"", ""Value"": [ { ""InitialValue"": 3.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.2, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Neurologica "", ""Value"": [ { ""InitialValue"": 3.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.3, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Toracica"", ""Value"": [ { ""InitialValue"": 3.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.4, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""ORL/Maxil\u00b7lo"", ""Value"": [ { ""InitialValue"": 2.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.5, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Oftalmo"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.6, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Ortopedia"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.7, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""Altres"", ""Value"": [ { ""InitialValue"": 1.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.8, ""FinalValue"": null } ] }, { ""Type"": ""surgery"", ""Category"": ""Observation"", ""Group"": ""not defined"", ""Name"": ""No"", ""Value"": [ { ""InitialValue"": 0.0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": 14000070.9, ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LM"", ""Name"": ""Llet materna"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIB586"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LM"", ""Name"": ""Llet materna de banc"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIB000589"", ""FinalValue"": null }, { ""InitialValue"": ""BIB000587"", ""FinalValue"": null }, { ""InitialValue"": ""BIB000588"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LM"", ""Name"": ""Llet materna a demanda"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""NO_EST2"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LM descremada"", ""Name"": ""LM descremada"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""NO_EST3"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Formula de soja"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBCOM003"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Formula hidrolizada (Alfare)"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBCOM002"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Formula inici"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBNOR003"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Formula prematurs 14,4%"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBCOM017"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Formula prematurs 15,9%"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBCOM018"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Formula sense lactosa"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBCOM01"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Monogen"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBCOM009"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Infatrini"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBNOR001"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Infatini Peptisorb"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBNOR0013"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Neocate 13,8%"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBBAS019"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Neocate Advance 25%"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""NO_EST4"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Energivit"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""BIBBAS021"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""LA"", ""Name"": ""Bibero especial"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""ALTESP001"", ""FinalValue"": null } ] }, { ""Type"": ""Nutrition"", ""Category"": ""Treatment"", ""Group"": ""Absoluta"", ""Name"": ""Absoluta"", ""Value"": [ { ""InitialValue"": 0, ""FinalValue"": null } ], ""Codes"": [ { ""InitialValue"": ""15002284"", ""FinalValue"": null } ] } ]"; const string complexityValuesJson = @"{ ""Oxigeno (O2)/Alto flujo"": 1, ""CPAP "": 2, ""Ventilación mecánica Invasiva"": 3, ""VAFO Ventilación Oscilatoria de alta frecuencia"": 4, ""VV perfiférica"": 1, ""VV epicutáneo cava"": 2, ""VV umbilical"": 2, ""VV central"": 2, ""VV PICC"": 2, ""VA umbilical"": 3, ""VA"": 3, ""Digoxina ev"": 1, ""Digoxina vo"": 1, ""Amiodarona ev"": 1, ""Amiodarona vo"": 1, ""Atropina"": 1, ""Esmolol"": 1, ""Propranolol"": 1, ""Isoprenalina"": 1, ""Flecainida ev"": 1, ""Flecainida vo"": 1, ""Adrenalina"": 2, ""Noradrenalina"": 2, ""Milrinona"": 2, ""Levosimendan"": 2, ""Dopamina"": 2, ""Debutamina"": 2, ""Fenilefrina"": 2, ""Hipotermia"": 2, ""aEEG"": 2, ""Drenaje ventricular (DVE)"": 2, ""Drenaje toracico"": 2, ""Dialisis peritoneal - abdominal"": 2, ""Cardiaca"": 4, ""Digestiva"": 3, ""Neurologica "": 3, ""Toracica"": 3, ""ORL/Maxil·lo"": 2, ""Oftalmo"": 1, ""Ortopedia"": 1, ""Altres"": 1, ""No"": 0 }"; // Deserialize the JSON var apiSettings = JsonConvert.DeserializeObject( $$""" { "MappingInterventions": {{mappingInterventionsJson}}, "ComplexityMappingObservation": {{complexityValuesJson}} } """ ); if (apiSettings == null) return; // Mock IOptions to return our populated ApiSettings _mockApiSettings = new Mock>(); _mockApiSettings.Setup(s => s.Value).Returns(apiSettings); // Create an instance of MappingUtils with the mocked IOptions _mappingUtils = new MappingUtils(_mockApiSettings.Object); var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(new Lazy(() => _mockObservationService.Object)); serviceCollection.AddSingleton(new Lazy(() => _medicineServiceMock.Object)); serviceCollection.AddSingleton(new Lazy(() => _treatmentServiceMock.Object)); serviceCollection.AddSingleton(_mockApiSettings.Object); serviceCollection.AddSingleton(_logger.Object); serviceCollection.AddSingleton(_mappingUtils); // Register the real instance var serviceProvider = serviceCollection.BuildServiceProvider(); _calculatedObservations = new CalculatedObservations(serviceProvider); } private Mock _mockObservationService; private Mock _medicineServiceMock; private Mock _treatmentServiceMock; private Mock> _logger; private Mock> _mockApiSettings; private MappingUtils _mappingUtils; private CalculatedObservations _calculatedObservations; /// /// Verifies that when an observation contains an intervention code (e.g., "204") that exists in the data, /// the Map method creates and inserts a multivalue observation (Respiratory_Device_Multivalue) /// containing the intervention description extracted from the observation value. /// /// [Test] public async Task Map_WithInterventionCodeInObservationValue_CallsCalculateInterventionMultiValueObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); var observation = new PatientObservation { Name = "Intervention_In", PatientId = patientId, Value = "204 Oxigeno (O2)/Alto flujo" }; // Code 204 exists in data _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.IsAny>())) .ReturnsAsync([]); // Simulate no existing multivalue observation // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Respiratory_Device_Multivalue") && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Count() == 1 && ((string[])o.Value)[0].ToString() == "Oxigeno (O2)/Alto flujo"), true, true), Times.Once); } /// /// Verifies that mapping an Intervention_Out observation updates an existing active multi-value observation /// (e.g., Respiratory_Device_Multivalue) for the patient by setting its end time, rather than inserting a new observation. /// /// [Test] public async Task Map_WithInterventionOut_UpdatesExistingMultiValueObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); var interventionCode = "204"; var interventionDescription = "Oxigeno (O2)/Alto flujo"; var observationOutValue = $"{interventionCode} {interventionDescription}"; var observationOut = new PatientObservation { Name = "Intervention_Out", PatientId = patientId, Value = observationOutValue }; // Simulate an existing multi-value observation that is active var existingMultiValueObservation = new PatientObservation { PatientId = patientId, Name = "Respiratory_Device_Multivalue", Value = new[] { interventionDescription }, Time = DateTime.UtcNow.AddMinutes(-30) // Simulate it started 30 minutes ago }; _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))) // Find the active multi-value observation .ReturnsAsync([existingMultiValueObservation]); // Act await _calculatedObservations.Map(observationOut); // Assert // Verify that the existing multi-value observation was updated to set an EndTime _mockObservationService.Verify( x => x.UpdateObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Respiratory_Device_Multivalue") )), Times.Once); // Optionally, verify that a new observation was NOT inserted _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that when a new "Intervention_In" observation is mapped via Map and the patient's prior "Respiratory_Device_Multivalue" observation is expired (so there is no existing active last observation), a new named "Respiratory_Device_Multivalue" is inserted containing the new intervention while the existing expired observation is left untouched. /// /// /// /// [Test] public async Task Map_WithNewInterventionNoExistingLastIntervention_NewMultiValueObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); // Simular una intervención activa existente //var existingInterventionCode = "204"; const string existingInterventionDescription = "Oxigeno (O2)/Alto flujo"; var existingMultiValueObservation = new PatientObservation { PatientId = patientId, Name = "Respiratory_Device_Multivalue", Value = new[] { existingInterventionDescription }, Time = DateTime.UtcNow.AddMinutes(-30), Expired = true }; _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))) .ReturnsAsync([existingMultiValueObservation]); // Nuevo evento de "Intervention_In" con una intervención diferente const string newInterventionCode = "202"; const string newInterventionDescription = "CPAP"; const string newObservationInValue = $"{newInterventionCode} {newInterventionDescription}"; var newObservationIn = new PatientObservation { Name = "Intervention_In", PatientId = patientId, Value = newObservationInValue }; // Act await _calculatedObservations.Map(newObservationIn); // Assert // Verificar que NO se insertó una nueva observación (se actualizó la existente) _mockObservationService.Verify( x => x.UpdateObservation(It.IsAny()), Times.Never); // Verificar que la observación multi-valor existente se actualizó añadiendo la nueva intervención _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Respiratory_Device_Multivalue") && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 1 && ((string[])o.Value)[0] != existingInterventionDescription && ((string[])o.Value)[0] != newInterventionDescription), true, true), Times.Once); } /// /// Verifies that when a new Intervention_In observation is mapped for a patient that already has an /// active Respiratory_Device_Multivalue observation, the new intervention is appended to the existing /// multi-value observation via rather than inserted as a /// new record through . /// /// /// [Test] public async Task Map_WithNewInterventionAddsToExistingMultiValueObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); // Simular una intervención activa existente //var existingInterventionCode = "204"; const string existingInterventionDescription = "Oxigeno (O2)/Alto flujo"; var existingMultiValueObservation = new PatientObservation { PatientId = patientId, Name = "Respiratory_Device_Multivalue", Value = new[] { existingInterventionDescription }, Time = DateTime.UtcNow.AddMinutes(-30) }; _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))) .ReturnsAsync([existingMultiValueObservation]); // Nuevo evento de "Intervention_In" con una intervención diferente const string newInterventionCode = "202"; const string newInterventionDescription = "CPAP"; const string newObservationInValue = $"{newInterventionCode} {newInterventionDescription}"; var newObservationIn = new PatientObservation { Name = "Intervention_In", PatientId = patientId, Value = newObservationInValue }; // Act await _calculatedObservations.Map(newObservationIn); // Assert // Verificar que la observación multi-valor existente se actualizó añadiendo la nueva intervención _mockObservationService.Verify( x => x.UpdateObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Respiratory_Device_Multivalue") && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 1 && ((string[])o.Value)[0] == existingInterventionDescription && o.Expired)), Times.Once); // Verificar que NO se insertó una nueva observación (se actualizó la existente) _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Respiratory_Device_Multivalue") && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 2 && ((string[])o.Value)[0] == existingInterventionDescription && ((string[])o.Value)[1] == newInterventionDescription ), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that mapping a surgery observation inserts a new Surgery_Multivalue observation /// when no existing multi-value observation is found, and does not trigger an update. /// /// [Test] public async Task Map_WithSurgeryObservation_InsertsNewSurgeryMultiValueObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); const string surgeryName = "Surgery"; const string surgeryValue = "Appendectomy"; var surgeryObservation = new PatientObservation { Name = surgeryName, PatientId = patientId, Value = surgeryValue }; const string expectedMultiValueObservationName = $"{surgeryName}_Multivalue"; // Simulate no existing Surgery_Multivalue observation _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(expectedMultiValueObservationName)))) .ReturnsAsync([]); // Act await _calculatedObservations.Map(surgeryObservation); // Assert // Verify that a new Surgery_Multivalue observation was inserted with the correct value _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals(expectedMultiValueObservationName) && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 1 && ((string[])o.Value)[0].ToString() == surgeryValue), true, true), Times.Once); // Verify that UpdateObservation was not called _mockObservationService.Verify( x => x.UpdateObservation(It.IsAny()), Times.Never); } /// /// Verifies that mapping a new surgery observation causes an existing "Surgery_Multivalue" patient observation /// to be expired and replaced with a new multi-value observation that contains both the previously recorded /// surgery value and the newly mapped surgery value. /// /// [Test] public async Task Map_WithSurgeryObservation_UpdatesExistingSurgeryMultiValueObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); const string surgeryName = "Surgery"; const string newSurgeryValue = "Cholecystectomy"; var surgeryObservation = new PatientObservation { Name = surgeryName, PatientId = patientId, Value = newSurgeryValue }; const string expectedMultiValueObservationName = $"{surgeryName}_Multivalue"; const string existingSurgeryValue = "Appendectomy"; var existingMultiValueObservation = new PatientObservation { PatientId = patientId, Name = expectedMultiValueObservationName, Value = new[] { existingSurgeryValue }, Time = DateTime.UtcNow.AddMinutes(-30), Expired = false }; // Simulate an existing Surgery_Multivalue observation _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(expectedMultiValueObservationName)))) .ReturnsAsync([existingMultiValueObservation]); // Act await _calculatedObservations.Map(surgeryObservation); // Assert // Verify that the existing Surgery_Multivalue observation was expired _mockObservationService.Verify( x => x.UpdateObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals(expectedMultiValueObservationName) && o.Expired)), Times.Once); // Verify that a new Surgery_Multivalue observation was inserted with the new value _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals(expectedMultiValueObservationName) && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 2 && ((string[])o.Value)[0].ToString() == existingSurgeryValue && ((string[])o.Value)[1].ToString() == newSurgeryValue), true, true), Times.Once); } /// /// Verifies that mapping a Surgery observation updates the existing Surgery_Multivalue observation by expiring the duplicate entry and inserting a new observation with the duplicate value removed. /// /// [Test] public async Task Map_WithSurgeryObservation_UpdatesExistingSurgeryMultiValueObservation_RemovesDuplicate() { // Arrange var patientId = ObjectId.GenerateNewId(); const string surgeryName = "Surgery"; const string duplicateSurgeryValue = "Appendectomy"; var surgeryObservation = new PatientObservation { Name = surgeryName, PatientId = patientId, Value = duplicateSurgeryValue }; const string expectedMultiValueObservationName = $"{surgeryName}_Multivalue"; var existingMultiValueObservation = new PatientObservation { PatientId = patientId, Name = expectedMultiValueObservationName, Value = new[] { "Appendectomy", "Tonsillectomy" }, Time = DateTime.UtcNow.AddMinutes(-30), Expired = false }; // Simulate an existing Surgery_Multivalue observation with a duplicate value _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(expectedMultiValueObservationName)))) .ReturnsAsync([existingMultiValueObservation]); // Act await _calculatedObservations.Map(surgeryObservation); // Assert // Verify that the existing Surgery_Multivalue observation was expired _mockObservationService.Verify( x => x.UpdateObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals(expectedMultiValueObservationName) && o.Expired)), Times.Once); // Verify that a new Surgery_Multivalue observation was inserted with the duplicate removed _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals(expectedMultiValueObservationName) && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 2 && ((string[])o.Value)[1].ToString() == "Appendectomy" && ((string[])o.Value)[0].ToString() == "Tonsillectomy"), true, true), Times.Once); } /// /// Verifies that does not insert or update any observation when a surgery observation is provided with a non-string Value. /// /// [Test] public async Task Map_WithSurgeryObservation_HandlesNonStringValue() { // Arrange var patientId = ObjectId.GenerateNewId(); const string surgeryName = "Surgery"; var surgeryObservation = new PatientObservation { Name = surgeryName, PatientId = patientId, Value = 123 }; // Non-string value // Act await _calculatedObservations.Map(surgeryObservation); // Assert // Verify that no new observation was inserted _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); // Verify that no existing observation was updated _mockObservationService.Verify( x => x.UpdateObservation(It.IsAny()), Times.Never); } /// /// Verifies that the method, when invoked with a respiratory device multivalue observation /// and no prior observations, inserts a "Complexity" observation with a value of 1. /// /// [Test] public async Task Map_WithRespiratoryDeviceMultiValueObservation_CallsCalculateComplexity_Return1() { // Arrange var patientId = ObjectId.GenerateNewId(); const string observationName = "Respiratory_Device_Multivalue"; var observationValue = new[] { "Oxigeno (O2)/Alto flujo" }; var observation = new PatientObservation { Name = observationName, PatientId = patientId, Value = observationValue }; //value 1 _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(observationName)))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Intravenous_Routes_Multivalue")))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Medication_Multivalue")))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("System_Multivalue")))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Newborn_Weight")))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Surgery_Multivalue")))) .ReturnsAsync([]); // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Complexity") && o.Value is int && (int)o.Value == 1), true, false), Times.Once); } /// /// Verifies that the Map method persists a "Complexity" with value 5 /// when an "Intravenous_Routes_Multivalue" entry of "VV central" (contributing 2) and a "Respiratory_Device_Multivalue" /// entry of "Ventilación mecánica Invasiva" (contributing 3) are provided, summing their mapped complexity contributions. /// /// [Test] public async Task Map_WithIntravenousRoutesAndRespiratoryDeviceMultiValueObservation_CalculatesComplexity_Return5() { // Arrange var patientId = ObjectId.GenerateNewId(); const string observationName = "Intravenous_Routes_Multivalue"; var observationValue = new[] { "VV central" }; var observation = new PatientObservation { Name = observationName, PatientId = patientId, Value = observationValue }; // value 2 var ventilationObs = new PatientObservation { Name = "Respiratory_Device_Multivalue", PatientId = patientId, Value = new[] { "Ventilación mecánica Invasiva" } }; //value 3 _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(observationName)))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([ventilationObs]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Medication_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("System_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Newborn_Weight")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Surgery_Multivalue")))).ReturnsAsync([]); // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Complexity") && o.Value is int && (int)o.Value == 5), // Esperamos 2 para "VV central" y 3 de "Ventilación mecánica Invasiva" según ComplexityValuesJson true, false), Times.Once); } /// /// Verifies that mapping a patient observation with the "Medication_Multivalue" name containing two /// medication values ("Adrenalina" and "Dopamina") results in a new "Complexity" observation being /// inserted with a calculated integer value of 4, while all related observation lookups (respiratory /// devices, intravenous routes, system, newborn weight, and surgery) return empty results. /// /// The instance passed implicitly to the /// test runner; not directly used as a method argument since this is a parameterless test method. /// [Test] public async Task Map_WithTwoMedicationMultiValueObservation_CalculatesComplexity_Return4() { // Arrange var patientId = ObjectId.GenerateNewId(); const string observationName = "Medication_Multivalue"; var observationValue = new[] { "Adrenalina", "Dopamina" }; var observation = new PatientObservation { Name = observationName, PatientId = patientId, Value = observationValue }; _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(observationName)))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("System_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Newborn_Weight")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Surgery_Multivalue")))).ReturnsAsync([]); // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Complexity") && o.Value is int && (int)o.Value == 4), // Esperamos 2 para "Adrenalina" y 2 para Dopamina true, false), Times.Once); } /// /// Verifies that when a patient has a system multivalue observation, medication multivalue observations, and a newborn weight observation, the mapping process calculates a complexity value of 9 and inserts it as a new "Complexity" observation. /// /// [Test] public async Task Map_WithSystemMedicationAndNewbornWeightMultiValueObservation_CalculatesComplexity_Return9() { // Arrange var patientId = ObjectId.GenerateNewId(); const string observationName = "System_Multivalue"; var observationValue = new[] { "Hipotermia" }; var observation = new PatientObservation { Name = observationName, PatientId = patientId, Value = observationValue }; //value 2 var medicationObs = new PatientObservation { Name = "Medication_Multivalue", PatientId = patientId, Value = new[] { "Isoprenalina", "Milrinona" } }; //value 1 + 2 var newbornWeight = new PatientObservation { Name = "Newborn_Weight", PatientId = patientId, Value = 800 }; //value 4 _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(observationName)))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Medication_Multivalue")))).ReturnsAsync([medicationObs]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Newborn_Weight")))).ReturnsAsync([newbornWeight]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Surgery_Multivalue")))).ReturnsAsync([]); // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Complexity") && o.Value is int && (int)o.Value == 9), // Esperamos 9 true, false), Times.Once); } /// /// Verifies that values mapped through the calculated observations pipeline /// produce a Complexity observation with value 4 when a newborn weight observation of 600 /// is provided and no previous observations exist for the respiratory, intravenous, medication, system, /// or surgery multivalue categories. /// /// [Test] public async Task Map_WithNewbornWeightObservation_CalculatesComplexity_Return4() { // Arrange var patientId = ObjectId.GenerateNewId(); const string observationName = "Newborn_Weight"; const string observationValue = "600"; // Ejemplo de peso var observation = new PatientObservation { Name = observationName, PatientId = patientId, Value = observationValue }; _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(observationName)))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Medication_Multivalue")))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("System_Multivalue")))) .ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Surgery_Multivalue")))) .ReturnsAsync([]); // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Complexity") && o.Value is int && (int)o.Value == 4), // Esperamos 4 para un peso entre 501 y 1000 según ComplexityValuesJson true, false), Times.Once); } /// /// Verifies that the Map method correctly calculates a complexity value of 13 when the input observation represents surgery, medication, and newborn weight data, by aggregating the per-section contribution of each observation type. /// /// [Test] public async Task Map_WithSurgeryMedicationMewbornWeightMultiValueObservation_CalculatesComplexity_Returns13() { // Arrange var patientId = ObjectId.GenerateNewId(); const string observationName = "Surgery_Multivalue"; var observationValue = new[] { "Cardiaca", "Toracica", "Ortopedia" }; var observation = new PatientObservation { Name = observationName, PatientId = patientId, Value = observationValue }; //value 4 + 3 + 1 var medicationObs = new PatientObservation { Name = "Medication_Multivalue", PatientId = patientId, Value = new[] { "Isoprenalina", "Milrinona" } }; //value 1 + 2 var newbornWeight = new PatientObservation { Name = "Newborn_Weight", PatientId = patientId, Value = 1800 }; //value 2 _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(observationName)))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Medication_Multivalue")))).ReturnsAsync([medicationObs]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("System_Multivalue")))).ReturnsAsync([]); _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains("Newborn_Weight")))).ReturnsAsync([newbornWeight]); // Act await _calculatedObservations.Map(observation); // Assert _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Complexity") && o.Value is int && (int)o.Value == 13), // Esperamos 13 true, false), Times.Once); } /// /// Tests that inserts a diff observation with the calculated difference and a combined pre/post observation when a pre-observation is provided and the matching post-observation is found through . /// /// [Test] public async Task CalculateSaturation_DiffObservation_WhenPreObservationExistsAndPostIsFound_InsertsDiffAndPrePost() { // Arrange var patientId = ObjectId.GenerateNewId(); const string preObservationName = "SpO2"; const string postObservationName = "SpO2_Post"; var currentTime = DateTime.UtcNow; var preObservation = new PatientObservation { PatientId = patientId, Name = preObservationName, Value = 98, Time = currentTime.AddMinutes(-5) }; var postObservation = new PatientObservation { PatientId = patientId, Name = postObservationName, Value = 95, Time = currentTime }; // Simula que FindLastObservations devuelve la observación post _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(preObservationName) && list.Contains(postObservationName)))) .ReturnsAsync([postObservation]); // Act await _calculatedObservations.Map(preObservation); // Assert // Verifica que se insertaron dos observaciones _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Diff" && o.Value.Equals(Math.Round(98.0 - 95.0, 2))), // Verifica la diferencia calculada true, true), Times.Once); _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Pre_Post" && o.Value.Equals("98/95")), true, true), Times.Once); } /// /// Verifies that when a post observation is processed and a matching pre observation is found, both a diff observation (with the computed difference value) and a combined pre/post observation (with the pre and post values) are inserted. /// /// [Test] public async Task CalculateSaturation_DiffObservation_WhenPostObservationExistsAndPreIsFound_InsertsDiffAndPrePost() { // Arrange var patientId = ObjectId.GenerateNewId(); const string preObservationName = "SpO2"; const string postObservationName = "SpO2_Post"; var currentTime = DateTime.UtcNow; var preObservation = new PatientObservation { PatientId = patientId, Name = preObservationName, Value = 98, Time = currentTime.AddMinutes(-5) }; var postObservation = new PatientObservation { PatientId = patientId, Name = postObservationName, Value = 95, Time = currentTime }; // Simula que FindLastObservations devuelve la observación pre _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(preObservationName) && list.Contains(postObservationName)))) .ReturnsAsync([preObservation]); // Act await _calculatedObservations.Map(postObservation); // Assert // Verifica que se insertaron dos observaciones _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Diff" && o.Value.Equals(Math.Round(98.0 - 95.0, 2))), true, true), Times.Once); _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Pre_Post" && o.Value.Equals("98/95")), true, true), Times.Once); } /// /// Verifies that does not insert new records when only the pre-observation is available for the patient and no matching post-observation is returned by . /// /// [Test] public async Task CalculateSaturation_DiffObservation_WhenOnlyPreObservationExists_DoesNotInsertNewObservations() { // Arrange var patientId = ObjectId.GenerateNewId(); const string preObservationName = "SpO2_Pre"; const string postObservationName = "SpO2_Post"; var currentTime = DateTime.UtcNow; var preObservation = new PatientObservation { PatientId = patientId, Name = preObservationName, Value = 98, Time = currentTime.AddMinutes(-5) }; // Simula que FindLastObservations devuelve solo la observación pre _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(preObservationName) && list.Contains(postObservationName)))) .ReturnsAsync([preObservation]); // Act await _calculatedObservations.Map(preObservation); // Assert // Verifica que no se insertaron nuevas observaciones _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that CalculateSaturation for a diff observation does not insert new /// entries when only the post-observation is found and the /// pre-observation is missing, ensuring no fallback insert occurs in this scenario. /// /// [Test] public async Task CalculateSaturation_DiffObservation_WhenOnlyPostObservationExists_DoesNotInsertNewObservations() { // Arrange var patientId = ObjectId.GenerateNewId(); const string preObservationName = "SpO2_Pre"; const string postObservationName = "SpO2_Post"; var currentTime = DateTime.UtcNow; var postObservation = new PatientObservation { PatientId = patientId, Name = postObservationName, Value = 95, Time = currentTime }; // Simula que FindLastObservations devuelve solo la observación post _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(preObservationName) && list.Contains(postObservationName)))) .ReturnsAsync([postObservation]); // Act await _calculatedObservations.Map(postObservation); // Assert // Verifica que no se insertaron nuevas observaciones _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that the saturation difference calculation correctly handles pre and post values that differ, producing a "SpO2_Diff" observation with the numeric difference (7.4) and a "SpO2_Pre_Post" observation with both values formatted as "99,5/92,1". /// /// [Test] public async Task CalculateSaturation_DiffObservation_WithDifferentPrePostValues_CalculatesCorrectDifference() { // Arrange var patientId = ObjectId.GenerateNewId(); const string preObservationName = "SpO2"; const string postObservationName = "SpO2_Post"; var currentTime = DateTime.UtcNow; var preObservation = new PatientObservation { PatientId = patientId, Name = preObservationName, Value = 99.5, Time = currentTime.AddMinutes(-5) }; var postObservation = new PatientObservation { PatientId = patientId, Name = postObservationName, Value = 92.1, Time = currentTime }; // Simula que FindLastObservations devuelve la observación post _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(preObservationName) && list.Contains(postObservationName)))) .ReturnsAsync([postObservation]); // Act await _calculatedObservations.Map(preObservation); // Assert // Verifica la diferencia calculada correctamente _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Diff" && o.Value.Equals(7.4)), true, true), Times.Once); _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Pre_Post" && o.Value.Equals("99,5/92,1")), true, true), Times.Once); } /// /// Verifies that when mapping a pre-observation whose is non-numeric, the /// CalculateSaturation logic treats the pre-value as 0 when computing the difference against the latest /// matching post-observation returned by . /// Confirms that a SpO2_Diff observation is inserted with the value 0 - post rounded to two decimals, /// and a SpO2_Pre_Post observation is inserted concatenating the raw pre-value and post-value. /// /// [Test] public async Task CalculateSaturation_DiffObservation_WithNonNumericPreValue_TreatsAsZero() { // Arrange var patientId = ObjectId.GenerateNewId(); const string preObservationName = "SpO2"; const string postObservationName = "SpO2_Post"; var currentTime = DateTime.UtcNow; var preObservation = new PatientObservation { PatientId = patientId, Name = preObservationName, Value = "TextoNoNumerico", Time = currentTime.AddMinutes(-5) }; var postObservation = new PatientObservation { PatientId = patientId, Name = postObservationName, Value = "95", Time = currentTime }; // Simula que FindLastObservations devuelve la observación post _mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is>(list => list.Contains(preObservationName) && list.Contains(postObservationName)))) .ReturnsAsync([postObservation]); // Act await _calculatedObservations.Map(preObservation); // Assert // Verifica que la diferencia se calcula como 0 - 95 = -95 _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Diff" && o.Value.Equals(Math.Round(0 - 95.0, 2))), true, true), Times.Once); _mockObservationService.Verify(x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name == "SpO2_Pre_Post" && o.Value.Equals("TextoNoNumerico/95")), true, true), Times.Once); } /// /// Verifies that mapping a patient treatment with no placer order returns the original treatment unchanged. /// /// [Test] public async Task Map_TreatmentWithNoPlacerOrder_ReturnsOriginalTreatment() { // Arrange var treatment = new PatientTreatment { PlacerOrder = null }; // Act var result = await _calculatedObservations.Map(treatment); // Assert Assert.That(result, Is.SameAs(treatment)); Assert.That(treatment.PlacerOrder, Is.Null); } /// /// Verifies that mapping a treatment which has active older treatments sets the order control to XO /// (cancel as a result of a new order being accepted) and does not insert a new observation. /// /// [Test] public async Task Map_TreatmentWithActiveOlderTreatments_SetsOrderControlToXO() { // Arrange var patientId = ObjectId.GenerateNewId(); const string orderIdentifier = "ORD123"; var treatment = new PatientTreatment { PatientId = patientId, PlacerOrder = new Entity { EntityIdentifier = orderIdentifier } }; var oldTreatments = new List { new() }; _treatmentServiceMock.Setup(x => x.GetActiveTreatmentsByPatient(patientId)).ReturnsAsync(oldTreatments); // Act var result = await _calculatedObservations.Map(treatment); // Assert Assert.That(result.OrderControl, Is.EqualTo(OrderControlType.Xo)); _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that when mapping a patient treatment with no active older treatments, the resulting order control is set to and no patient observation is inserted. /// /// [Test] public async Task Map_TreatmentWithNoActiveOlderTreatments_SetsOrderControlToNW() { // Arrange var patientId = ObjectId.GenerateNewId(); const string orderIdentifier = "ORD123"; var treatment = new PatientTreatment { PatientId = patientId, PlacerOrder = new Entity { EntityIdentifier = orderIdentifier } }; _treatmentServiceMock.Setup(x => x.GetActiveTreatmentsByPatient(patientId)).ReturnsAsync([]); // Act var result = await _calculatedObservations.Map(treatment); // Assert Assert.That(result.OrderControl, Is.EqualTo(OrderControlType.Nw)); _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that when a patient treatment has an end time set, mapping it sets the order control to and does not insert a new observation. /// /// [Test] public async Task Map_TreatmentWithEndTimeSet_SetsOrderControlToDC() { // Arrange var patientId = ObjectId.GenerateNewId(); const string orderIdentifier = "ORD123"; var treatment = new PatientTreatment { PatientId = patientId, PlacerOrder = new Entity { EntityIdentifier = orderIdentifier }, EndTime = DateTime.UtcNow.AddHours(1) }; _treatmentServiceMock.Setup(x => x.GetActiveTreatmentsByPatient(patientId)).ReturnsAsync([]); // Act var result = await _calculatedObservations.Map(treatment); // Assert Assert.That(result.OrderControl, Is.EqualTo(OrderControlType.Dc)); _mockObservationService.Verify( x => x.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } /// /// Verifies that mapping a whose is set yields a result with , overriding the order control that would otherwise be derived from the patient's previously active treatments. /// /// A that completes when the assertions have been evaluated. /// [Test] public async Task Map_TreatmentWithEndTimeSet_OverridesOrderControlFromOldTreatments() { // Arrange var patientId = ObjectId.GenerateNewId(); const string orderIdentifier = "ORD123"; var treatment = new PatientTreatment { PatientId = patientId, PlacerOrder = new Entity { EntityIdentifier = orderIdentifier }, EndTime = DateTime.UtcNow.AddHours(1) }; var oldTreatments = new List { new() }; _treatmentServiceMock.Setup(x => x.GetActiveTreatmentsByPatient(patientId)).ReturnsAsync(oldTreatments); // Act var result = await _calculatedObservations.Map(treatment); // Assert // Aunque había tratamientos antiguos, EndTime debería priorizar OrderControlType.DC Assert.That(result.OrderControl, Is.EqualTo(OrderControlType.Dc)); } /// /// Verifies that the map operation inserts an observation when the supplied carries a medication code. The test arranges a treatment with a single requested give code, configures the treatment, medicine, and observation services to return an existing active treatment list, the matching , and no previous observations; then asserts that the resulting is and that the observation service is invoked once with a whose name equals "Medication_Multivalue" and whose value is a array of length one containing the medication text. /// /// [Test] public async Task Map_TreatmentWithMedication_InsertObservation() { // Arrange var patientId = ObjectId.GenerateNewId(); const string orderIdentifier = "ORD123"; var code = new Code { Identifier = "16323", CodingSystem = "CCC", Text = "Amiodarona vo" }; var medication = new Medicine { Name = code.Text, Codes = [code.Identifier], Type = ["Medication"], Group = ["Antiarrítmicos"] }; var treatment = new PatientTreatment { PatientId = patientId, PlacerOrder = new Entity { EntityIdentifier = orderIdentifier }, RequestedGiveCodes = [code] }; var oldTreatments = new List { new() }; _treatmentServiceMock.Setup(x => x.GetActiveTreatmentsByPatient(patientId)).ReturnsAsync(oldTreatments); _medicineServiceMock.Setup(m => m.GetByCode(code.Identifier)).ReturnsAsync(medication); _mockObservationService.Setup(s => s.FindLastObservations(It.IsAny(), 1, It.IsAny>())) .ReturnsAsync([]); // Act var result = await _calculatedObservations.Map(treatment); // Assert //Assert.That(result,Is.Null); Assert.That(result.OrderControl, Is.EqualTo(OrderControlType.Xo)); _mockObservationService.Verify( x => x.InsertObservation(It.Is(o => o.PatientId == patientId && o.Name != null && o.Name.Equals("Medication_Multivalue") && o.Value.GetType() == typeof(string[]) && ((string[])o.Value).Length == 1 && ((string[])o.Value)[0].ToString() == "Amiodarona vo" ), true, true), Times.Once); } }