Files

2401 lines
86 KiB
C#

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;
[TestFixture]
public class CalculatedObservationsTest
{
[SetUp]
public void Setup()
{
_mockObservationService = new Mock<IObservationService>();
_medicineServiceMock = new Mock<IMedicineService>();
_treatmentServiceMock = new Mock<ITreatmentService>();
_logger = new Mock<ILogger<CalculatedObservations>>();
//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<ApiSettings>(
$$"""
{
"MappingInterventions": {{mappingInterventionsJson}},
"ComplexityMappingObservation": {{complexityValuesJson}}
}
"""
);
if (apiSettings == null) return;
// Mock IOptions<ApiSettings> to return our populated ApiSettings
_mockApiSettings = new Mock<IOptions<ApiSettings>>();
_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<IObservationService>(() => _mockObservationService.Object));
serviceCollection.AddSingleton(new Lazy<IMedicineService>(() => _medicineServiceMock.Object));
serviceCollection.AddSingleton(new Lazy<ITreatmentService>(() => _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<IObservationService> _mockObservationService;
private Mock<IMedicineService> _medicineServiceMock;
private Mock<ITreatmentService> _treatmentServiceMock;
private Mock<ILogger<CalculatedObservations>> _logger;
private Mock<IOptions<ApiSettings>> _mockApiSettings;
private MappingUtils _mappingUtils;
private CalculatedObservations _calculatedObservations;
[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<List<string>>()))
.ReturnsAsync([]); // Simulate no existing multivalue observation
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(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);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()),
Times.Never);
}
[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<string>>(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<PatientObservation>()),
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<PatientObservation>(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);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(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<bool>(), It.IsAny<bool>()),
Times.Never);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>()),
Times.Never);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(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);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(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);
}
[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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()),
Times.Never);
// Verify that no existing observation was updated
_mockObservationService.Verify(
x => x.UpdateObservation(It.IsAny<PatientObservation>()),
Times.Never);
}
[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<string>>(list =>
list.Contains(observationName))))
.ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Intravenous_Routes_Multivalue"))))
.ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Medication_Multivalue"))))
.ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("System_Multivalue"))))
.ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Newborn_Weight"))))
.ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Surgery_Multivalue"))))
.ReturnsAsync([]);
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(o =>
o.PatientId == patientId &&
o.Name != null &&
o.Name.Equals("Complexity") &&
o.Value is int &&
(int)o.Value == 1),
true, false),
Times.Once);
}
[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<string>>(list =>
list.Contains(observationName)))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([ventilationObs]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Medication_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("System_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Newborn_Weight")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Surgery_Multivalue")))).ReturnsAsync([]);
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(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);
}
[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<string>>(list =>
list.Contains(observationName)))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("System_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Newborn_Weight")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Surgery_Multivalue")))).ReturnsAsync([]);
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(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);
}
[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<string>>(list =>
list.Contains(observationName)))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Medication_Multivalue")))).ReturnsAsync([medicationObs]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Newborn_Weight")))).ReturnsAsync([newbornWeight]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Surgery_Multivalue")))).ReturnsAsync([]);
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(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);
}
[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<string>>(list => list.Contains(observationName))))
.ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1,
It.Is<List<string>>(list => list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1,
It.Is<List<string>>(list => list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x =>
x.FindLastObservations(patientId, 1,
It.Is<List<string>>(list => list.Contains("Medication_Multivalue"))))
.ReturnsAsync([]);
_mockObservationService.Setup(x =>
x.FindLastObservations(patientId, 1, It.Is<List<string>>(list => list.Contains("System_Multivalue"))))
.ReturnsAsync([]);
_mockObservationService.Setup(x =>
x.FindLastObservations(patientId, 1, It.Is<List<string>>(list => list.Contains("Surgery_Multivalue"))))
.ReturnsAsync([]);
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(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);
}
[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<string>>(list =>
list.Contains(observationName)))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Respiratory_Device_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Intravenous_Routes_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Medication_Multivalue")))).ReturnsAsync([medicationObs]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("System_Multivalue")))).ReturnsAsync([]);
_mockObservationService.Setup(x => x.FindLastObservations(patientId, 1, It.Is<List<string>>(list =>
list.Contains("Newborn_Weight")))).ReturnsAsync([newbornWeight]);
// Act
await _calculatedObservations.Map(observation);
// Assert
_mockObservationService.Verify(
x => x.InsertObservation(It.Is<PatientObservation>(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);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(o =>
o.PatientId == patientId &&
o.Name == "SpO2_Pre_Post" &&
o.Value.Equals("98/95")), true, true),
Times.Once);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(o =>
o.PatientId == patientId &&
o.Name == "SpO2_Pre_Post" &&
o.Value.Equals("98/95")), true, true),
Times.Once);
}
[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<string>>(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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never);
}
[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<string>>(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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never);
}
[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<string>>(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<PatientObservation>(o =>
o.PatientId == patientId &&
o.Name == "SpO2_Diff" &&
o.Value.Equals(7.4)),
true, true), Times.Once);
_mockObservationService.Verify(x => x.InsertObservation(It.Is<PatientObservation>(o =>
o.PatientId == patientId &&
o.Name == "SpO2_Pre_Post" &&
o.Value.Equals("99,5/92,1")), true, true),
Times.Once);
}
[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<string>>(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<PatientObservation>(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<PatientObservation>(o =>
o.PatientId == patientId &&
o.Name == "SpO2_Pre_Post" &&
o.Value.Equals("TextoNoNumerico/95")), true, true),
Times.Once);
}
[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);
}
[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<PatientTreatment> { 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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never);
}
[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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never);
}
[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<PatientObservation>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never);
}
[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<PatientTreatment> { 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));
}
[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<PatientTreatment> { 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<ObjectId>(), 1, It.IsAny<List<string>>()))
.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<PatientObservation>(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);
}
}