using adas_core.Application.Customizations.H12O.UCIN;
using adas_core.Application.Services.Interfaces;
using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Moq;
using Options = Microsoft.Extensions.Options.Options;
namespace adas_core.Test.Customizations.H12O.UCIN;
///
/// Represents a test fixture that contains unit tests for calculated observations, executing with an order priority of 2 relative to other test fixtures.
///
///
/// This fixture is annotated with to mark it as a container of NUnit test methods, and with to control its execution sequence within the test suite.
///
///
[TestFixture]
[Order(2)]
public class CalculatedObservationsTest
{
///
/// Initializes the test fixture for by creating mocked instances of
/// , , ,
/// , and , configuring
/// settings for medication bolus, transcutaneous, regional brain saturation,
/// electroencephalogram, respiratory, high-frequency ventilation, invasive ventilation, non-invasive
/// ventilation, one-lung isolation, and ECMO codes, and registering all dependencies in a
/// so that a fully wired instance
/// is produced for each test.
///
///
[SetUp]
public void Setup()
{
_observationServiceMock = new Mock();
_configOservationServiceMock = new Mock();
_medicineServiceMock = new Mock();
_treatmentServiceMock = new Mock();
_logger = new Mock>();
_optionsApiSettings = Options.Create(_apiSettings);
_optionsApiSettings.Value.MedicationBolus = ["18851000140100", "21011000140105"];
_optionsApiSettings.Value.IntravenousLinesCode = ["10546003"];
_optionsApiSettings.Value.Transcutaneous = ["151756", "151760"];
_optionsApiSettings.Value.RegionalBrainSaturation = ["194908", "194909"];
_optionsApiSettings.Value.Electroencephalogram = ["42803009"];
_optionsApiSettings.Value.Respiratory = ["361110005", "84481000140102"];
_optionsApiSettings.Value.HighFrequencyVentilation = ["PC-HFO"];
_optionsApiSettings.Value.InvasiveVentilation =
[
"A/C (S.I.P.P.V. )", "A/C (S.I.P.P.V.) + V.G.", "PRVC", "PC-SIMV", "SIMV-PRVC", "PC-AC", "SIMV",
"SIMV-PC", "S.I.M.V.", "PC-CMV", "SIPPV", "PC"
];
_optionsApiSettings.Value.NonInvasiveVentilation = ["DUOPAP", "NCPAP"];
_optionsApiSettings.Value.Oni = ["84481000140102", "416362002"];
_optionsApiSettings.Value.Ecmo = ["705923009"];
var serviceCollection = new ServiceCollection();
//serviceCollection.AddSingleton(_observationServiceMock.Object);
serviceCollection.AddSingleton(new Lazy(() => _observationServiceMock.Object));
serviceCollection.AddSingleton(
new Lazy(() => _configOservationServiceMock.Object));
serviceCollection.AddSingleton(_medicineServiceMock.Object);
serviceCollection.AddSingleton(new Lazy(() => _treatmentServiceMock.Object));
serviceCollection.AddSingleton(_optionsApiSettings);
serviceCollection.AddSingleton(_logger.Object);
var serviceProvider = serviceCollection.BuildServiceProvider();
_calculatedObservations = new CalculatedObservations(serviceProvider);
}
private CalculatedObservations _calculatedObservations;
private Mock _medicineServiceMock;
private Mock _observationServiceMock;
private Mock _configOservationServiceMock;
private Mock _treatmentServiceMock;
private Mock> _logger;
private readonly ApiSettings _apiSettings = new()
{
ConfigObservation = new ConfigObservationSettings
{
IgnoreUnknownObservation = false
}
};
private IOptions _optionsApiSettings;
///
/// Verifies that processing a new that contains a medicine—matched by code to a known with an assigned —for the first time for a patient (no prior observations and no active treatments) results in a named Medication with value 1 associated to the treatment's .
///
///
[Test]
public async Task Calculate_First_Medicine_Observation_With_Type_Should_Return_1()
{
//Entra un tratamiento por primera vez con una medicina, se crea una observación medication con valor 1
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Nw,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Type = [MedicineEnum.Types.MuscleRelaxant.ToString()],
Name = "cisataracurio"
};
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, true));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(new List().AsEnumerable());
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Medication" && (int)arg.Value == 1 && arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a new containing a medicine, when no prior
/// observations or active treatments exist for the patient, results in the insertion of a
/// named "Medication" with value 0 for the patient.
///
///
[Test]
public async Task Calculate_First_Medicine_Observation_With_Out_Type_Should_Return_1()
{
//Entra un tratamiento por primera vez con una medicina, se crea una observación medication con valor 1
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Nw,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "cisataracurio"
};
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, true));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(new List().AsEnumerable());
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Medication" && (int)arg.Value == 0 && arg.PatientId == patientId
), true, false));
}
///
/// Verifies that when a new with an OrderControl of is mapped for the first time and contains a medicine code, a with name Medication and value 1 is inserted for the patient.
///
///
[Test]
public async Task Calculate__Medicine_Observation_New_Type_Should_Sum_1()
{
//Entra un tratamiento por primera vez con una medicina, se crea una observación medication con valor 1
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Nw,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "cisataracurio",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
};
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(new List().AsEnumerable());
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, true));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Medication" && (int)arg.Value == 1 && arg.PatientId == patientId
), true, false));
}
///
/// Verifies that when a new is mapped and a prior of name "Medication" with value 0 already exists for the patient, the calculated observations service inserts a new observation with value 1 (the sum of the existing value 0 plus the new contribution).
///
///
[Test]
public async Task Calculate__Medicine_Observation_Type_Already_Exists_Should_Sum_0()
{
//Entra un tratamiento por primera vez con una medicina, se crea una observación medication con valor 1
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Nw,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "cisataracurio",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
};
var activeMedicines = new List
{
new()
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "Biotin",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
}
};
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(activeMedicines.AsEnumerable());
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, true));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Value = 0,
Name = "Medication"
}
]);
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Medication"
&& (int)arg.Value == 1
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that when a medicine observation of type already exists for the patient,
/// subtracts the existing value and inserts a new observation with a resulting value of 0.
///
/// A representing the asynchronous unit test execution.
///
[Test]
public async Task Calculate__Medicine_Observation_DC_Type_Already_Exists_Should_Subtract_0()
{
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Dc,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "cisataracurio",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
};
var activeMedicines = new List
{
new()
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "cisataracurio",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
}
};
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(activeMedicines.AsEnumerable());
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, true));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([
new PatientObservation(patientId, 1, "Medication")
]);
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "ERMedication" && (int)arg.Value == 0 && arg.PatientId == patientId
), true, false));
}
///
/// Verifies that when a treatment is processed and the patient has two active medicines, a Medication observation is inserted with the last observation value decremented by one (2 - 1 = 1).
///
///
[Test]
public async Task Calculate__Medicine_Observation_DC_OF_TYPE_WITH_TWO_MEDICINES_Should_Subtract_0()
{
//Entra un tratamiento por primera vez con una medicina, se crea una observación medication con valor 1
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Dc,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Name = "cisataracurio",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
};
var activeMedicines = new List
{
new()
{
Codes = ["12345"],
Name = "cisataracurio",
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
},
new()
{
Codes = ["12345"],
Name = "Lipoic acid",
Group = [MedicineEnum.Group.DoubleSignature.ToString()],
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
}
};
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(activeMedicines.AsEnumerable());
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, false));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Value = 2,
Name = "Medication"
}
]);
//_observationServiceMock.Setup(o => o.InsertObservation(It.Is(arg =>
// (arg.Name == "ERMedication" && (int)arg.Value == 1)
// && arg.PatientId == patientId
//), true, true));
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Medication"
&& (int)arg.Value == 1
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a new containing a medicine without a defined type results in the insertion of a named "Medication" with a value of 1 for the associated patient.
///
///
[Test]
public async Task Calculate_Medicine_Observation_New_Medicine_Without_Type_Should_Insert_Medication_1_point()
{
//Entra un tratamiento por primera vez con una medicina, se crea una observación medication con valor 1
var patientId = ObjectId.GenerateNewId();
var treatment =
new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Nw,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "12345" }],
OrderStatus = "A",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
var medicine =
new Medicine
{
Codes = ["12345"],
Name = "Betaine"
};
var activeMedicines = new List
{
new()
{
Codes = ["12345"],
Name = "cisataracurio",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
},
new()
{
Codes = ["12345"],
Name = "Lipoic acid",
Type = [MedicineEnum.Types.AdrenalineNoradrenaline.ToString()]
}
};
var expectedMedication = new PatientObservation
{
PatientId = patientId,
Value = 0,
Name = "Medication"
};
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "12345" }))
.ReturnsAsync([medicine]);
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(activeMedicines.AsEnumerable());
_observationServiceMock.Setup(o => o.InsertObservation(It.IsAny(), true, true));
_observationServiceMock.Setup(o => o.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([expectedMedication]);
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Medication"
&& (int)arg.Value == 1
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that . inserts a new
/// observation with a score of 5 when processing the first
/// intravenous arterial observation for a patient, given that no previous observations exist.
///
///
[Test]
public async Task Calculate_First_Intravenous_Arterial_Observation_Should_Return_5()
{
var patientId = ObjectId.GenerateNewId();
var obs = new PatientObservation
{
PatientId = patientId,
Value = new PatientIntravenousLinesValue
{
Action = "Insert",
Duration = "7",
InsertTime = DateTime.Now,
Location = "Rodilla",
Type = "Catéter arterial"
},
Name = "IntravenousLinesObs"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
_observationServiceMock.Setup(t => t.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync([]);
await _calculatedObservations.Map(obs, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "IntravenousLines"
&& (int)arg.Value == 5
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that when a previous for the same patient and location has already been removed, the intravenous calculation performed by produces a result of 0.
///
///
[Test]
public async Task Calculate_Intravenous_Obs_Already_Exist_Removed_Should_Return_0()
{
var patientId = ObjectId.GenerateNewId();
var now = DateTime.Now;
var obs = new PatientObservation
{
PatientId = patientId,
Value = new PatientIntravenousLinesValue
{
Action = "Insert",
Duration = "7",
InsertTime = now,
Location = "Rodilla",
Type = "Catéter arterial",
RemoveTime = DateTime.Now.AddDays(1)
},
Name = "IntravenousLinesObs"
};
_observationServiceMock.Setup(t => t.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync([]);
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Value = new PatientIntravenousLinesValue
{
Action = "Insert",
Duration = "7",
InsertTime = now,
Type = "Catéter arterial",
Location = "Rodilla"
},
Name = "IntravenousLinesObs"
}
]);
await _calculatedObservations.Map(obs, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "IntravenousLines"
&& (int)arg.Value == 0
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a with an whose type and location match the last stored observation for the same patient does not trigger an insertion of a calculated "IntravenousLines" observation.
///
///
[Test]
public async Task Calculate_Intravenous_two_observations_of_same_type_and_same_location_should_return_null()
{
var patientId = ObjectId.GenerateNewId();
var now = DateTime.Now;
var obs = new PatientObservation
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Location = "Rodilla",
Type = "Catéter arterial"
}
};
_observationServiceMock.Setup(t => t.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Type = "Catéter arterial",
Location = "Rodilla"
},
Name = "IntravenousLinesObs"
}
]);
await _calculatedObservations.Map(obs, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "IntravenousLines"
&& (int)arg.Value == 5
&& arg.PatientId == patientId
), true, true), Times.Never);
}
///
/// Verifies that when a new PatientObservation of type "IntravenousLinesObs" is processed alongside a previous observation of the same type for the same patient, the calculator produces a derived PatientObservation named "IntravenousLines" with a value of 10.
///
///
[Test]
public async Task Calculate_Intravenous_two_observations_of_same_type_should_return_10()
{
var patientId = ObjectId.GenerateNewId();
var now = DateTime.Now;
var obs = new PatientObservation
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Location = "Rodilla",
Type = "Catéter arterial"
}
};
_observationServiceMock.Setup(t => t.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Type = "Catéter arterial",
Location = "Codo"
}
}
]);
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(obs, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "IntravenousLines"
&& (int)arg.Value == 10
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that the method limits the calculated sum of observations to a maximum value of ten when the total exceeds that threshold.
///
///
[Test]
public async Task Calculate_Intravenous_sum_more_than_10_should_limit_to_ten()
{
var patientId = ObjectId.GenerateNewId();
var now = DateTime.Now;
var obs = new PatientObservation
{
PatientId = patientId,
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Location = "Rodilla Izd.",
Type = "Catéter arterial"
},
Name = "IntravenousLinesObs"
};
var patientObservations = new List
{
new()
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Type = "Catéter arterial",
Location = "Rodilla Der."
}
},
new()
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Type = "Catéter PICC",
Location = "Brazo"
}
}
};
_observationServiceMock.Setup(t => t.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync(patientObservations);
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(obs, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "IntravenousLines"
&& (int)arg.Value == 10
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a new with a "Catéter línea media" type, when two prior intravenous lines exist (one "Catéter EPICUTÁNEO PERIFÉRICO" and one "Catéter Venoso PERIFÉRICO"), inserts an named "IntravenousLines" with a summed value of 5 for the given .
///
///
[Test]
public async Task Calculate_Intravenous_sum_one_middle_line_and_two_Peripheral_should_return_5()
{
var patientId = ObjectId.GenerateNewId();
var now = DateTime.Now;
var obs = new PatientObservation
{
PatientId = patientId,
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Location = "Rodilla Izd.",
Type = "Catéter línea media"
},
Name = "IntravenousLinesObs"
};
_observationServiceMock.Setup(t => t.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Type = "Catéter EPICUTÁNEO PERIFÉRICO",
Location = "Rodilla Der."
}
},
new PatientObservation
{
PatientId = patientId,
Name = "IntravenousLinesObs",
Value = new PatientIntravenousLinesValue
{
Action = "Insertado",
Duration = "7",
InsertTime = now,
Type = "Catéter Venoso PERIFÉRICO",
Location = "Brazo"
}
}
]);
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(obs, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "IntravenousLines"
&& (int)arg.Value == 5
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that . produces a monitor observation with value 3 for a treatment containing the EEG code 42803009, based on the most recent transcutaneous and regional brain saturation observations retrieved for the patient.
///
///
[Test]
public async Task Calculate_Monitor_Transcuatenous_Regional_Brain_Saturation_and_enter_EEG_should_return_3()
{
var patientId = ObjectId.GenerateNewId();
var treatment = new PatientTreatment
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
OrderControl = OrderControlType.Nw,
PlacerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
FillerOrder = new Entity { EntityIdentifier = "100", NamespaceId = "CareVue" },
RequestedGiveCodes = [new Code { Identifier = "42803009" }],
OrderStatus = "NW",
OrderTime = DateTime.Now,
Notes = [],
Routes = []
};
_treatmentServiceMock.Setup(t => t.GetActiveTreatmentsByPatient(patientId))
.ReturnsAsync(new List().AsEnumerable());
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(new List { "42803009" }))
.ReturnsAsync([]);
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([
new PatientObservation
{
PatientId = patientId,
Code = "151756",
Name = "Transcutaneous",
Time = DateTime.Now
},
new PatientObservation
{
PatientId = patientId,
Code = "151760",
Name = "Transcutaneous",
Time = DateTime.Now
},
new PatientObservation
{
PatientId = patientId,
Code = "194908",
Name = "RegionalBrainSaturation",
Time = DateTime.Now
},
new PatientObservation
{
PatientId = patientId,
Code = "194909",
Name = "RegionalBrainSaturation",
Time = DateTime.Now
}
]);
await _calculatedObservations.Map(treatment);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Monitor"
&& (int)arg.Value == 3
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a ventilation with value OXIDO NITRICO 800 PPM MOL for a patient with no prior observations produces a derived named "Respiratory" with an integer value of 10.
///
///
[Test]
public async Task Calculate_Respiratory_INO_should_return_10()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "OXIDO NITRICO 800 PPM MOL",
Code = "84481000140102",
Name = "Tipo de ventilación",
CodingSystem = "SNM"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Respiratory"
&& (int)arg.Value == 10
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that calculates a respiratory value of 5 when the patient observation
/// represents a "V.A.F.O." (ventilación de alta frecuencia oscilatoria) entry coded as 361110005 in the SNM coding system,
/// using an empty list returned by .
///
/// A that completes when the assertions have been executed.
///
[Test]
public async Task Calculate_Respiratory_VAFO_should_return_5()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "V.A.F.O.",
Code = "361110005",
Name = "Tipo de ventilación",
CodingSystem = "SNM"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Respiratory"
&& (int)arg.Value == 5
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a with value "V.M.C." (ventilation type, SNOMED code "361110005") produces a calculated respiratory observation with value 3 for the same , when no previous observations are returned by the observation service.
///
///
[Test]
public async Task Calculate_Respiratory_VMC_should_return_3()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "V.M.C.",
Code = "361110005",
Name = "Tipo de ventilación",
CodingSystem = "SNM"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Respiratory"
&& (int)arg.Value == 3
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a with the ventilation type V.N.I. Ciclada (Non-Invasive Mechanical Ventilation) results in the insertion of a calculated respiratory observation with an integer value of 2 for the same patient.
///
///
[Test]
public async Task Calculate_Respiratory_VMNI_should_return_2()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "V.N.I. Ciclada",
Code = "361110005",
Name = "Tipo de ventilación",
CodingSystem = "SNM"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Respiratory"
&& (int)arg.Value == 2
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that when a with name "Tipo de ventilación" and value "Bajo Flujo" is mapped, a calculated respiratory observation is inserted with value 1 for the associated patient.
///
///
[Test]
public async Task Calculate_Respiratory_Nassal_Canulas_Bajo_Flujo_should_return_2()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "Bajo Flujo",
Code = "361110005",
Name = "Tipo de ventilación",
CodingSystem = "SNM"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Respiratory"
&& (int)arg.Value == 1
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that returns a respiratory value of 1 when the patient observation indicates an "Alto Flujo" (high flow nasal cannula) ventilation type, identified by "361110005" in the SNM coding system.
///
///
[Test]
public async Task Calculate_Respiratory_Nassal_Canulas_Alto_Flujo_should_return_1()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "Alto Flujo",
Code = "361110005",
Name = "Tipo de ventilación",
CodingSystem = "SNM"
};
_observationServiceMock.Setup(t => t.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertObservation(It.Is(arg =>
arg.Name == "Respiratory"
&& (int)arg.Value == 1
&& arg.PatientId == patientId
), true, false));
}
///
/// Verifies that mapping a with the name "Resp_Mode" and the value "PC-AC"
/// produces a calculated observation for "Resp_Type" using the "ADAS" coding system with the
/// value.
///
///
[Test]
public async Task Calculate_Ventilation_Mode_Returns_INVASIVE()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "PC-AC",
Name = "Resp_Mode"
};
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertIfChanged("Resp_Type", It.Is(arg =>
arg.Name == "Resp_Type" &&
arg.CodingSystem == "ADAS" &&
arg.Value.ToString() == RespirationType.Invasive.ToString()
), true, true));
}
///
/// Verifies that mapping a with the name Resp_Mode and value DUOPAP triggers an insert of a new observation named Resp_Type using the value.
///
///
[Test]
public async Task Calculate_Ventilation_Mode_Returns_NON_INVASIVE()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "DUOPAP",
Name = "Resp_Mode"
};
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertIfChanged("Resp_Type", It.Is(arg =>
arg.Name == "Resp_Type" &&
arg.CodingSystem == "ADAS" &&
arg.Value.ToString() == RespirationType.NonInvasive.ToString()
), true, true));
}
///
/// Verifies that mapping a with the Resp_Mode name and the PC-HFO value produces a calculated observation named Resp_Type using the ADAS coding system whose value resolves to .
///
///
[Test]
public async Task Calculate_Ventilation_Mode_Returns_HIGH_FREQUENCY()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "PC-HFO",
Name = "Resp_Mode"
};
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertIfChanged("Resp_Type", It.Is(arg =>
arg.Name == "Resp_Type" &&
arg.CodingSystem == "ADAS" &&
arg.Value.ToString() == RespirationType.HighFrequencyVentilation.ToString()
), true, true));
}
///
/// Verifies that when a with "Resp_Mode" and "VENTAPNEA" is mapped, the calculated observation for "Resp_Type" is produced with using the "ADAS" coding system.
///
/// A representing the asynchronous test execution.
///
[Test]
public async Task Calculate_Ventilation_Mode_Returns_NONE()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Value = "VENTAPNEA",
Name = "Resp_Mode"
};
await _calculatedObservations.Map(observation, false);
_observationServiceMock.Verify(o => o.InsertIfChanged("Resp_Type", It.Is(arg =>
arg.Name == "Resp_Type" &&
arg.CodingSystem == "ADAS" &&
arg.Value.ToString() == RespirationType.None.ToString()
), true, true));
}
///
/// Verifies that CalculateOxygenationIndex retrieves the latest AirPressure_Mean, FiO2, and PaO2
/// values for the patient via FindLastObservations and inserts a new
/// named "Oxygenation_Index" with the correctly computed value of 1250.
///
///
[Test]
public async Task CalculateOxygenationIndex_ShouldInsertCorrectObservation()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
PatientId = patientId,
Name = "FiO2",
Value = 50
};
var observations = new List
{
new() { Name = "AirPressure_Mean", Value = 20, PatientId = patientId },
new() { Name = "FiO2", Value = 50, PatientId = patientId },
new() { Name = "PaO2", Value = 80, PatientId = patientId }
};
_observationServiceMock.Setup(s => s.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync(observations);
await _calculatedObservations.CalculateOxygenationIndex(observation);
_observationServiceMock.Verify(s => s.InsertObservation(
It.Is(o =>
o.Name == "Oxygenation_Index" && o.PatientId == patientId && (int)o.Value == 1250),
It.IsAny(), It.IsAny()));
}
///
/// Verifies that inserts a new
/// with the name Respiratory for the patient when the most recent
/// retrieved observation matches the expected respiratory mode (Resp_Mode), and returns the
/// original .
///
///
[Test]
public async Task CalculateAsistResp_ShouldUpdateObservation_WhenConditionsMet()
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
PatientId = patientId,
Name = "ONi",
Value = "valor",
Time = DateTime.Now,
Code = "codigo"
};
var lastAsistResp = new PatientObservation
{
PatientId = patientId,
Name = "Resp_Mode",
Value = "valor",
Time = DateTime.Now.AddMinutes(-10)
};
_observationServiceMock.Setup(s => s.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([lastAsistResp]);
var result = await _calculatedObservations.CalculateAsistResp(observation);
_observationServiceMock.Verify(s => s.InsertObservation(
It.Is(o => o.Name == "Respiratory" && o.PatientId == patientId),
It.IsAny(), It.IsAny()));
Assert.That(result, Is.EqualTo(observation));
}
// [TestCase("valorHFV", RespirationType.HIGH_FREQUENCY_VENTILATION)]
// [TestCase("valorInvasive", RespirationType.INVASIVE)]
// [TestCase("valorNonInvasive", RespirationType.NON_INVASIVE)]
// [TestCase("valorNone", RespirationType.NONE)]
///
/// Verifies that maps the supplied input value to the expected and persists it as a Resp_Type observation via .
/// Handles the localized input cases valorHFV (mapped to PC-HFO), valorInvasive (mapped to PRVC), and valorNonInvasive (mapped to DUOPAP); any other value falls back to .
///
/// The raw Resp_Mode input value from the observation; when it does not match a known ventilation label, it is replaced by .
/// The expected to be inserted as Resp_Type after the calculation runs.
///
public async Task CalculateVentilationMode_ShouldInsertCorrectRespType(string value,
RespirationType expectedRespType)
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
PatientId = patientId,
Name = "Resp_Mode",
Time = DateTime.Now,
Value = value switch
{
"valorHFV" => "PC-HFO",
"valorInvasive" => "PRVC",
"valorNonInvasive" => "DUOPAP",
_ => expectedRespType
}
};
await _calculatedObservations.CalculateVentilationMode(observation);
_observationServiceMock.Verify(s => s.InsertIfChanged(
"Resp_Type",
It.Is(o =>
o.PatientId == patientId && o.Name == "Resp_Type" && o.Value.ToString() == expectedRespType.ToString()),
It.IsAny(), It.IsAny()));
}
// [TestCase("TAm", 10, 12, ObservationStatus.Ok)]
// [TestCase("Age_Gestational", 1, 2, ObservationStatus.Alert)]
// [TestCase("Age_Gestational", 1, 12, ObservationStatus.Ok)]
// [TestCase("Age_Gestational_Fixed", 5, 10, ObservationStatus.Ok)]
///
/// Verifies that the CalculateTAmAlert method updates the status of a TAm observation
/// to the expected when the observation name is "TAm", and inserts a new
/// TAm observation when the name is "Age_Gestational" or "Age_Gestational_Fixed".
///
/// The name of the observation under test, expected to be "TAm", "Age_Gestational", or "Age_Gestational_Fixed".
/// The numeric TAm value assigned to the observation and related grouped observations.
/// The numeric gestational age value used in the related grouped observations.
/// The expected used to assert the resulting observation status.
///
public async Task CalculateTAmAlert_ShouldUpdateStatusCorrectly(string observationName, int tamValue,
int gestationalAge, StatusEnum.Type expectedType)
{
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
PatientId = patientId,
Name = observationName,
Value = tamValue,
Time = DateTime.Now,
Status = expectedType
};
List groupedObservations = [];
switch (observationName)
{
case "TAm":
groupedObservations =
[
new PatientObservation
{
Name = "Age_Gestational", Value = gestationalAge, PatientId = patientId,
Time = DateTime.Now.AddMinutes(-10), Status = expectedType
},
new PatientObservation
{
Name = "Age_Gestational_Fixed", Value = gestationalAge, PatientId = patientId,
Time = DateTime.Now.AddMinutes(-10), Status = expectedType
}
];
break;
case "Age_Gestational":
case "Age_Gestational_Fixed":
groupedObservations =
[
new PatientObservation
{
Name = "Age_Gestational", Value = gestationalAge, PatientId = patientId,
Time = DateTime.Now.AddMinutes(-10), Status = expectedType
},
new PatientObservation
{
Name = "TAm", Value = tamValue, PatientId = patientId, Time = DateTime.Now.AddMinutes(-10),
Status = expectedType
}
];
break;
}
_observationServiceMock.Setup(s => s.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync(groupedObservations);
await _calculatedObservations.CalculateTAmAlert(observation);
if (observation.Name == "TAm")
Assert.That(observation.Status, Is.EqualTo(expectedType));
else
_observationServiceMock.Verify(s => s.InsertObservation(
It.Is(o => o.PatientId == patientId && o.Name == "TAm"),
It.IsAny(), It.IsAny()));
}
///
/// Verifies that the ParseWeight method correctly converts the units to "gr" and scales the value (multiplying by 1000) when given a valid with a numeric .
///
///
[Test]
public async Task ParseWeight_WhenValidObservation_ShouldConvertUnitsAndValue()
{
var obs = new PatientObservation
{
Value = 1.23
};
var result = await _calculatedObservations.ParseWeight(obs) as PatientObservation;
Assert.That(result, Is.Not.Null);
Action assertions = () =>
{
Assert.That(result!.Units, Is.EqualTo("gr"));
Assert.That(result.Value, Is.EqualTo(1230));
};
Assert.Multiple(assertions);
}
///
/// Verifies that ParseWeight handles non-numeric gracefully by returning the original unchanged.
///
///
[Test]
public async Task ParseWeight_WhenValueIsNotNumeric_ShouldHandleGracefullyAndReturnOriginal()
{
var obs = new PatientObservation
{
Value = "string"
};
var result = await _calculatedObservations.ParseWeight(obs);
Assert.That(result, Is.EqualTo(obs));
}
///
/// Verifies that the ParseWeight method returns the original unchanged when the observation cannot be converted to a PatientObservation, exercising the fallback behavior for invalid input types.
///
///
[Test]
public async Task ParseWeight_WhenInvalidObservation_ShouldReturnOriginal()
{
var obs = new BasePatientObservation(); // No es PatientObservation, por lo que no se puede convertir
var result = await _calculatedObservations.ParseWeight(obs);
Assert.That(result, Is.EqualTo(obs));
}
///
/// Verifies that when the patient temperature and the latest incubator temperature observation are both recent, CalculateTempGradient triggers an InsertObservation call exactly once to persist the computed Temp_Gradient value (incubator minus patient temperature).
///
///
[Test]
public async Task CalculateTempGradient_WhenTempPatientAndTempIncubatorAreRecent_ShouldCalculateGradient()
{
var now = DateTime.UtcNow;
var patientId = ObjectId.GenerateNewId();
var tempPatientObs = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "Temp_Patient",
Time = now,
Value = 36.5
};
var tempIncubatorObs = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "Temp_Incubator",
Time = now.AddMinutes(-10), // 10 minutos antes
Value = 37.0
};
var tempGradientObs = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "Temp_Gradient",
Time = now.AddSeconds(1),
Value = 37.0
};
_observationServiceMock.Setup(s => s.FindAnyWithSameDate(patientId, now, "Temp_Gradient"))
.ReturnsAsync([tempGradientObs]);
_observationServiceMock.Setup(s => s.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([tempIncubatorObs]);
_observationServiceMock.Setup(s => s.InsertObservation(
It.IsAny(),
It.IsAny(),
It.IsAny()
)).Callback((obs, _, _) =>
{
Action assertions = () =>
{
Assert.That(obs.Name, Is.EqualTo("Temp_Gradient"));
Assert.That(Math.Abs((double)obs.Value - (37.0 - 36.5)), Is.LessThan(0.001));
};
});
await _calculatedObservations.CalculateTempGradient(tempPatientObs);
_observationServiceMock.Verify(s => s.InsertObservation(
It.IsAny(),
It.IsAny(),
It.IsAny()
), Times.Once());
}
///
/// Verifies that the temperature gradient calculation does not persist a new
/// when the lookup for the complementary temperature reading returns no observations.
///
///
[Test]
public async Task CalculateTempGradient_WhenOneTemperatureIsMissing_ShouldNotCalculateGradient()
{
var patientId = ObjectId.GenerateNewId();
var tempPatientObs = new PatientObservation
{
PatientId = patientId,
Name = "Temp_Patient",
Time = DateTime.UtcNow,
Value = 36.5
};
// Configuramos el mock para que no devuelva ninguna observación para Temp_Incubator
_observationServiceMock.Setup(s => s.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.CalculateTempGradient(tempPatientObs);
_observationServiceMock.Verify(s => s.InsertObservation(
It.IsAny(),
It.IsAny(),
It.IsAny()
), Times.Never()); // Verificamos que InsertObservation no se llama
}
///
/// Verifies that the intravenous line observation calculation maps to "IntravenousLines", preserves , and ensures is not earlier than the current time when no prior intravenous lines observation exists.
///
///
[Test]
public async Task CalculateIntravenousLineObservation_ShouldCalculateObservationAndAdjustTimeIfNecessary()
{
var patientId = ObjectId.GenerateNewId();
var currentTime = DateTime.UtcNow;
var obs = new PatientObservation
{
PatientId = patientId,
Name = "IntravenousLine",
Value = new PatientIntravenousLinesValue(),
Time = currentTime
};
_observationServiceMock.Setup(s => s.FindLastIntravenousLinesObservationByLocation(patientId))
.ReturnsAsync([]);
PatientObservation? insertedObservation = null;
_observationServiceMock.Setup(s =>
s.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()))
.Callback((ob, _, _) => insertedObservation = ob)
.Returns(Task.CompletedTask);
_observationServiceMock.Setup(s => s.FindLastObservations(It.IsAny(), 1, It.IsAny>()))
.ReturnsAsync([]);
await _calculatedObservations.CalculateIntravenousLineObservation(obs);
Assert.That(insertedObservation, Is.Not.Null);
Action assertions = () =>
{
Assert.That(insertedObservation!.PatientId, Is.EqualTo(patientId));
Assert.That(insertedObservation.Name, Is.EqualTo("IntravenousLines"));
Assert.That(insertedObservation.Time,
Is.GreaterThanOrEqualTo(currentTime)); // Verificar que la hora no sea anterior a la hora actual
};
}
///
/// Verifies that correctly calculates and inserts a "Monitor" when the patient has a valid existing observation matching the configured regional brain saturation code or an active treatment.
///
///
[Test]
public async Task CalculateMonitor_WithValidObservationOrTreatment_ShouldCalculateAndInsertObservation()
{
var patientId = ObjectId.GenerateNewId();
var monitorObservation = new PatientObservation
{
PatientId = patientId
};
var activeObservation = new PatientObservation
{
Code = _optionsApiSettings.Value.RegionalBrainSaturation?.FirstOrDefault(),
PatientId = patientId
};
var activeTreatment = new PatientTreatment
{
PatientId = patientId
};
_observationServiceMock.Setup(s =>
s.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>()))
.ReturnsAsync([activeObservation]);
_treatmentServiceMock.Setup(s => s.GetActiveTreatmentsByPatient(It.IsAny()))
.ReturnsAsync(new List { activeTreatment });
_observationServiceMock.Setup(s => s.InsertObservation(It.IsAny(), true, true))
.Returns(Task.CompletedTask)
.Verifiable();
await _calculatedObservations.CalculateMonitor(monitorObservation);
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == patientId &&
o.Name == "Monitor" &&
o.CodingSystem == "ADAS" &&
o.Min != null && Math.Abs(o.Min.Value - 0) < 0.01 &&
o.Max != null && Math.Abs(o.Max.Value - 3) < 0.01
), It.IsAny(), It.IsAny()),
Times.Once());
}
///
/// Verifies that CalculateMonitor calculates and inserts a new Monitor observation for the patient when invoked with a , provided an active treatment exists and a matching non-expired is returned by FindLastObservations.
///
///
[Test]
public async Task CalculateMonitor_WithPatientTreatment_ShouldCalculateAndInsertObservation()
{
// Arrange
var patientId = ObjectId.GenerateNewId();
var monitorTreatment = new PatientTreatment
{
PatientId = patientId
};
var activeTreatment = new PatientTreatment
{
PatientId = patientId
};
var patientObservation = new PatientObservation
{
Code = _optionsApiSettings.Value.Transcutaneous?.First(),
PatientId = patientId,
Expired = false
};
// Simular respuestas de los servicios
_treatmentServiceMock.Setup(s => s.GetActiveTreatmentsByPatient(It.IsAny()))
.ReturnsAsync(new List { activeTreatment });
_observationServiceMock.Setup(s => s.InsertObservation(It.IsAny(), true, true))
.Returns(Task.CompletedTask)
.Verifiable();
_observationServiceMock.Setup(s => s.FindLastObservations(patientId, 1, It.IsAny>()))
.ReturnsAsync([patientObservation]);
// Act
await _calculatedObservations.CalculateMonitor(monitorTreatment);
// Assert
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == patientId &&
o.Name == "Monitor" &&
o.CodingSystem == "ADAS" &&
o.Min != null && Math.Abs(o.Min.Value - 0) < 0.01 &&
o.Max != null && Math.Abs(o.Max.Value - 3) < 0.01
), It.IsAny(), It.IsAny()),
Times.Once());
}
///
/// Verifies that does not invoke
/// when the supplied
/// contains incomplete data (only
/// is populated), and the prior observations returned by are empty.
///
///
[Test]
public async Task CalculateMonitor_WithIncompleteData_ShouldNotInsertObservation()
{
// Arrange
var patientId = ObjectId.GenerateNewId();
var incompleteObservation = new PatientObservation
{
PatientId = patientId
// Proporcionar datos incompletos o irrelevantes
};
// Simular respuestas de los servicios
_observationServiceMock.Setup(s =>
s.FindLastObservations(It.IsAny(), It.IsAny(), It.IsAny>()))
.ReturnsAsync([]);
_observationServiceMock.Setup(s => s.InsertObservation(It.IsAny(), true, true))
.Returns(Task.CompletedTask)
.Verifiable();
// Act
await _calculatedObservations.CalculateMonitor(incompleteObservation);
// Assert
_observationServiceMock.Verify(
s => s.InsertObservation(It.IsAny(), It.IsAny(), It.IsAny()),
Times.Never());
}
///
/// Verifies that the surgery expiration check does not insert the when its flag is set to false, ensuring that only expired observations trigger an insertion.
///
///
[Test]
public async Task CheckSurgeryExpired_WhenNotExpired_DoesNotInsertObservation()
{
var obs = new PatientObservation
{
Expired = false
};
await _calculatedObservations.CheckSurgeryExpired(obs);
_observationServiceMock.Verify(s => s.InsertObservation(It.IsAny(), true, false),
Times.Never);
}
///
/// Tests that when a has expired, inserts a new named "Surgery" with value 0, range 0 to 5, coding system "ADAS", timestamp offset by one second from the original observation, and matching patient identifier and expiry duration.
///
///
[Test]
public async Task CheckSurgeryExpired_WhenExpired_InsertsCorrectObservation()
{
var initialTime = DateTime.Now;
var obs = new PatientObservation
{
Expired = true,
PatientId = ObjectId.GenerateNewId(),
Time = initialTime,
Expires = 30
};
await _calculatedObservations.CheckSurgeryExpired(obs);
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == obs.PatientId &&
o.Name == "Surgery" &&
o.Min != null && Math.Abs(o.Min.Value - 0) < 0.01 &&
o.Max != null && Math.Abs(o.Max.Value - 5) < 0.01 &&
o.CodingSystem == "ADAS" &&
o.Time == initialTime.AddSeconds(1) &&
o.Value.Equals(0) && // Asegúrate de que la comparación de 'o.Value' sea apropiada para su tipo
o.Expires == 30
), true, false), Times.Once);
}
///
/// Verifies that inserts a new complexity observation when processing a patient observation in a non-ECMO treatment context, ensuring the active treatments and recent observations are retrieved and the resulting complexity value is persisted.
///
///
[Test]
public async Task CalculateComplexity_NewObservation_NoECMO_AddsComplexity()
{
var patientId = ObjectId.GenerateNewId();
var patientTreatment = new PatientTreatment
{
Id = patientId
};
var patientObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "Weight_Current",
Value = 10
};
var complelxity = new PatientObservation
{
Id = patientId,
Value = 1
};
// Mock de datos de tratamiento activo
var activeTreatments = new List { patientTreatment };
_treatmentServiceMock.Setup(m => m.GetActiveTreatmentsByPatient(It.IsAny()))
.ReturnsAsync(activeTreatments);
// Mock de datos de observación
var observations = new List { patientObservation };
_observationServiceMock.Setup(m => m.FindLastObservations(It.IsAny(), 1, It.IsAny>()))
.ReturnsAsync(observations);
var complexityObservations = new List { complelxity };
_observationServiceMock.Setup(m => m.FindLastObservations(It.IsAny(), 1, It.IsAny>()))
.ReturnsAsync(complexityObservations);
var obs = patientObservation as BasePatientObservation;
var result = await _calculatedObservations.CalculateComplexity(obs);
// Verifica que el valor de complejidad calculado sea el esperado
Assert.That(result.Name, Is.EqualTo("Weight_Current"));
// Verifica que se hayan llamado los métodos esperados en los servicios mockeados
_treatmentServiceMock.Verify(m => m.GetActiveTreatmentsByPatient(It.IsAny()), Times.Once);
_observationServiceMock.Verify(m => m.FindLastObservations(It.IsAny(), 1, It.IsAny>()),
Times.Exactly(3));
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == obs.PatientId &&
o.Name == "Complexity" &&
o.CodingSystem == "ADAS" &&
Equals(o.Value, 7)
), true, false), Times.Once);
}
///
/// Verifies that when an expired is passed to the complexity calculation,
/// no new complexity record is inserted into the database, ensuring that expired observations are excluded
/// from contributing to the patient's calculated complexity value.
///
///
[Test]
public async Task CalculateComplexity_ExpiredObservation_DoesNotAddToComplexity()
{
// Configuración inicial
var patientId = ObjectId.GenerateNewId();
var expiredPatientObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "Weight_Current",
Value = 10,
Expired = true // Observación expirada
};
var observations = new List { expiredPatientObservation };
_observationServiceMock.Setup(m => m.FindLastObservations(It.IsAny(), 1, It.IsAny>()))
.ReturnsAsync(observations);
var obs = expiredPatientObservation as BasePatientObservation;
var result = await _calculatedObservations.CalculateComplexity(obs);
// Verificaciones
Assert.That(result.Name, Is.EqualTo("Weight_Current"));
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == obs.PatientId &&
o.Name == "Complexity" &&
Equals(o.Value, 0) // Valor de complejidad no debe cambiar
), true, true), Times.Never); // No se debe llamar InsertObservation
}
///
/// Verifies that when an active treatment includes ECMO,
/// preserves the original value and records a derived Complexity observation labeled
/// "1 ECMO" for the patient.
///
///
[Test]
public async Task CalculateComplexity_ECMOActive_AdjustsComplexity()
{
var code = new Code { Identifier = "705923009" };
// Configuración inicial
var patientId = ObjectId.GenerateNewId();
var observation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "ECMO",
Value = 10
};
var lastObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Name = "Surgery",
Value = 1
};
var patientTreatment = new PatientTreatment
{
Id = patientId
};
patientTreatment.RequestedGiveCodes.Add(code);
// Mock de datos de tratamiento activo
var activeTreatments = new List { patientTreatment };
_treatmentServiceMock.Setup(m => m.GetActiveTreatmentsByPatient(It.IsAny()))
.ReturnsAsync(activeTreatments);
var observations = new List { lastObservation };
_observationServiceMock.Setup(m => m.FindLastObservations(It.IsAny(), 1, It.IsAny>()))
.ReturnsAsync(observations);
BasePatientObservation obs = observation;
var result = await _calculatedObservations.CalculateComplexity(obs);
// Verificaciones
Assert.That(result.Name, Is.EqualTo("ECMO"));
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == obs.PatientId &&
o.Name == "ECMO" &&
Equals(o.Value, 10) // Valor de complejidad no debe cambiar
), true, true), Times.Once);
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == obs.PatientId &&
o.Name == "Complexity" &&
Equals(o.Value, "1 ECMO")
), true, false), Times.Once);
}
///
/// Verifies that increments the by one second beyond the existing observation when the lookup returns a sharing the same timestamp, patient, and observation name as the supplied instance.
///
///
[Test]
public async Task CheckObsExistsAndIncrementTime_SameHourObservation_IncrementsTime()
{
// Configuración inicial
var patientId = ObjectId.GenerateNewId();
var initialTime = DateTime.UtcNow;
var sameHourObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Time = initialTime,
Name = "TestObservation"
};
var existingObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Time = initialTime, // Misma hora que sameHourObservation
Name = "TestObservation"
};
// Mock del servicio de observación para que retorne una observación existente en la misma hora
_observationServiceMock.Setup(m =>
m.FindLastBeforeDate(It.IsAny(), It.IsAny(), It.IsAny()))
.ReturnsAsync(existingObservation);
var obs = sameHourObservation as BasePatientObservation;
var result = await _calculatedObservations.CheckObsExistsAndIncrementTime(obs);
// Verificaciones
var resultObs = result as PatientObservation;
Assert.That(resultObs, Is.Not.Null);
Assert.That(resultObs!.Time, Is.GreaterThan(initialTime)); // Verifica que el tiempo ha sido incrementado
Assert.That(resultObs.Time,
Is.EqualTo(existingObservation.Time.AddSeconds(1))); // Verifica que el tiempo se incrementó en 1 segundo
}
///
/// Verifies that increments the of the supplied by one second and assigns a new when another observation with the same time and already exists for the same .
///
///
[Test]
public async Task CheckObsWithSameTimeExistsAndIncrementTime_WhenObservationWithSameTimeExists_IncrementsTime()
{
// Configuración inicial
var patientId = ObjectId.GenerateNewId();
var observationTime = DateTime.UtcNow;
const string observationName = "TestObservation";
var newObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Time = observationTime,
Name = observationName
};
var existingObservation = new PatientObservation
{
Id = ObjectId.GenerateNewId(),
PatientId = patientId,
Time = observationTime, // Misma hora y nombre que newObservation
Name = observationName
};
// Mock del servicio de observación para que retorne una observación existente con el mismo tiempo y nombre
_observationServiceMock.Setup(m => m.FindAnyWithSameDate(patientId, observationTime, observationName))
.ReturnsAsync([existingObservation]);
BasePatientObservation obs = newObservation;
var result = await _calculatedObservations.CheckObsWithSameTimeExistsAndIncrementTime(obs);
// Verificaciones
var resultObs = result as PatientObservation;
Assert.That(resultObs, Is.Not.Null);
using (Assert.EnterMultipleScope())
{
{
Assert.That(resultObs!.Time,
Is.EqualTo(observationTime.AddSeconds(1))); // Verifica que el tiempo se haya incrementado en 1 segundo
Assert.That(existingObservation.Id,
Is.Not.EqualTo(resultObs.Id)); // Verifica que el Id sea diferente al de la observación existente
}
;
}
}
///
/// Verifies that correctly processes a treatment whose notes contain a parental nutrition formulation (comment "NPT" with comment type "formularybaseformulation"), looking up the associated by code, retrieving active treatments and the last medication observation for the patient, and inserting a new with "Medication", "ADAS" and 1.
///
///
[Test]
public async Task CheckTreatmentMedicines_ProcessesTreatmentCorrectly_WithParentalNutritionMedicine()
{
var patientId = ObjectId.GenerateNewId();
var code = new Code { Identifier = "705923009" };
var medicationObs = new PatientObservation { PatientId = patientId, Value = 2 };
// Configuración inicial
var treatment = new PatientTreatment
{
PatientId = patientId,
Notes =
[
new Note { Comment = "NPT", CommentType = "formularybaseformulation" }
],
RequestedGiveCodes = [code],
RequestedGiveTreatment = "Medicación"
};
var medicine = new Medicine { Codes = [code.Identifier] };
var lastMedicationObs = new List { medicationObs };
var expectedMedicines = new List { medicine };
var activeTreatments = new List { treatment };
// Mock de medicineService para que devuelva medicinas esperadas
_medicineServiceMock.Setup(m => m.GetByCodeOrNote(It.IsAny>()))
.ReturnsAsync(expectedMedicines);
_medicineServiceMock.Setup(m => m.GetMedicinesOfTreatments(It.IsAny>()))
.ReturnsAsync(expectedMedicines);
_treatmentServiceMock.Setup(m => m.GetActiveTreatmentsByPatient(It.IsAny()))
.ReturnsAsync(activeTreatments);
_observationServiceMock
.Setup(m => m.FindLastObservations(It.IsAny(), 1, new List { "Medication" }))
.ReturnsAsync(lastMedicationObs);
_observationServiceMock.Setup(s => s.FindLastObservations(It.IsAny(), 1, It.IsAny>()))
.ReturnsAsync([]);
// Otras configuraciones de mock según sea necesario
// Llamada al método bajo prueba
await _calculatedObservations.CheckTreatmentMedicines(treatment);
// Verificaciones
// Verifica que las llamadas a los servicios mockeados son como se esperan
// Verifica que la lógica de procesamiento de medicamentos es correcta
// Puedes usar Assert o Verify de Moq según corresponda
// ...
_observationServiceMock.Verify(s => s.InsertObservation(It.Is(o =>
o.PatientId == patientId &&
o.Name == "Medication" &&
o.CodingSystem == "ADAS" &&
Equals(o.Value, 1)
), true, false), Times.Once);
}
}